diff --git a/AUTHORS b/AUTHORS
index def32e0..ce7d33a 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,6 +1,9 @@
J Harper
+Janne Johansson
Bryan Klisch
Steve Lokos
+Arto Niemi
+Marko Nippula
Tom St.Denis
diff --git a/CHANGES.md b/CHANGES.md
index ccc36cb..3dc14b8 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,6 +1,152 @@
MatrixSSL Release Notes
=======================
+Changes in 3.9.0
+----------------
+
+> **Version 3.9.0**
+> March 2017
+> (C) Copyright 2017 INSIDE Secure - All Rights Reserved
+
+1. BUG FIXES SINCE 3.8.7b
+ - Fixed server-side handling of client authentication with Server Name Indication
+ - Constant Time Modular Exponentiation
+
+2. NEW FEATURES SINCE 3.8.7b
+
+ - RFC 5280 Compliant Certificate Matching
+ - Certificate Validation Configuration Options
+ - Client Authentication using an External Security Token
+ - X.509 Generation Improvements (Commercial Edition Only)
+ - Added psX509GetOnelineDN API
+ - Added matrixValidateCertsExt API
+ - Support for RSA-MD2 and RSA-MD5 Signatures in CSR and CRL Parsing
+ - ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE Compatibility Option
+
+3. OTHER CHANGES SINCE 3.8.7b
+ - Indent style changes
+
+#1. BUG FIXES SINCE 3.8.7b
+
+## Fixed server-side handling of client authentication with Server Name Indication
+
+This bug caused client authentication to fail when MatrixSSL was used
+as the server and the client was sending the Server Name Indication
+extension.
+
+## Constant Time Modular Exponentiation
+
+It was reported by Andreas Zankl that Matrix Crypto implementation had
+a side-channel information leak via instruction cache. In response to
+the research, Matrix Crypto modular exponentiation was changed to use
+code that does not leak information via instruction cache and uses
+constant-time execution. The new code is slower. (Note: The SafeZone
+CL/CLS cryptography used in MatrixSSL FIPS Edition has been using
+constant time modular exponention before.)
+
+#2. NEW FEATURES SINCE 3.8.7b
+
+## RFC 5280 Compliant Certificate Matching
+
+Matching certificate fields in MatrixSSL has been improved. MatrixSSL
+now implements the requirement from RFC 5280 that Subject Alternative Name
+is used for matching instead of subject Common Name if alternative
+name is available. Subject Alternative Name contain more precise
+information on the type of the field and thus avoids false positive field
+matches. MatrixSSL now allows RFC 5280 compliant matching of email
+addresses, where only domain name part is case insensitive. It is now
+possible to specify the type of name to match with new session
+options. See the Session Options section in the MatrixSSL APIs manual
+for details.
+
+The issues in certificate matching were reported by Suphannee Sivakorn from
+Columbia University.
+
+## Certificate Validation Configuration Options
+
+New session options have been added for configuring MatrixSSL's
+internal certificate validation process. These include options for
+specifying the field in the server certificate against which the
+expected server name should be matched, an option to limit the maximum
+certificate chain validation depth and options for retaining the peer
+certificate after processing. See the Session Options section in the
+MatrixSSL APIs manual for details.
+
+## Client Authentication using an External Security Token
+
+MatrixSSL's external client authentication feature allows
+client-side private key operation in TLS client authentication,
+i.e. the signing of the handshake_messages hash in the
+CertificateVerify handshake message, to be offloaded from MatrixSSL to
+an external module such as a security or authentication token. See
+the MatrixSSL External Module Integration manual for details.
+
+## X.509 Generation Improvements (Commercial Edition Only)
+
+Support has been added for encoding the netscape-comment certificate
+extension. The psParseCertReqBufExt API has been added. This version
+of psParseCertReqBufExt allows storing additional information from
+the parsed CSR. Another additional API is psX509SetPublicKey, which
+can be used to set the public key in a psCertConfig_t struct, before
+it is passed to the CSR or certificate encoding routines. See the
+MatrixSSL Certificates and Certificate Revocation Lists manual for
+details.
+
+## Added psX509GetOnelineDN API
+
+The new psX509GetOnelineDN API can be used to generate a one-line
+string representation of a Distinguished Name.
+
+## Added matrixValidateCertsExt API
+
+The new matrixValidateCertsExt API has an additional options struct
+argument for configuring some aspects of the certificate chain
+validation process. The old matrixValidateCerts API is now deprecated.
+
+## Support for RSA-MD2 and RSA-MD5 Signatures in CSR and CRL Parsing
+
+Support for RSA-MD2 and RSA-MD5 signature verification has been added
+to CSR parsing, and support for RSA-MD2 signature verification has
+been added to CRL parsing. These insecure, legacy algorithms are
+disabled by default, but they can be enabled by defining USE_MD2 or
+USE_MD5.
+
+## ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE Compatibility Option
+
+The ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE build-time option allows CRL
+authentication to succeed even when signer CA's cert does not have the
+keyUsage extension and thus no cRLSign bit. This option is for
+compatibility with old CRL issuer certs. RFC 5280 requires CRL issuer
+certs to have the keyUsage extension and the cRLSign bit.
+
+#3. OTHER CHANGES SINCE 3.8.7b
+
+## Indent style changes
+
+Indent style has been changed and made more consistent accross source
+and header files.
+
+Changes in 3.8.7b
+-----------------
+
+> **Version 3.8.7b**
+> January 2017
+> (C) Copyright 2017 INSIDE Secure - All Rights Reserved
+
+
+
+1. BUG FIXES SINCE 3.8.7
+- Fixed compile error if SHA224 was enabled.
+- Fixed compile warning around HTTP2 alpn detection.
+- Fixed issue where a cipher suite could be negotiated that did not match the authentication type for the keys.
+
+#1. BUG FIXES SINCE 3.8.7
+
+## Fixed issue where a cipher suite could be negotiated that did not match the authentication type for the keys.
+
+This manifested in the default apps/ssl/server.c example when Chrome was connected. It negotiated an ECDSA based cipher even though keys loaded by default were RSA keys.
+
+
Changes in 3.8.7
----------------
diff --git a/Makefile b/Makefile
index d42eca7..128b945 100644
--- a/Makefile
+++ b/Makefile
@@ -102,6 +102,12 @@ CONFIG_FIPS_AVAILABLE=1
CONFIG_NONFIPS_PREFIX=nonfips-
endif
+ifneq (,$(findstring -DUSE_EXT_EXAMPLE_MODULE, $(CFLAGS)))
+D_USE_EXT_EXAMPLE_MODULE=1
+else
+D_USE_EXT_EXAMPLE_MODULE=0
+endif
+
# These are some examples of configuration selection targets for MatrixSSL.
# You can instead apply any of any of configurations in configs directory with
# make CONFIGNAME-config and then proceed with make all / make libs etc.
@@ -179,12 +185,17 @@ test-combined-default-nonfips:
.PHONY: all libs tests apps clean
+ext:
+ if [ "$(D_USE_EXT_EXAMPLE_MODULE)" = "1" ]; then $(MAKE) --directory=ext/psext-example; \
+ elif $(MAKE) --directory=matrixssl parse-config | grep -q '#define USE_EXT_EXAMPLE_MODULE'; then $(MAKE) --directory=ext/psext-example; fi \
+
# Add dependencies
all: libs tests apps
all: check-config
libs: check-config
-tests: check-config libs
-apps: check-config libs
+tests: check-config libs ext
+apps: check-config libs ext
+ext: check-config libs
all-utils: check-config
# Alias
@@ -232,6 +243,7 @@ clean:
if [ -e apps/crypto ];then $(MAKE) clean --directory=apps/crypto;fi
if [ -e crypto/cms/test ]; then $(MAKE) clean --directory=crypto/cms/test;fi
if [ -e matrixssh ]; then $(MAKE) clean --directory=matrixssh; fi
+ if [ -e ext/psext-example ]; then $(MAKE) clean --directory=ext/psext-example;fi
clobber: clean clean-config
diff --git a/README.html b/README.html
new file mode 100644
index 0000000..a5df6f3
--- /dev/null
+++ b/README.html
@@ -0,0 +1,49 @@
+

+
+Lightweight Embedded SSL/TLS Implementation
+Official source repository of matrixssl.org
+
+
+
+
+
+
+
+Overview
+
+MatrixSSL has been continuously maintained since 2002. It is the first open source small footprint SSL stack. Until recently, releases were tracked on http://freecode.com/projects/matrixssl
+
+MatrixSSL is an embedded SSL and TLS implementation designed for small footprint IoT devices requiring low overhead per connection. The library is less than 50Kb on disk with cipher suites. It includes client and server support through TLS 1.2, mutual authentication, session resumption, and implementations of RSA, ECC, AES, SHA1, SHA-256 and more. The source is well documented and contains portability layers for additional operating systems, cipher suites, and cryptography providers.
+
+Reporting Issues
+
+Please email support@matrixssl.org.
+Sensitive emails can be encrypted using the public key in this directory pgp.asc, Key fingerprint = D6AD F1C5 E34E 696B 0953 556C 8BB2 B39A 2795 C6B3.
+
+Features
+
+
+- < 50KB total footprint with crypto provider
+- SSL 3.0 and TLS 1.0, 1.1 and 1.2 server and client support
+- Included crypto library - RSA, ECC, AES, 3DES, ARC4, SHA1, SHA256, MD5
+- Assembly language optimizations for Intel, ARM and MIPS
+- Session re-keying and cipher renegotiation
+- Full support for session resumption/caching
+- Server Name Indication and Stateless Session Tickets
+- RFC7301 Application Protocol Negotiation
+- Server and client X.509 certificate chain authentication
+- Parsing of X.509 .pem and ASN.1 DER certificate formats
+- PKCS#1.5, PKCS#5 PKCS#8 and PKCS#12 support for key formatting
+- RSASSA-PSS Signature Algorithm support
+- Certificate Revocation List (CRL) support
+- Fully cross platform, portable codebase; minimum use of system calls
+- Pluggable cipher suite interface
+- Pluggable crypto provider interface
+- Pluggable operating system and malloc interface
+- TCP/IP optional
+- Multithreading optional
+- Only a handful of external APIs, all non-blocking
+- Example client and server code included
+- Clean, heavily commented code in portable C
+- User and developer documentation
+
diff --git a/apps/dtls/dtlsClient.c b/apps/dtls/dtlsClient.c
index 209a636..4366057 100644
--- a/apps/dtls/dtlsClient.c
+++ b/apps/dtls/dtlsClient.c
@@ -1,219 +1,225 @@
/**
- * @file dtlsClient.c
- * @version $Format:%h%d$
+ * @file dtlsClient.c
+ * @version $Format:%h%d$
*
- * MatrixDTLS client example.
+ * MatrixDTLS client example.
*/
/*
- * Copyright (c) 2014-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2014-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#include "dtlsCommon.h"
+/* Currently this example uses _psTrace for tracing, so osdep.h is needed: */
+#include "core/osdep.h"
+#include "core/psUtil.h"
#if defined(USE_DTLS) && defined(USE_CLIENT_SIDE_SSL)
static int packet_loss_prob = 0; /* Reciprocal of packet loss probability
- (i.e. P(packet loss) = 1/x).
- Default value is 0 (no packet loss). */
+ (i.e. P(packet loss) = 1/x).
+ Default value is 0 (no packet loss). */
-#ifdef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
+# ifdef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
static int test_lost_cipherspec_change_rehandshake = 0;
-#endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
+# endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
/* Client DTLS context data type */
-typedef struct {
- SOCKET fd;
- struct sockaddr_in addr;
- ssl_t *ssl;
+typedef struct
+{
+ SOCKET fd;
+ struct sockaddr_in addr;
+ ssl_t *ssl;
} sslDtls_t;
-#ifdef WIN32
-#pragma message("DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS.")
-#else
-#warning "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
-#endif
+# ifndef MATRIX_TESTING_ENVIRONMENT /* Omit the message when testing. */
+# ifdef WIN32
+# pragma message("DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS.")
+# else
+# warning "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
+# endif
+# endif
-#define ALLOW_ANON_CONNECTIONS 1
-#define USE_HEADER_KEYS
+# define ALLOW_ANON_CONNECTIONS 1
+# define USE_HEADER_KEYS
/*
- If supporting client authentication, pick ONE identity to auto select a
- certificate and private key that support desired algorithms.
-*/
-//#define ID_RSA /* RSA Certificate and Key */
-//#define ID_ECDH_ECDSA /* EC Certificate and Key */
-//#define ID_ECDH_RSA /* EC Key with RSA signed certificate */
+ If supporting client authentication, pick ONE identity to auto select a
+ certificate and private key that support desired algorithms.
+ */
+/* #define ID_RSA / * RSA Certificate and Key * / */
+/* #define ID_ECDH_ECDSA / * EC Certificate and Key * / */
+/* #define ID_ECDH_RSA / * EC Key with RSA signed certificate * / */
-#if !defined(ID_RSA) && !defined(ID_ECDH_ECDSA) && !defined(ID_ECDH_RSA)
+# if !defined(ID_RSA) && !defined(ID_ECDH_ECDSA) && !defined(ID_ECDH_RSA)
/* Choose a default identity based on which algorithms are supported. */
-#ifdef USE_RSA_CIPHER_SUITE
-#define ID_RSA
-#else
-#ifdef USE_ECC_CIPHER_SUITE
-#define ID_ECDH_ECDSA
-#else
-#error "Please enable either RSA or ECC for client"
-#endif /* USE_ECC_CIPHER_SUITE */
-#endif /* USE_RSA_CIPHER_SUITE */
-#endif /* !ID_RSA && !ID_ECDH_ECDSA && !ID_ECDH_RSA */
+# ifdef USE_RSA_CIPHER_SUITE
+# define ID_RSA
+# else
+# ifdef USE_ECC_CIPHER_SUITE
+# define ID_ECDH_ECDSA
+# else
+# error "Please enable either RSA or ECC for client"
+# endif /* USE_ECC_CIPHER_SUITE */
+# endif /* USE_RSA_CIPHER_SUITE */
+# endif /* !ID_RSA && !ID_ECDH_ECDSA && !ID_ECDH_RSA */
-/* If the algorithm type is supported, load a CA for it */
-#ifdef USE_HEADER_KEYS
+/* If the algorithm type is supported, load a CA for it */
+# ifdef USE_HEADER_KEYS
/* CAs */
-#ifdef USE_RSA_CIPHER_SUITE
-#include "testkeys/RSA/ALL_RSA_CAS.h"
-#ifdef USE_ECC_CIPHER_SUITE
-#include "testkeys/ECDH_RSA/ALL_ECDH-RSA_CAS.h"
-#endif
-#endif
-#ifdef USE_ECC_CIPHER_SUITE
+# ifdef USE_RSA_CIPHER_SUITE
+# include "testkeys/RSA/ALL_RSA_CAS.h"
+# ifdef USE_ECC_CIPHER_SUITE
+# include "testkeys/ECDH_RSA/ALL_ECDH-RSA_CAS.h"
+# endif
+# endif
+# ifdef USE_ECC_CIPHER_SUITE
-#if defined(USE_SECP192R1) && defined(USE_SECP224R1) && defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS.h"
-#endif /* USE_SECP192R1 && USE_SECP224R1 && USE_SECP521R1 */
+# if defined(USE_SECP192R1) && defined(USE_SECP224R1) && defined(USE_SECP521R1)
+# include "testkeys/EC/ALL_EC_CAS.h"
+# endif /* USE_SECP192R1 && USE_SECP224R1 && USE_SECP521R1 */
-#if !defined(USE_SECP192R1) && defined(USE_SECP224R1) && defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192.h"
-#endif /* !USE_SECP192R1 && USE_SECP224R1 && USE_SECP521R1 */
+# if !defined(USE_SECP192R1) && defined(USE_SECP224R1) && defined(USE_SECP521R1)
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192.h"
+# endif /* !USE_SECP192R1 && USE_SECP224R1 && USE_SECP521R1 */
-#if defined(USE_SECP192R1) && !defined(USE_SECP224R1) && defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P224.h"
-#endif /* USE_SECP192R1 && !USE_SECP224R1 && USE_SECP521R1 */
+# if defined(USE_SECP192R1) && !defined(USE_SECP224R1) && defined(USE_SECP521R1)
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P224.h"
+# endif /* USE_SECP192R1 && !USE_SECP224R1 && USE_SECP521R1 */
-#if defined(USE_SECP192R1) && defined(USE_SECP224R1) && !defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P521.h"
-#endif /* USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
+# if defined(USE_SECP192R1) && defined(USE_SECP224R1) && !defined(USE_SECP521R1)
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P521.h"
+# endif /* USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
-#if !defined(USE_SECP192R1) && !defined(USE_SECP224R1) && defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P224.h"
-#endif /* !USE_SECP192R1 && !USE_SECP224R1 && USE_SECP521R1 */
+# if !defined(USE_SECP192R1) && !defined(USE_SECP224R1) && defined(USE_SECP521R1)
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P224.h"
+# endif /* !USE_SECP192R1 && !USE_SECP224R1 && USE_SECP521R1 */
-#if !defined(USE_SECP192R1) && defined(USE_SECP224R1) && !defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P521.h"
-#endif /* !USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
+# if !defined(USE_SECP192R1) && defined(USE_SECP224R1) && !defined(USE_SECP521R1)
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P521.h"
+# endif /* !USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
-#if defined(USE_SECP192R1) && !defined(USE_SECP224R1) && !defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P224_AND_P521.h"
-#endif /* USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
+# if defined(USE_SECP192R1) && !defined(USE_SECP224R1) && !defined(USE_SECP521R1)
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P224_AND_P521.h"
+# endif /* USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
-#if !defined(USE_SECP192R1) && !defined(USE_SECP224R1) && !defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_P224_AND_P521.h"
-#endif /* !USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
+# if !defined(USE_SECP192R1) && !defined(USE_SECP224R1) && !defined(USE_SECP521R1)
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_P224_AND_P521.h"
+# endif /* !USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
-#endif /* USE_ECC_CIPHER_SUITE */
+# endif /* USE_ECC_CIPHER_SUITE */
/* Identity Certs and Keys for use with Client Authentication */
-#ifdef ID_RSA
-#define EXAMPLE_RSA_KEYS
-#include "testkeys/RSA/1024_RSA.h"
-#include "testkeys/RSA/1024_RSA_KEY.h"
-#include "testkeys/RSA/2048_RSA.h"
-#include "testkeys/RSA/2048_RSA_KEY.h"
-#include "testkeys/RSA/3072_RSA.h"
-#include "testkeys/RSA/3072_RSA_KEY.h"
-#include "testkeys/RSA/4096_RSA.h"
-#include "testkeys/RSA/4096_RSA_KEY.h"
-#endif
+# ifdef ID_RSA
+# define EXAMPLE_RSA_KEYS
+# include "testkeys/RSA/1024_RSA.h"
+# include "testkeys/RSA/1024_RSA_KEY.h"
+# include "testkeys/RSA/2048_RSA.h"
+# include "testkeys/RSA/2048_RSA_KEY.h"
+# include "testkeys/RSA/3072_RSA.h"
+# include "testkeys/RSA/3072_RSA_KEY.h"
+# include "testkeys/RSA/4096_RSA.h"
+# include "testkeys/RSA/4096_RSA_KEY.h"
+# endif
-#ifdef ID_ECDH_ECDSA
-#define EXAMPLE_EC_KEYS
-#include "testkeys/EC/384_EC.h"
-#include "testkeys/EC/384_EC_KEY.h"
-#endif
+# ifdef ID_ECDH_ECDSA
+# define EXAMPLE_EC_KEYS
+# include "testkeys/EC/384_EC.h"
+# include "testkeys/EC/384_EC_KEY.h"
+# endif
-#ifdef ID_ECDH_RSA
-#define EXAMPLE_ECDH_RSA_KEYS
-#include "testkeys/ECDH_RSA/521_ECDH-RSA.h"
-#include "testkeys/ECDH_RSA/521_ECDH-RSA_KEY.h"
-#endif
+# ifdef ID_ECDH_RSA
+# define EXAMPLE_ECDH_RSA_KEYS
+# include "testkeys/ECDH_RSA/521_ECDH-RSA.h"
+# include "testkeys/ECDH_RSA/521_ECDH-RSA_KEY.h"
+# endif
/* File-based keys */
-#else
+# else
/* CAs */
-#ifdef USE_RSA_CIPHER_SUITE
+# ifdef USE_RSA_CIPHER_SUITE
static char rsaCAFile[] = "testkeys/RSA/ALL_RSA_CAS.pem";
-#ifdef USE_ECC_CIPHER_SUITE
+# ifdef USE_ECC_CIPHER_SUITE
static char ecdhRsaCAFile[] = "testkeys/ECDH_RSA/ALL_ECDH-RSA_CAS.pem";
-#endif
-#endif
-#ifdef USE_ECC_CIPHER_SUITE
+# endif
+# endif
+# ifdef USE_ECC_CIPHER_SUITE
-#if defined(USE_SECP192R1) && defined(USE_SECP521R1)
+# if defined(USE_SECP192R1) && defined(USE_SECP521R1)
static char ecCAFile[] = "testkeys/EC/ALL_EC_CAS.pem";
-#endif /* USE_SECP192R1 && USE_SECP521R1 */
+# endif /* USE_SECP192R1 && USE_SECP521R1 */
-#if !defined(USE_SECP192R1) && defined(USE_SECP521R1)
+# if !defined(USE_SECP192R1) && defined(USE_SECP521R1)
static char ecCAFile[] = "testkeys/EC/ALL_EC_CAS_EXCEPT_P192.pem";
-#endif /* USE_SECP192R1 && USE_SECP521R1 */
+# endif /* USE_SECP192R1 && USE_SECP521R1 */
-#if defined(USE_SECP192R1) && !defined(USE_SECP521R1)
+# if defined(USE_SECP192R1) && !defined(USE_SECP521R1)
static char ecCAFile[] = "testkeys/EC/ALL_EC_CAS_EXCEPT_P521.pem";
-#endif /* USE_SECP192R1 && USE_SECP521R1 */
+# endif /* USE_SECP192R1 && USE_SECP521R1 */
-#if !defined(USE_SECP192R1) && !defined(USE_SECP521R1)
+# if !defined(USE_SECP192R1) && !defined(USE_SECP521R1)
static char ecCAFile[] = "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P521.pem";
-#endif /* USE_SECP192R1 && USE_SECP521R1 */
+# endif /* USE_SECP192R1 && USE_SECP521R1 */
-#endif /* USE_ECC_CIPHER_SUITE */
+# endif /* USE_ECC_CIPHER_SUITE */
/* Identity Certs and Keys for use with Client Authentication */
-#ifdef ID_RSA
-#define EXAMPLE_RSA_KEYS
+# ifdef ID_RSA
+# define EXAMPLE_RSA_KEYS
static char rsaCertFile[] = "testkeys/RSA/2048_RSA.pem";
static char rsaPrivkeyFile[] = "testkeys/RSA/2048_RSA_KEY.pem";
-#endif
+# endif
-#ifdef ID_ECDH_ECDSA
-#define EXAMPLE_EC_KEYS
+# ifdef ID_ECDH_ECDSA
+# define EXAMPLE_EC_KEYS
static char ecCertFile[] = "testkeys/EC/384_EC.pem";
static char ecPrivkeyFile[] = "testkeys/EC/384_EC_KEY.pem";
-#endif
+# endif
-#ifdef ID_ECDH_RSA
-#define EXAMPLE_ECDH_RSA_KEYS
+# ifdef ID_ECDH_RSA
+# define EXAMPLE_ECDH_RSA_KEYS
static char ecdhRsaCertFile[] = "testkeys/ECDH_RSA/521_ECDH-RSA.pem";
static char ecdhRsaPrivkeyFile[] = "testkeys/ECDH_RSA/521_ECDH-RSA_KEY.pem";
-#endif
+# endif
-#endif /* USE_HEADER_KEYS */
+# endif /* USE_HEADER_KEYS */
-#ifdef USE_PSK_CIPHER_SUITE
-#include "testkeys/PSK/psk.h"
-#endif
+# ifdef USE_PSK_CIPHER_SUITE
+# include "testkeys/PSK/psk.h"
+# endif
/*
- Test rehandshakes
-*/
-#ifndef TEST_DTLS_CLIENT_REHANDSHAKE
-#define TEST_DTLS_CLIENT_REHANDSHAKE 0
-#endif /* TEST_DTLS_CLIENT_REHANDSHAKE */
-#ifndef TEST_DTLS_CLIENT_RESUMED_REHANDSHAKE
-#define TEST_DTLS_CLIENT_RESUMED_REHANDSHAKE 0
-#endif /* TEST_DTLS_CLIENT_RESUMED_REHANDSHAKE */
+ Test rehandshakes
+ */
+# ifndef TEST_DTLS_CLIENT_REHANDSHAKE
+# define TEST_DTLS_CLIENT_REHANDSHAKE 0
+# endif /* TEST_DTLS_CLIENT_REHANDSHAKE */
+# ifndef TEST_DTLS_CLIENT_RESUMED_REHANDSHAKE
+# define TEST_DTLS_CLIENT_RESUMED_REHANDSHAKE 0
+# endif /* TEST_DTLS_CLIENT_RESUMED_REHANDSHAKE */
/********************************** Globals ***********************************/
@@ -234,878 +240,999 @@ static int32 sendHelloWorld(sslDtls_t *dtlsCtx);
/******************************************************************************/
/*
- Allocate the data structure to manage the socket and ssl combo of
- a DTLS client.
-*/
+ Allocate the data structure to manage the socket and ssl combo of
+ a DTLS client.
+ */
static SOCKET dtlsInitClientSocket(sslDtls_t **newCtx, ssl_t *ssl)
{
- sslDtls_t *dtls;
+ sslDtls_t *dtls;
- *newCtx = NULL;
+ *newCtx = NULL;
- if ((dtls = psMalloc(NULL, sizeof(sslDtls_t))) == NULL) {
- return PS_MEM_FAIL;
- }
- dtls->ssl = ssl;
+ if ((dtls = psMalloc(NULL, sizeof(sslDtls_t))) == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ dtls->ssl = ssl;
- if ((dtls->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
- _psTrace("Error creating INET UDP socket\n");
- psFree(dtls, NULL);
- return INVALID_SOCKET;
- }
+ if ((dtls->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ {
+ _psTrace("Error creating INET UDP socket\n");
+ psFree(dtls, NULL);
+ return INVALID_SOCKET;
+ }
- memset(&dtls->addr, 0x0, sizeof(struct sockaddr_in));
- dtls->addr.sin_family = AF_INET;
- dtls->addr.sin_port = htons((short)g_port);
- dtls->addr.sin_addr.s_addr = inet_addr(g_ip);
- *newCtx = dtls;
+ memset(&dtls->addr, 0x0, sizeof(struct sockaddr_in));
+ dtls->addr.sin_family = AF_INET;
+ dtls->addr.sin_port = htons((short) g_port);
+ dtls->addr.sin_addr.s_addr = inet_addr(g_ip);
+ *newCtx = dtls;
- udpInitProxy();
+ udpInitProxy();
- return dtls->fd;
+ return dtls->fd;
}
/******************************************************************************/
/*
- Make a secure HTTP request to a defined IP and port
- Connection is made in blocking socket mode
- The connection is considered successful if the SSL/TLS session is
- negotiated successfully, a request is sent, and a HTTP response is received.
+ Make a secure HTTP request to a defined IP and port
+ Connection is made in blocking socket mode
+ The connection is considered successful if the SSL/TLS session is
+ negotiated successfully, a request is sent, and a HTTP response is received.
*/
static int32 dtlsClientConnection(sslKeys_t *keys, sslSessionId_t *sid)
{
- int32 rc, transferred, len, val, weAreDone;
- ssl_t *ssl;
- sslDtls_t *dtlsCtx;
- unsigned char *buf;
- socklen_t addrlen;
- struct sockaddr_in from;
- socklen_t fromLen;
- struct timeval timeout;
- long tSec;
- fd_set readfd;
- SOCKET fd;
- sslSessOpts_t options;
- int16 rehandshakeTestDone, resumedRehandshakeTestDone;
+ int32 rc, transferred, len, val, weAreDone;
+ ssl_t *ssl;
+ sslDtls_t *dtlsCtx;
+ unsigned char *buf;
+ socklen_t addrlen;
+ struct sockaddr_in from;
+ socklen_t fromLen;
+ struct timeval timeout;
+ long tSec;
+ fd_set readfd;
+ SOCKET fd;
+ sslSessOpts_t options;
+ int16 rehandshakeTestDone, resumedRehandshakeTestDone;
-#ifdef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
- int drop_next_cipherspec_packet = 0;
-#endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
+# ifdef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
+ int drop_next_cipherspec_packet = 0;
+# endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
- memset(&options, 0x0, sizeof(sslSessOpts_t));
- options.versionFlag = SSL_FLAGS_DTLS;
- options.trustedCAindication = 1;
+ memset(&options, 0x0, sizeof(sslSessOpts_t));
+ options.versionFlag = SSL_FLAGS_DTLS;
+ options.trustedCAindication = 1;
- /* We are passing the IP address of the server as the expected name */
- /* To skip certificate subject name tests, pass NULL instead of g_ip */
- if (g_disableCertNameChk == 0) {
- rc = matrixSslNewClientSession(&ssl, keys, sid, g_cipher, g_ciphers,
- certCb, g_ip, NULL, NULL, &options);
- } else {
- rc = matrixSslNewClientSession(&ssl, keys, sid, g_cipher, g_ciphers,
- certCb, NULL, NULL, NULL, &options);
- }
+ /* We are passing the IP address of the server as the expected name */
+ /* To skip certificate subject name tests, pass NULL instead of g_ip */
+ if (g_disableCertNameChk == 0)
+ {
+ rc = matrixSslNewClientSession(&ssl, keys, sid, g_cipher, g_ciphers,
+ certCb, g_ip, NULL, NULL, &options);
+ }
+ else
+ {
+ rc = matrixSslNewClientSession(&ssl, keys, sid, g_cipher, g_ciphers,
+ certCb, NULL, NULL, NULL, &options);
+ }
- if (rc != MATRIXSSL_REQUEST_SEND) {
- _psTraceInt("New Client Session Failed: %d. Exiting\n", rc);
- return PS_ARG_FAIL;
- }
+ if (rc != MATRIXSSL_REQUEST_SEND)
+ {
+ _psTraceInt("New Client Session Failed: %d. Exiting\n", rc);
+ return PS_ARG_FAIL;
+ }
/*
- Create the UDP socket and associate the SSL context with it
-*/
- if ((fd = dtlsInitClientSocket(&dtlsCtx, ssl)) < 0) {
- matrixSslDeleteSession(ssl);
- return fd;
- }
+ Create the UDP socket and associate the SSL context with it
+ */
+ if ((fd = dtlsInitClientSocket(&dtlsCtx, ssl)) < 0)
+ {
+ matrixSslDeleteSession(ssl);
+ return fd;
+ }
/*
- Local inits
-*/
- rehandshakeTestDone = resumedRehandshakeTestDone = 0;
- weAreDone = 0; /* resumed handshake exit hint mechanism */
- addrlen = sizeof(dtlsCtx->addr);
- memset(&from, 0x0, sizeof(struct sockaddr_in));
+ Local inits
+ */
+ rehandshakeTestDone = resumedRehandshakeTestDone = 0;
+ weAreDone = 0; /* resumed handshake exit hint mechanism */
+ addrlen = sizeof(dtlsCtx->addr);
+ memset(&from, 0x0, sizeof(struct sockaddr_in));
/*
- Timeout mechanism is implemented according to guidelines in spec
-*/
- tSec = MIN_WAIT_SECS;
- timeout.tv_usec = 0;
+ Timeout mechanism is implemented according to guidelines in spec
+ */
+ tSec = MIN_WAIT_SECS;
+ timeout.tv_usec = 0;
/*
- matrixDtlsGetOutdata will always return data to send. If a new outgoing
- flight is not waiting to be send a resend of the previous flight will be
- returned.
-*/
+ matrixDtlsGetOutdata will always return data to send. If a new outgoing
+ flight is not waiting to be send a resend of the previous flight will be
+ returned.
+ */
WRITE_MORE:
- while ((len = matrixDtlsGetOutdata(ssl, &buf)) > 0) {
-#ifdef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
- if (test_lost_cipherspec_change_rehandshake && drop_next_cipherspec_packet)
- transferred = udpSend(fd, buf, len, (struct sockaddr*)&dtlsCtx->addr,
- addrlen, (int)tSec,
- packet_loss_prob, &drop_next_cipherspec_packet);
- else
-#endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
- transferred = udpSend(fd, buf, len, (struct sockaddr*)&dtlsCtx->addr,
- addrlen, (int)tSec,
- packet_loss_prob, NULL);
+ while ((len = matrixDtlsGetOutdata(ssl, &buf)) > 0)
+ {
+# ifdef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
+ if (test_lost_cipherspec_change_rehandshake && drop_next_cipherspec_packet)
+ {
+ transferred = udpSend(fd, buf, len, (struct sockaddr *) &dtlsCtx->addr,
+ addrlen, (int) tSec,
+ packet_loss_prob, &drop_next_cipherspec_packet);
+ }
+ else
+# endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
+ transferred = udpSend(fd, buf, len, (struct sockaddr *) &dtlsCtx->addr,
+ addrlen, (int) tSec,
+ packet_loss_prob, NULL);
- if (transferred <= 0) {
- goto L_CLOSE_ERR;
- } else {
- /* Always indicate the entire datagram was sent as there is no
- way for DTLS to handle partial records. Resends and timeouts will
- handle any problems */
- if ((rc = matrixDtlsSentData(ssl, len)) < 0) {
- goto L_CLOSE_ERR;
- }
- if (rc == MATRIXSSL_REQUEST_CLOSE) {
- /* This is a 'graceful' exit so return success */
- closeConn(dtlsCtx, fd);
- return MATRIXSSL_SUCCESS;
- }
- if (rc == MATRIXSSL_HANDSHAKE_COMPLETE) {
- /* This is the resumed handshake endgame case and is a bit more
- problematic than the standard case because we are the last
- to send and we can't be sure the server received our FINISHED
- message. Let's handle this in our example by waiting another
- timeout to see if the server is trying to resend */
- _psTrace("Resumed handshake case. Pausing to check ");
- _psTrace("server received final FINISHED message\n");
- tSec = 4;
- timeout.tv_usec = 0;
- weAreDone = 1;
- }
- /* SSL_REQUEST_SEND is handled by loop logic */
- }
- }
+ if (transferred <= 0)
+ {
+ goto L_CLOSE_ERR;
+ }
+ else
+ {
+ /* Always indicate the entire datagram was sent as there is no
+ way for DTLS to handle partial records. Resends and timeouts will
+ handle any problems */
+ if ((rc = matrixDtlsSentData(ssl, len)) < 0)
+ {
+ goto L_CLOSE_ERR;
+ }
+ if (rc == MATRIXSSL_REQUEST_CLOSE)
+ {
+ /* This is a 'graceful' exit so return success */
+ closeConn(dtlsCtx, fd);
+ return MATRIXSSL_SUCCESS;
+ }
+ if (rc == MATRIXSSL_HANDSHAKE_COMPLETE)
+ {
+ /* This is the resumed handshake endgame case and is a bit more
+ problematic than the standard case because we are the last
+ to send and we can't be sure the server received our FINISHED
+ message. Let's handle this in our example by waiting another
+ timeout to see if the server is trying to resend */
+ _psTrace("Resumed handshake case. Pausing to check ");
+ _psTrace("server received final FINISHED message\n");
+ tSec = 4;
+ timeout.tv_usec = 0;
+ weAreDone = 1;
+ }
+ /* SSL_REQUEST_SEND is handled by loop logic */
+ }
+ }
READ_MORE:
- /* Select is the DTLS timeout/resend mechanism */
- FD_ZERO(&readfd);
- FD_SET(fd, &readfd);
- timeout.tv_sec = tSec;
+ /* Select is the DTLS timeout/resend mechanism */
+ FD_ZERO(&readfd);
+ FD_SET(fd, &readfd);
+ timeout.tv_sec = tSec;
- if ((val = select(fd+1, &readfd, NULL, NULL, &timeout)) < 0) {
- if (SOCKET_ERRNO != EINTR) {
- psTraceIntDtls("unhandled error %d from select", SOCKET_ERRNO);
- goto L_CLOSE_ERR;
- }
- goto READ_MORE;
- }
- /* Check for timeout or select wake-up */
- if (!FD_ISSET(fd, &readfd)) {
- /* Timed out. For good? */
- psTraceIntDtls("select timed out %d\n", val);
- if (tSec == MAX_WAIT_SECS) {
- psTraceDtls("Max Timeout. Leaving\n");
- goto L_CLOSE_ERR;
- }
- tSec *= 2;
- /* Our special exit case for resumed handshakes was simply to wait
- and see if the server was resending its FINISHED message. If not,
- safe to assume we are connected. Send app data and leave */
- if (weAreDone == 1) {
- if (TEST_DTLS_CLIENT_RESUMED_REHANDSHAKE == 1 &&
- resumedRehandshakeTestDone == 0) {
- sendHelloWorld(dtlsCtx);
- _psTrace("--- Initiating resumed rehandshake ---\n");
- resumedRehandshakeTestDone = 1;
- weAreDone = 0;
- matrixSslEncodeRehandshake(ssl, NULL, NULL, 0, g_cipher,
- g_ciphers);
- goto WRITE_MORE;
- }
- sendHelloWorld(dtlsCtx);
- closeConn(dtlsCtx, fd);
- return MATRIXSSL_SUCCESS;
- }
- /* Normal timeout case is to resend flight */
- goto WRITE_MORE;
- }
+ if ((val = select(fd + 1, &readfd, NULL, NULL, &timeout)) < 0)
+ {
+ if (SOCKET_ERRNO != EINTR)
+ {
+ psTraceIntDtls("unhandled error %d from select", SOCKET_ERRNO);
+ goto L_CLOSE_ERR;
+ }
+ goto READ_MORE;
+ }
+ /* Check for timeout or select wake-up */
+ if (!FD_ISSET(fd, &readfd))
+ {
+ /* Timed out. For good? */
+ psTraceIntDtls("select timed out %d\n", val);
+ if (tSec == MAX_WAIT_SECS)
+ {
+ psTraceDtls("Max Timeout. Leaving\n");
+ goto L_CLOSE_ERR;
+ }
+ tSec *= 2;
+ /* Our special exit case for resumed handshakes was simply to wait
+ and see if the server was resending its FINISHED message. If not,
+ safe to assume we are connected. Send app data and leave */
+ if (weAreDone == 1)
+ {
+ if (TEST_DTLS_CLIENT_RESUMED_REHANDSHAKE == 1 &&
+ resumedRehandshakeTestDone == 0)
+ {
+ sendHelloWorld(dtlsCtx);
+ _psTrace("--- Initiating resumed rehandshake ---\n");
+ resumedRehandshakeTestDone = 1;
+ weAreDone = 0;
+ matrixSslEncodeRehandshake(ssl, NULL, NULL, 0, g_cipher,
+ g_ciphers);
+ goto WRITE_MORE;
+ }
+ sendHelloWorld(dtlsCtx);
+ closeConn(dtlsCtx, fd);
+ return MATRIXSSL_SUCCESS;
+ }
+ /* Normal timeout case is to resend flight */
+ goto WRITE_MORE;
+ }
- /* Select woke. Reset timeout */
- tSec = MIN_WAIT_SECS;
+ /* Select woke. Reset timeout */
+ tSec = MIN_WAIT_SECS;
- if ((len = matrixSslGetReadbuf(ssl, &buf)) <= 0) {
- goto L_CLOSE_ERR;
- }
- fromLen = sizeof(struct sockaddr_in);
- if ((transferred = (int32)recvfrom(fd, buf, len, MSG_DONTWAIT,
- (struct sockaddr*)&from, &fromLen)) < 0) {
- goto L_CLOSE_ERR;
- }
+ if ((len = matrixSslGetReadbuf(ssl, &buf)) <= 0)
+ {
+ goto L_CLOSE_ERR;
+ }
+ fromLen = sizeof(struct sockaddr_in);
+ if ((transferred = (int32) recvfrom(fd, buf, len, MSG_DONTWAIT,
+ (struct sockaddr *) &from, &fromLen)) < 0)
+ {
+ goto L_CLOSE_ERR;
+ }
-#ifdef USE_DTLS_DEBUG_TRACE
- /* nice for debugging */
- psTraceIntDtls("Read %d bytes from server\n", transferred);
-#endif
+# ifdef USE_DTLS_DEBUG_TRACE
+ /* nice for debugging */
+ psTraceIntDtls("Read %d bytes from server\n", transferred);
+# endif
- /* If EOF, remote socket closed. But we haven't received the HTTP response
- so we consider it an error in the case of an HTTP client */
- if (transferred == 0) {
- goto L_CLOSE_ERR;
- }
- if ((rc = matrixSslReceivedData(ssl, (int32)transferred, &buf,
- (uint32*)&len)) < 0) {
- goto L_CLOSE_ERR;
- }
+ /* If EOF, remote socket closed. But we haven't received the HTTP response
+ so we consider it an error in the case of an HTTP client */
+ if (transferred == 0)
+ {
+ goto L_CLOSE_ERR;
+ }
+ if ((rc = matrixSslReceivedData(ssl, (int32) transferred, &buf,
+ (uint32 *) &len)) < 0)
+ {
+ goto L_CLOSE_ERR;
+ }
PROCESS_MORE:
- switch (rc) {
- case MATRIXSSL_HANDSHAKE_COMPLETE:
- /* This is the ideal protocol scenario to know that the handshake is
- complete when the client sends app data first. This is the normal
- handshake case and the client is the last to receive FINISHED
+ switch (rc)
+ {
+ case MATRIXSSL_HANDSHAKE_COMPLETE:
+ /* This is the ideal protocol scenario to know that the handshake is
+ complete when the client sends app data first. This is the normal
+ handshake case and the client is the last to receive FINISHED
- If enabled, perform a rehandshake test */
- if (TEST_DTLS_CLIENT_REHANDSHAKE == 1 && rehandshakeTestDone == 0) {
- sendHelloWorld(dtlsCtx);
- _psTrace("--- Initiating rehandshake ---\n");
+ If enabled, perform a rehandshake test */
+ if (TEST_DTLS_CLIENT_REHANDSHAKE == 1 && rehandshakeTestDone == 0)
+ {
+ sendHelloWorld(dtlsCtx);
+ _psTrace("--- Initiating rehandshake ---\n");
-#ifdef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
- if (test_lost_cipherspec_change_rehandshake) {
- /*
- Cause an encryption algorithm change during a re-handshake.
- The aim here is to test the dtlsRevertWriteCipher() function,
- in the situation where the CHANGE_CIPHER_SPEC message
- that is supposed to inform the server about the
- algorithm change gets lost.
- The following cipher spec changes are supported:
- TLS_RSA_WITH_AES_128_GCM_SHA256 --> TLS_RSA_WITH_AES_128_CBC_SHA256
- (anything) --> TLS_RSA_WITH_AES_128_GCM_SHA256.
- */
- _psTrace("Forcing a change cipher spec...\n");
- if (g_cipher[0] == TLS_RSA_WITH_AES_128_GCM_SHA256)
- g_cipher[0] = TLS_RSA_WITH_AES_128_CBC_SHA256;
- else
- g_cipher[0] = TLS_RSA_WITH_AES_128_GCM_SHA256;
- if (drop_next_cipherspec_packet == 1)
- drop_next_cipherspec_packet = 0;
- else
- drop_next_cipherspec_packet = 1;
- }
-#endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
- if (matrixSslEncodeRehandshake(ssl, NULL, NULL,
- SSL_OPTION_FULL_HANDSHAKE,
- g_cipher, g_ciphers) == MATRIXSSL_SUCCESS) {
- rehandshakeTestDone = 1;
- goto WRITE_MORE;
- }
- else {
- _psTrace("matrixSslEncodeRehandshake failed\n");
- goto L_CLOSE_ERR;
- }
- }
+# ifdef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
+ if (test_lost_cipherspec_change_rehandshake)
+ {
+ /*
+ Cause an encryption algorithm change during a re-handshake.
+ The aim here is to test the dtlsRevertWriteCipher() function,
+ in the situation where the CHANGE_CIPHER_SPEC message
+ that is supposed to inform the server about the
+ algorithm change gets lost.
+ The following cipher spec changes are supported:
+ TLS_RSA_WITH_AES_128_GCM_SHA256 --> TLS_RSA_WITH_AES_128_CBC_SHA256
+ (anything) --> TLS_RSA_WITH_AES_128_GCM_SHA256.
+ */
+ _psTrace("Forcing a change cipher spec...\n");
+ if (g_cipher[0] == TLS_RSA_WITH_AES_128_GCM_SHA256)
+ {
+ g_cipher[0] = TLS_RSA_WITH_AES_128_CBC_SHA256;
+ }
+ else
+ {
+ g_cipher[0] = TLS_RSA_WITH_AES_128_GCM_SHA256;
+ }
+ if (drop_next_cipherspec_packet == 1)
+ {
+ drop_next_cipherspec_packet = 0;
+ }
+ else
+ {
+ drop_next_cipherspec_packet = 1;
+ }
+ }
+# endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
+ if (matrixSslEncodeRehandshake(ssl, NULL, NULL,
+ SSL_OPTION_FULL_HANDSHAKE,
+ g_cipher, g_ciphers) == MATRIXSSL_SUCCESS)
+ {
+ rehandshakeTestDone = 1;
+ goto WRITE_MORE;
+ }
+ else
+ {
+ _psTrace("matrixSslEncodeRehandshake failed\n");
+ goto L_CLOSE_ERR;
+ }
+ }
- sendHelloWorld(dtlsCtx);
- closeConn(dtlsCtx, fd);
- return MATRIXSSL_SUCCESS;
+ sendHelloWorld(dtlsCtx);
+ closeConn(dtlsCtx, fd);
+ return MATRIXSSL_SUCCESS;
- case MATRIXSSL_APP_DATA:
+ case MATRIXSSL_APP_DATA:
/*
- Would process app data here
-*/
- if ((rc = matrixSslProcessedData(ssl, &buf, (uint32*)&len)) == 0) {
- goto READ_MORE;
- }
- goto PROCESS_MORE;
- case MATRIXSSL_REQUEST_SEND:
- goto WRITE_MORE;
- case MATRIXSSL_REQUEST_RECV:
- goto READ_MORE;
- case MATRIXSSL_RECEIVED_ALERT:
- /* The first byte of the buffer is the level */
- /* The second byte is the description */
- if (*buf == SSL_ALERT_LEVEL_FATAL) {
- psTraceIntInfo("Fatal alert: %d, closing connection.\n",
- *(buf + 1));
- goto L_CLOSE_ERR;
- }
- /* Closure alert is normal (and best) way to close */
- if (*(buf + 1) == SSL_ALERT_CLOSE_NOTIFY) {
- closeConn(dtlsCtx, fd);
- return MATRIXSSL_SUCCESS;
- }
- psTraceIntInfo("Warning alert: %d\n", *(buf + 1));
- if ((rc = matrixSslProcessedData(ssl, &buf, (uint32*)&len)) == 0) {
- /* No more data in buffer. Might as well read for more. */
- goto READ_MORE;
- }
- goto PROCESS_MORE;
- default:
- /* If rc <= 0 we fall here */
- goto L_CLOSE_ERR;
- }
+ Would process app data here
+ */
+ if ((rc = matrixSslProcessedData(ssl, &buf, (uint32 *) &len)) == 0)
+ {
+ goto READ_MORE;
+ }
+ goto PROCESS_MORE;
+ case MATRIXSSL_REQUEST_SEND:
+ goto WRITE_MORE;
+ case MATRIXSSL_REQUEST_RECV:
+ goto READ_MORE;
+ case MATRIXSSL_RECEIVED_ALERT:
+ /* The first byte of the buffer is the level */
+ /* The second byte is the description */
+ if (*buf == SSL_ALERT_LEVEL_FATAL)
+ {
+ psTraceIntInfo("Fatal alert: %d, closing connection.\n",
+ *(buf + 1));
+ goto L_CLOSE_ERR;
+ }
+ /* Closure alert is normal (and best) way to close */
+ if (*(buf + 1) == SSL_ALERT_CLOSE_NOTIFY)
+ {
+ closeConn(dtlsCtx, fd);
+ return MATRIXSSL_SUCCESS;
+ }
+ psTraceIntInfo("Warning alert: %d\n", *(buf + 1));
+ if ((rc = matrixSslProcessedData(ssl, &buf, (uint32 *) &len)) == 0)
+ {
+ /* No more data in buffer. Might as well read for more. */
+ goto READ_MORE;
+ }
+ goto PROCESS_MORE;
+ default:
+ /* If rc <= 0 we fall here */
+ goto L_CLOSE_ERR;
+ }
L_CLOSE_ERR:
- _psTrace("DTLS Connection FAIL. Exiting\n");
- closeConn(dtlsCtx, fd);
- return MATRIXSSL_ERROR;
+ _psTrace("DTLS Connection FAIL. Exiting\n");
+ closeConn(dtlsCtx, fd);
+ return MATRIXSSL_ERROR;
}
/******************************************************************************/
/*
- Example application data send
-*/
+ Example application data send
+ */
static int32 sendHelloWorld(sslDtls_t *dtlsCtx)
{
- unsigned char *buf;
- int32 avail, len, ret;
+ unsigned char *buf;
+ int32 avail, len, ret;
- _psTrace("DTLS handshake complete. Sending sample application data\n");
- len = (int32)strlen((char*)helloWorld) + 1;
+ _psTrace("DTLS handshake complete. Sending sample application data\n");
+ len = (int32) strlen((char *) helloWorld) + 1;
/*
- Get free buffer, copy in plaintext, and encode
-*/
- if ((avail = matrixSslGetWritebuf(dtlsCtx->ssl, &buf, len)) < 0) {
- return PS_MEM_FAIL;
- }
- avail = min(avail, len);
- strncpy((char*)buf, (char*)helloWorld, avail);
+ Get free buffer, copy in plaintext, and encode
+ */
+ if ((avail = matrixSslGetWritebuf(dtlsCtx->ssl, &buf, len)) < 0)
+ {
+ return PS_MEM_FAIL;
+ }
+ avail = min(avail, len);
+ strncpy((char *) buf, (char *) helloWorld, avail);
- if ((ret = matrixSslEncodeWritebuf(dtlsCtx->ssl, avail)) < 0) {
- return ret;
- }
+ if ((ret = matrixSslEncodeWritebuf(dtlsCtx->ssl, avail)) < 0)
+ {
+ return ret;
+ }
/*
- Get the encoded buffer and write it out
-*/
- while ((len = matrixDtlsGetOutdata(dtlsCtx->ssl, &buf)) > 0) {
- ret = (int32)sendto(dtlsCtx->fd, buf, len, 0,
- (struct sockaddr*)&dtlsCtx->addr, sizeof(struct sockaddr_in));
- if (ret == -1) {
- perror("sendto");
- exit(1);
- }
- matrixDtlsSentData(dtlsCtx->ssl, len);
- }
- return PS_SUCCESS;
+ Get the encoded buffer and write it out
+ */
+ while ((len = matrixDtlsGetOutdata(dtlsCtx->ssl, &buf)) > 0)
+ {
+ ret = (int32) sendto(dtlsCtx->fd, buf, len, 0,
+ (struct sockaddr *) &dtlsCtx->addr, sizeof(struct sockaddr_in));
+ if (ret == -1)
+ {
+ perror("sendto");
+ exit(1);
+ }
+ matrixDtlsSentData(dtlsCtx->ssl, len);
+ }
+ return PS_SUCCESS;
}
static void usage(void)
{
- printf("\nusage: client { option }\n"
- "\n"
- "where option can be one of the following:\n"
- "\n"
- "-c - Comma separated list of ciphers nums\n"
- "-d - Disable server certicate name/addr chk\n"
- "-h - Print usage and exit\n"
- "-k - RSA keyLen (if using client auth)\n"
- "-n - Num of new (full handshake) sessions\n"
- "-p - Port number for DTLS server\n"
- "-r - Num of resumed DTLS sesssions\n"
- "-s - IP address of server machine/interface\n"
-#ifdef DTLS_PACKET_LOSS_TEST
- "-l - Reciprocal of packet loss probability\n"
- " (for packet loss simulation tests)\n"
-#endif /* DTLS_PACKET_LOSS_TEST */
-#ifdef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
- "-x - Run test, where the client tries to change\n"
- " the cipher spec during a re-handshake and\n"
- " the CHANGE_CIPHER_SPEC message is lost.\n"
-#endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
- "\n"
- "where -s is a required option (i.e. has no current default, and\n"
- "serverPortNum is usually 443 or 4433. The cipherList is a comma separated list\n"
- "of cipher numbers to propose. It should NOT contain any spaces.\n\n");
+ printf("\nusage: client { option }\n"
+ "\n"
+ "where option can be one of the following:\n"
+ "\n"
+ "-c - Comma separated list of ciphers nums\n"
+ "-d - Disable server certicate name/addr chk\n"
+ "-h - Print usage and exit\n"
+ "-k - RSA keyLen (if using client auth)\n"
+ "-n - Num of new (full handshake) sessions\n"
+ "-p - Port number for DTLS server\n"
+ "-r - Num of resumed DTLS sesssions\n"
+ "-s - IP address of server machine/interface\n"
+# ifdef DTLS_PACKET_LOSS_TEST
+ "-l - Reciprocal of packet loss probability\n"
+ " (for packet loss simulation tests)\n"
+# endif /* DTLS_PACKET_LOSS_TEST */
+# ifdef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
+ "-x - Run test, where the client tries to change\n"
+ " the cipher spec during a re-handshake and\n"
+ " the CHANGE_CIPHER_SPEC message is lost.\n"
+# endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
+ "\n"
+ "where -s is a required option (i.e. has no current default, and\n"
+ "serverPortNum is usually 443 or 4433. The cipherList is a comma separated list\n"
+ "of cipher numbers to propose. It should NOT contain any spaces.\n\n");
- printf("Common ciphers and the cipher number to use in the cipherList:\n"
- " 53 TLS_RSA_WITH_AES_256_CBC_SHA\n"
- " 47 TLS_RSA_WITH_AES_128_CBC_SHA\n"
- " 10 SSL_RSA_WITH_3DES_EDE_CBC_SHA\n"
- " 5 SSL_RSA_WITH_RC4_128_SHA\n"
- " 4 SSL_RSA_WITH_RC4_128_MD5\n");
+ printf("Common ciphers and the cipher number to use in the cipherList:\n"
+ " 53 TLS_RSA_WITH_AES_256_CBC_SHA\n"
+ " 47 TLS_RSA_WITH_AES_128_CBC_SHA\n"
+ " 10 SSL_RSA_WITH_3DES_EDE_CBC_SHA\n"
+ " 5 SSL_RSA_WITH_RC4_128_SHA\n"
+ " 4 SSL_RSA_WITH_RC4_128_MD5\n");
}
-// Returns number of cipher numbers found, or -1 if an error.
-static int32 parse_cipher_list(char *cipherListString,
- uint16_t cipher_array[],
- uint32 size_of_cipher_array)
+/* Returns number of cipher numbers found, or -1 if an error. */
+static int32 parse_cipher_list(char *cipherListString,
+ psCipher16_t cipher_array[],
+ uint32 size_of_cipher_array)
{
- int32 numCiphers, cipher;
- char *endPtr;
+ int32 numCiphers, cipher;
+ char *endPtr;
- // Convert the cipherListString into an array of cipher numbers.
- numCiphers = 0;
- while (cipherListString != NULL)
- {
- cipher = (int32)strtol(cipherListString, &endPtr, 10);
- if (endPtr == cipherListString)
- {
- printf("The remaining cipherList has no cipher numbers - '%s'\n",
- cipherListString);
- return -1;
- }
- else if (size_of_cipher_array <= numCiphers)
- {
- printf("Too many cipher numbers supplied. limit is %d\n",
- size_of_cipher_array);
- return -1;
- }
- else
- {
- cipher_array[numCiphers++] = cipher;
- if (*endPtr == '\0')
- break;
- else if (*endPtr != ',')
- {
- printf("\n");
- return -1;
- }
+ /* Convert the cipherListString into an array of cipher numbers. */
+ numCiphers = 0;
+ while (cipherListString != NULL)
+ {
+ cipher = (int32) strtol(cipherListString, &endPtr, 10);
+ if (endPtr == cipherListString)
+ {
+ printf("The remaining cipherList has no cipher numbers - '%s'\n",
+ cipherListString);
+ return -1;
+ }
+ else if (size_of_cipher_array <= numCiphers)
+ {
+ printf("Too many cipher numbers supplied. limit is %d\n",
+ size_of_cipher_array);
+ return -1;
+ }
+ else
+ {
+ cipher_array[numCiphers++] = cipher;
+ if (*endPtr == '\0')
+ {
+ break;
+ }
+ else if (*endPtr != ',')
+ {
+ printf("\n");
+ return -1;
+ }
- cipherListString = endPtr + 1;
- }
- }
+ cipherListString = endPtr + 1;
+ }
+ }
- return numCiphers;
+ return numCiphers;
}
/* Return 0 on good set of cmd options, return -1 if a bad cmd option is
encountered OR a request for help is seen (i.e. '-h' option). */
static int32 process_cmd_options(int32 argc, char **argv)
{
- int optionChar, key_len, numCiphers, g_ip_set;
- char *cipherListString;
+ int optionChar, key_len, numCiphers, g_ip_set;
+ char *cipherListString;
- // Set some default options:
- memset(g_cipher, 0, sizeof(g_cipher));
- memset(g_ip, 0, sizeof(g_ip));
- memset(g_path, 0, sizeof(g_path));
+ /* Set some default options: */
+ memset(g_cipher, 0, sizeof(g_cipher));
+ memset(g_ip, 0, sizeof(g_ip));
+ memset(g_path, 0, sizeof(g_path));
- g_ip_set = 0;
- g_ciphers = 1;
- g_cipher[0] = 47;
- g_disableCertNameChk = 0;
- g_key_len = 1024;
- g_new = 1;
- g_port = 4433;
- g_resumed = 1;
+ g_ip_set = 0;
+ g_ciphers = 1;
+ g_cipher[0] = 47;
+ g_disableCertNameChk = 0;
+ g_key_len = 1024;
+ g_new = 1;
+ g_port = 4433;
+ g_resumed = 1;
- opterr = 0;
- while ((optionChar = getopt(argc, argv, "c:dhk:n:p:r:s:l:x")) != -1)
- {
- switch (optionChar)
- {
- case '?':
- return -1;
+ opterr = 0;
+ while ((optionChar = getopt(argc, argv, "c:dhk:n:p:r:s:l:x")) != -1)
+ {
+ switch (optionChar)
+ {
+ case '?':
+ return -1;
- case 'c':
- // Convert the cipherListString into an array of cipher numbers.
- cipherListString = optarg;
- numCiphers = parse_cipher_list(cipherListString, g_cipher, 16);
- if (numCiphers <= 0)
- return -1;
+ case 'c':
+ /* Convert the cipherListString into an array of cipher numbers. */
+ cipherListString = optarg;
+ numCiphers = parse_cipher_list(cipherListString, g_cipher, 16);
+ if (numCiphers <= 0)
+ {
+ return -1;
+ }
- g_ciphers = numCiphers;
- break;
+ g_ciphers = numCiphers;
+ break;
- case 'd':
- g_disableCertNameChk = 1;
- break;
+ case 'd':
+ g_disableCertNameChk = 1;
+ break;
- case 'h':
- return -1;
+ case 'h':
+ return -1;
- case 'k':
- key_len = atoi(optarg);
- if ((key_len != 1024) && (key_len != 2048) && (key_len != 3072)
- && (key_len != 4096))
- {
- printf("-k option must be followed by a key_len whose value "
- " must be 1024, 2048, 3072 or 4096\n");
- return -1;
- }
+ case 'k':
+ key_len = atoi(optarg);
+ if ((key_len != 1024) && (key_len != 2048) && (key_len != 3072)
+ && (key_len != 4096))
+ {
+ printf("-k option must be followed by a key_len whose value "
+ " must be 1024, 2048, 3072 or 4096\n");
+ return -1;
+ }
- g_key_len = key_len;
- break;
+ g_key_len = key_len;
+ break;
- case 'n':
- g_new = atoi(optarg);
- break;
+ case 'n':
+ g_new = atoi(optarg);
+ break;
- case 'p':
- g_port = atoi(optarg);
- break;
+ case 'p':
+ g_port = atoi(optarg);
+ break;
- case 'r':
- g_resumed = atoi(optarg);
- break;
+ case 'r':
+ g_resumed = atoi(optarg);
+ break;
- case 's':
- g_ip_set = 1;
- strncpy(g_ip, optarg, 15);
- break;
+ case 's':
+ g_ip_set = 1;
+ strncpy(g_ip, optarg, 15);
+ break;
-#ifdef DTLS_PACKET_LOSS_TEST
- case 'l':
- packet_loss_prob = atoi(optarg);
- if (packet_loss_prob < 0) {
- printf("invalid -l option\n");
- return -1;
- }
- if (packet_loss_prob > 0) {
- printf("Client simulating packet loss with probability 1/%d\n",
- packet_loss_prob);
- }
- break;
+# ifdef DTLS_PACKET_LOSS_TEST
+ case 'l':
+ packet_loss_prob = atoi(optarg);
+ if (packet_loss_prob < 0)
+ {
+ printf("invalid -l option\n");
+ return -1;
+ }
+ if (packet_loss_prob > 0)
+ {
+ printf("Client simulating packet loss with probability 1/%d\n",
+ packet_loss_prob);
+ }
+ break;
-#ifdef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
- case 'x':
- test_lost_cipherspec_change_rehandshake = 1;
- break;
-#endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
-#endif /* DTLS_PACKET_LOSS_TEST */
- }
- }
+# ifdef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
+ case 'x':
+ test_lost_cipherspec_change_rehandshake = 1;
+ break;
+# endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
+# endif /* DTLS_PACKET_LOSS_TEST */
+ }
+ }
- if (g_ip_set == 0)
- {
- printf("The -s option is currently required!\n");
- return -1;
- }
+ if (g_ip_set == 0)
+ {
+ printf("The -s option is currently required!\n");
+ return -1;
+ }
- return 0;
+ return 0;
}
-#if defined(USE_HEADER_KEYS) && defined(ID_RSA)
+# if defined(USE_HEADER_KEYS) && defined(ID_RSA)
static int32 loadRsaKeys(uint32 key_len, sslKeys_t *keys,
- unsigned char *CAstream, int32 CAstreamLen)
+ unsigned char *CAstream, int32 CAstreamLen)
{
- int32 rc;
+ int32 rc;
- if (key_len == 1024) {
- _psTrace("Using 1024 bit RSA private key\n");
- rc = matrixSslLoadRsaKeysMem(keys, RSA1024, sizeof(RSA1024),
- RSA1024KEY, sizeof(RSA1024KEY), CAstream, CAstreamLen);
- } else if (key_len == 2048) {
- _psTrace("Using 2048 bit RSA private key\n");
- rc = matrixSslLoadRsaKeysMem(keys, RSA2048, sizeof(RSA2048),
- RSA2048KEY, sizeof(RSA2048KEY), CAstream, CAstreamLen);
- } else if (key_len == 3072) {
- _psTrace("Using 3072 bit RSA private key\n");
- rc = matrixSslLoadRsaKeysMem(keys, RSA3072, sizeof(RSA3072),
- RSA3072KEY, sizeof(RSA3072KEY), CAstream, CAstreamLen);
- } else if (key_len == 4096) {
- _psTrace("Using 4096 bit RSA private key\n");
- rc = matrixSslLoadRsaKeysMem(keys, RSA4096, sizeof(RSA4096),
- RSA4096KEY, sizeof(RSA4096KEY), CAstream, CAstreamLen);
- } else {
- rc = -1;
- psAssert((key_len == 1024) || (key_len == 2048) || (key_len == 3072)
- ||(key_len == 4096));
- }
+ if (key_len == 1024)
+ {
+ _psTrace("Using 1024 bit RSA private key\n");
+ rc = matrixSslLoadRsaKeysMem(keys, RSA1024, sizeof(RSA1024),
+ RSA1024KEY, sizeof(RSA1024KEY), CAstream, CAstreamLen);
+ }
+ else if (key_len == 2048)
+ {
+ _psTrace("Using 2048 bit RSA private key\n");
+ rc = matrixSslLoadRsaKeysMem(keys, RSA2048, sizeof(RSA2048),
+ RSA2048KEY, sizeof(RSA2048KEY), CAstream, CAstreamLen);
+ }
+ else if (key_len == 3072)
+ {
+ _psTrace("Using 3072 bit RSA private key\n");
+ rc = matrixSslLoadRsaKeysMem(keys, RSA3072, sizeof(RSA3072),
+ RSA3072KEY, sizeof(RSA3072KEY), CAstream, CAstreamLen);
+ }
+ else if (key_len == 4096)
+ {
+ _psTrace("Using 4096 bit RSA private key\n");
+ rc = matrixSslLoadRsaKeysMem(keys, RSA4096, sizeof(RSA4096),
+ RSA4096KEY, sizeof(RSA4096KEY), CAstream, CAstreamLen);
+ }
+ else
+ {
+ rc = -1;
+ psAssert((key_len == 1024) || (key_len == 2048) || (key_len == 3072)
+ || (key_len == 4096));
+ }
- if (rc < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- if (CAstream) {
- psFree(CAstream, NULL);
- }
- matrixSslDeleteKeys(keys);
- matrixSslClose();
- }
+ if (rc < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ if (CAstream)
+ {
+ psFree(CAstream, NULL);
+ }
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ }
- return rc;
+ return rc;
}
-#endif
+# endif
/******************************************************************************/
/*
- Main routine. Initialize SSL keys and structures, and make two DTLS
- connections, the first with a blank session Id, and the second with
- a session ID populated during the first connection to do a much faster
- session resumption connection the second time.
+ Main routine. Initialize SSL keys and structures, and make two DTLS
+ connections, the first with a blank session Id, and the second with
+ a session ID populated during the first connection to do a much faster
+ session resumption connection the second time.
*/
int32 main(int32 argc, char **argv)
{
- int32 rc, CAstreamLen;
- sslKeys_t *keys;
- sslSessionId_t *sid;
- unsigned char *CAstream;
- int32 rv;
-#ifdef WIN32
- WSADATA wsaData;
- WSAStartup(MAKEWORD(1, 1), &wsaData);
-#endif
- if ((rc = matrixSslOpen()) < 0) {
- _psTrace("MatrixSSL library init failure. Exiting\n");
- return rc;
- }
- if (matrixSslNewKeys(&keys, NULL) < 0) {
- matrixSslClose();
- _psTrace("MatrixSSL library key init failure. Exiting\n");
- return -1;
- }
+ int32 rc, CAstreamLen;
+ sslKeys_t *keys;
+ sslSessionId_t *sid;
+ unsigned char *CAstream;
+ int32 rv;
- if (0 != process_cmd_options(argc, argv)) {
- usage();
- return 0;
- }
- printf("client https://%s:%d%s "
- "new:%d resumed:%d keylen:%d nciphers:%d\n",
- g_ip, g_port, g_path, g_new, g_resumed, g_key_len,
- g_ciphers);
+# ifdef WIN32
+ WSADATA wsaData;
+ WSAStartup(MAKEWORD(1, 1), &wsaData);
+# endif
+ if ((rc = matrixSslOpen()) < 0)
+ {
+ _psTrace("MatrixSSL library init failure. Exiting\n");
+ return rc;
+ }
+ if (matrixSslNewKeys(&keys, NULL) < 0)
+ {
+ matrixSslClose();
+ _psTrace("MatrixSSL library key init failure. Exiting\n");
+ return -1;
+ }
-#ifndef USE_ONLY_PSK_CIPHER_SUITE
-#ifdef USE_HEADER_KEYS
+ if (0 != process_cmd_options(argc, argv))
+ {
+ usage();
+ return 0;
+ }
+ printf("client https://%s:%d%s "
+ "new:%d resumed:%d keylen:%d nciphers:%d\n",
+ g_ip, g_port, g_path, g_new, g_resumed, g_key_len,
+ g_ciphers);
+
+# ifndef USE_ONLY_PSK_CIPHER_SUITE
+# ifdef USE_HEADER_KEYS
/*
- In-memory based keys
- Build the CA list first for potential client auth usage
-*/
- CAstreamLen = 0;
-#ifdef USE_RSA_CIPHER_SUITE
- CAstreamLen += sizeof(RSACAS);
-#ifdef USE_ECC_CIPHER_SUITE
- CAstreamLen += sizeof(ECDHRSACAS);
-#endif
-#endif
-#ifdef USE_ECC_CIPHER_SUITE
- CAstreamLen += sizeof(ECCAS);
-#endif
-#if defined(USE_RSA_CIPHER_SUITE) || defined(USE_ECC_CIPHER_SUITE)
- CAstream = psMalloc(NULL, CAstreamLen);
-#else
- CAstream = NULL;
-#endif
+ In-memory based keys
+ Build the CA list first for potential client auth usage
+ */
+ CAstreamLen = 0;
+# ifdef USE_RSA_CIPHER_SUITE
+ CAstreamLen += sizeof(RSACAS);
+# ifdef USE_ECC_CIPHER_SUITE
+ CAstreamLen += sizeof(ECDHRSACAS);
+# endif
+# endif
+# ifdef USE_ECC_CIPHER_SUITE
+ CAstreamLen += sizeof(ECCAS);
+# endif
+# if defined(USE_RSA_CIPHER_SUITE) || defined(USE_ECC_CIPHER_SUITE)
+ CAstream = psMalloc(NULL, CAstreamLen);
+# else
+ CAstream = NULL;
+# endif
- CAstreamLen = 0;
-#ifdef USE_RSA_CIPHER_SUITE
- memcpy(CAstream, RSACAS, sizeof(RSACAS));
- CAstreamLen += sizeof(RSACAS);
-#ifdef USE_ECC_CIPHER_SUITE
- memcpy(CAstream + CAstreamLen, ECDHRSACAS, sizeof(ECDHRSACAS));
- CAstreamLen += sizeof(ECDHRSACAS);
-#endif
-#endif
-#ifdef USE_ECC_CIPHER_SUITE
- memcpy(CAstream + CAstreamLen, ECCAS, sizeof(ECCAS));
- CAstreamLen += sizeof(ECCAS);
-#endif
+ CAstreamLen = 0;
+# ifdef USE_RSA_CIPHER_SUITE
+ memcpy(CAstream, RSACAS, sizeof(RSACAS));
+ CAstreamLen += sizeof(RSACAS);
+# ifdef USE_ECC_CIPHER_SUITE
+ memcpy(CAstream + CAstreamLen, ECDHRSACAS, sizeof(ECDHRSACAS));
+ CAstreamLen += sizeof(ECDHRSACAS);
+# endif
+# endif
+# ifdef USE_ECC_CIPHER_SUITE
+ memcpy(CAstream + CAstreamLen, ECCAS, sizeof(ECCAS));
+ CAstreamLen += sizeof(ECCAS);
+# endif
-#ifdef ID_RSA
- rc = loadRsaKeys(g_key_len, keys, CAstream, CAstreamLen);
- if (rc < 0) {
- return rc;
- }
-#endif
+# ifdef ID_RSA
+ rc = loadRsaKeys(g_key_len, keys, CAstream, CAstreamLen);
+ if (rc < 0)
+ {
+ return rc;
+ }
+# endif
-#ifdef ID_ECDH_RSA
- if ((rc = matrixSslLoadEcKeysMem(keys, ECDHRSA521, sizeof(ECDHRSA521),
- ECDHRSA521KEY, sizeof(ECDHRSA521KEY), CAstream, CAstreamLen)) < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- if (CAstream) psFree(CAstream, NULL);
- matrixSslDeleteKeys(keys);
- matrixSslClose();
- return rc;
- }
-#endif
+# ifdef ID_ECDH_RSA
+ if ((rc = matrixSslLoadEcKeysMem(keys, ECDHRSA521, sizeof(ECDHRSA521),
+ ECDHRSA521KEY, sizeof(ECDHRSA521KEY), CAstream, CAstreamLen)) < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ if (CAstream)
+ {
+ psFree(CAstream, NULL);
+ }
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ return rc;
+ }
+# endif
-#ifdef ID_ECDH_ECDSA
- if ((rc = matrixSslLoadEcKeysMem(keys, EC384, sizeof(EC384),
- EC384KEY, sizeof(EC384KEY), CAstream, CAstreamLen)) < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- if (CAstream) psFree(CAstream, NULL);
- matrixSslDeleteKeys(keys);
- matrixSslClose();
- return rc;
- }
-#endif
+# ifdef ID_ECDH_ECDSA
+ if ((rc = matrixSslLoadEcKeysMem(keys, EC384, sizeof(EC384),
+ EC384KEY, sizeof(EC384KEY), CAstream, CAstreamLen)) < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ if (CAstream)
+ {
+ psFree(CAstream, NULL);
+ }
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ return rc;
+ }
+# endif
- if (CAstream) psFree(CAstream, NULL);
+ if (CAstream)
+ {
+ psFree(CAstream, NULL);
+ }
-#else
+# else
/*
- File based keys
-*/
- CAstreamLen = 0;
-#ifdef USE_RSA_CIPHER_SUITE
- CAstreamLen += (int32)strlen(rsaCAFile) + 1;
-#ifdef USE_ECC_CIPHER_SUITE
- CAstreamLen += (int32)strlen(ecdhRsaCAFile) + 1;
-#endif
-#endif
-#ifdef USE_ECC_CIPHER_SUITE
- CAstreamLen += (int32)strlen(ecCAFile) + 1;
-#endif
- if (CAstreamLen > 0) {
- CAstream = psMalloc(NULL, CAstreamLen);
- memset(CAstream, 0x0, CAstreamLen);
- } else {
- CAstream = NULL;
- }
+ File based keys
+ */
+ CAstreamLen = 0;
+# ifdef USE_RSA_CIPHER_SUITE
+ CAstreamLen += (int32) strlen(rsaCAFile) + 1;
+# ifdef USE_ECC_CIPHER_SUITE
+ CAstreamLen += (int32) strlen(ecdhRsaCAFile) + 1;
+# endif
+# endif
+# ifdef USE_ECC_CIPHER_SUITE
+ CAstreamLen += (int32) strlen(ecCAFile) + 1;
+# endif
+ if (CAstreamLen > 0)
+ {
+ CAstream = psMalloc(NULL, CAstreamLen);
+ memset(CAstream, 0x0, CAstreamLen);
+ }
+ else
+ {
+ CAstream = NULL;
+ }
- CAstreamLen = 0;
-#ifdef USE_RSA_CIPHER_SUITE
- memcpy(CAstream, rsaCAFile, strlen(rsaCAFile));
- CAstreamLen += strlen(rsaCAFile);
-#ifdef USE_ECC_CIPHER_SUITE
- memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
- memcpy(CAstream + CAstreamLen, ecdhRsaCAFile, strlen(ecdhRsaCAFile));
- CAstreamLen += strlen(ecdhRsaCAFile);
-#endif
-#endif
-#ifdef USE_ECC_CIPHER_SUITE
- if (CAstreamLen > 0) {
- memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
- }
- memcpy(CAstream + CAstreamLen, ecCAFile, strlen(ecCAFile));
-#endif
+ CAstreamLen = 0;
+# ifdef USE_RSA_CIPHER_SUITE
+ memcpy(CAstream, rsaCAFile, strlen(rsaCAFile));
+ CAstreamLen += strlen(rsaCAFile);
+# ifdef USE_ECC_CIPHER_SUITE
+ memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
+ memcpy(CAstream + CAstreamLen, ecdhRsaCAFile, strlen(ecdhRsaCAFile));
+ CAstreamLen += strlen(ecdhRsaCAFile);
+# endif
+# endif
+# ifdef USE_ECC_CIPHER_SUITE
+ if (CAstreamLen > 0)
+ {
+ memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
+ }
+ memcpy(CAstream + CAstreamLen, ecCAFile, strlen(ecCAFile));
+# endif
/* Load Identiy */
-#ifdef EXAMPLE_RSA_KEYS
- if ((rc = matrixSslLoadRsaKeys(keys, rsaCertFile, rsaPrivkeyFile, NULL,
- (char*)CAstream)) < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- if (CAstream) psFree(CAstream);
- matrixSslDeleteKeys(keys);
- matrixSslClose();
- return rc;
- }
-#endif
+# ifdef EXAMPLE_RSA_KEYS
+ if ((rc = matrixSslLoadRsaKeys(keys, rsaCertFile, rsaPrivkeyFile, NULL,
+ (char *) CAstream)) < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ if (CAstream)
+ {
+ psFree(CAstream);
+ }
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ return rc;
+ }
+# endif
-#ifdef EXAMPLE_ECDH_RSA_KEYS
- if ((rc = matrixSslLoadEcKeys(keys, ecdhRsaCertFile, ecdhRsaPrivkeyFile,
- NULL, (char*)CAstream)) < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- if (CAstream) psFree(CAstream);
- matrixSslDeleteKeys(keys);
- matrixSslClose();
- return rc;
- }
-#endif
+# ifdef EXAMPLE_ECDH_RSA_KEYS
+ if ((rc = matrixSslLoadEcKeys(keys, ecdhRsaCertFile, ecdhRsaPrivkeyFile,
+ NULL, (char *) CAstream)) < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ if (CAstream)
+ {
+ psFree(CAstream);
+ }
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ return rc;
+ }
+# endif
-#ifdef EXAMPLE_EC_KEYS
- if ((rc = matrixSslLoadEcKeys(keys, ecCertFile, ecPrivkeyFile, NULL,
- (char*)CAstream)) < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- if (CAstream) psFree(CAstream);
- matrixSslDeleteKeys(keys);
- matrixSslClose();
- return rc;
- }
-#endif
+# ifdef EXAMPLE_EC_KEYS
+ if ((rc = matrixSslLoadEcKeys(keys, ecCertFile, ecPrivkeyFile, NULL,
+ (char *) CAstream)) < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ if (CAstream)
+ {
+ psFree(CAstream);
+ }
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ return rc;
+ }
+# endif
- if (CAstream) psFree(CAstream);
-#endif /* USE_HEADER_KEYS */
-#endif /* USE_ONLY_PSK_CIPHER_SUITE */
+ if (CAstream)
+ {
+ psFree(CAstream);
+ }
+# endif /* USE_HEADER_KEYS */
+# endif /* USE_ONLY_PSK_CIPHER_SUITE */
-#ifdef USE_PSK_CIPHER_SUITE
- for (rc = 0; rc < PSK_HEADER_TABLE_COUNT; rc++) {
+# ifdef USE_PSK_CIPHER_SUITE
+ for (rc = 0; rc < PSK_HEADER_TABLE_COUNT; rc++)
+ {
matrixSslLoadPsk(keys,
PSK_HEADER_TABLE[rc].key, sizeof(PSK_HEADER_TABLE[rc].key),
PSK_HEADER_TABLE[rc].id, sizeof(PSK_HEADER_TABLE[rc].id));
}
-#endif /* USE_PSK_CIPHER_SUITE */
+# endif /* USE_PSK_CIPHER_SUITE */
- rv = MATRIXSSL_ERROR;
+ rv = MATRIXSSL_ERROR;
- matrixSslNewSessionId(&sid, NULL);
- printf("=== %d new connections ===\n", g_new);
- for (rc = 0; rc < g_new; rc++) {
- matrixSslNewSessionId(&sid, NULL);
- rv = dtlsClientConnection(keys, sid);
- if (rv < 0)
- goto out_main;
- /* Leave the final sessionID for resumed connections */
- if (rc + 1 < g_new) matrixSslDeleteSessionId(sid);
- }
- if (g_new) printf("\n");
+ matrixSslNewSessionId(&sid, NULL);
+ printf("=== %d new connections ===\n", g_new);
+ for (rc = 0; rc < g_new; rc++)
+ {
+ matrixSslNewSessionId(&sid, NULL);
+ rv = dtlsClientConnection(keys, sid);
+ if (rv < 0)
+ {
+ goto out_main;
+ }
+ /* Leave the final sessionID for resumed connections */
+ if (rc + 1 < g_new)
+ {
+ matrixSslDeleteSessionId(sid);
+ }
+ }
+ if (g_new)
+ {
+ printf("\n");
+ }
- printf("=== %d resumed connections ===\n", g_resumed);
- for (rc = 0; rc < g_resumed; rc++) {
- rv = dtlsClientConnection(keys, sid);
- if (rv < 0)
- goto out_main;
- }
+ printf("=== %d resumed connections ===\n", g_resumed);
+ for (rc = 0; rc < g_resumed; rc++)
+ {
+ rv = dtlsClientConnection(keys, sid);
+ if (rv < 0)
+ {
+ goto out_main;
+ }
+ }
out_main:
- matrixSslDeleteSessionId(sid);
- matrixSslDeleteKeys(keys);
- matrixSslClose();
+ matrixSslDeleteSessionId(sid);
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
-#ifdef WIN32
- _psTrace("Press any key to close");
- getchar();
-#endif
+# ifdef WIN32
+ _psTrace("Press any key to close");
+ getchar();
+# endif
- if (rv == 0)
- return 0;
- else
- return 1;
+ if (rv == 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
}
/******************************************************************************/
/*
- Close a socket and free associated SSL context and buffers
- An attempt is made to send a closure alert
+ Close a socket and free associated SSL context and buffers
+ An attempt is made to send a closure alert
*/
static void closeConn(sslDtls_t *dtls, SOCKET fd)
{
- ssl_t *ssl;
- unsigned char *buf;
- int32 len, ret;
+ ssl_t *ssl;
+ unsigned char *buf;
+ int32 len, ret;
- ssl = dtls->ssl;
+ ssl = dtls->ssl;
- /* Quick attempt to send a closure alert, don't worry about failure */
- if (matrixSslEncodeClosureAlert(ssl) >= 0) {
- if ((len = matrixDtlsGetOutdata(ssl, &buf)) > 0) {
- ret = (int32)sendto(fd, buf, len, 0, (struct sockaddr*)&dtls->addr,
- sizeof(struct sockaddr_in));
- if (ret == -1) {
- /* sendto failed, but we don't care about that because
- the connection was closing. Maybe server was faster
- in closing the connection down. */
- }
- matrixDtlsSentData(ssl, len);
- }
- }
- psFree(dtls, NULL);
- matrixSslDeleteSession(ssl);
- close(fd);
+ /* Quick attempt to send a closure alert, don't worry about failure */
+ if (matrixSslEncodeClosureAlert(ssl) >= 0)
+ {
+ if ((len = matrixDtlsGetOutdata(ssl, &buf)) > 0)
+ {
+ ret = (int32) sendto(fd, buf, len, 0, (struct sockaddr *) &dtls->addr,
+ sizeof(struct sockaddr_in));
+ if (ret == -1)
+ {
+ /* sendto failed, but we don't care about that because
+ the connection was closing. Maybe server was faster
+ in closing the connection down. */
+ }
+ matrixDtlsSentData(ssl, len);
+ }
+ }
+ psFree(dtls, NULL);
+ matrixSslDeleteSession(ssl);
+ close(fd);
}
/******************************************************************************/
/*
- Example callback to do additional certificate validation.
- If this callback is not registered in matrixSslNewService,
- the connection will be accepted or closed based on the status flag.
+ Example callback to do additional certificate validation.
+ If this callback is not registered in matrixSslNewService,
+ the connection will be accepted or closed based on the status flag.
*/
static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert)
{
-#ifndef USE_ONLY_PSK_CIPHER_SUITE
+# ifndef USE_ONLY_PSK_CIPHER_SUITE
- /* Example to allow anonymous connections based on a define */
- if (alert > 0) {
- if (ALLOW_ANON_CONNECTIONS) {
- _psTraceStr("Allowing anonymous connection for: %s.\n",
- cert->subject.commonName);
- return SSL_ALLOW_ANON_CONNECTION;
- }
- _psTrace("Certificate callback returning fatal alert\n");
- return alert;
- }
+ /* Example to allow anonymous connections based on a define */
+ if (alert > 0)
+ {
+ if (ALLOW_ANON_CONNECTIONS)
+ {
+ _psTraceStr("Allowing anonymous connection for: %s.\n",
+ cert->subject.commonName);
+ return SSL_ALLOW_ANON_CONNECTION;
+ }
+ _psTrace("Certificate callback returning fatal alert\n");
+ return alert;
+ }
- psTraceStrDtls("Validated cert for: %s.\n", cert->subject.commonName);
+ psTraceStrDtls("Validated cert for: %s.\n", cert->subject.commonName);
-#endif /* !USE_ONLY_PSK_CIPHER_SUITE */
- return PS_SUCCESS;
+# endif /* !USE_ONLY_PSK_CIPHER_SUITE */
+ return PS_SUCCESS;
}
#else
/******************************************************************************/
/*
- Stub main for compiling without dtls and client enabled
-*/
+ Stub main for compiling without dtls and client enabled
+ */
int32 main(int32 argc, char **argv)
{
- printf("USE_DTLS and USE_CLIENT_SIDE_SSL must be enabled in " \
- "matrixsslConfig.h at build time to run this application\n");
- return -1;
+ printf("USE_DTLS and USE_CLIENT_SIDE_SSL must be enabled in " \
+ "matrixsslConfig.h at build time to run this application\n");
+ return -1;
}
#endif /* USE_DTLS && USE_CLIENT_SIDE_SSL */
diff --git a/apps/dtls/dtlsCommon.c b/apps/dtls/dtlsCommon.c
index 0b304f9..4095051 100644
--- a/apps/dtls/dtlsCommon.c
+++ b/apps/dtls/dtlsCommon.c
@@ -1,125 +1,142 @@
/**
- * @file dtlsCommon.c
- * @version $Format:%h%d$
+ * @file dtlsCommon.c
+ * @version $Format:%h%d$
*/
/*
- * Copyright (c) 2014-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2014-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
#include "dtlsCommon.h"
+/* Currently this example uses _psTrace for tracing, so osdep.h is needed: */
+#include "core/osdep.h"
+#include "core/psUtil.h"
#ifdef USE_DTLS
-#ifdef DTLS_PACKET_LOSS_TEST
+# ifdef DTLS_PACKET_LOSS_TEST
static int num_dropped = 0;
-#endif /* DTLS_PACKET_LOSS_TEST */
+# endif /* DTLS_PACKET_LOSS_TEST */
/******************************************************************************/
/*
- Set up a PRNG context for dropping random packets
-*/
+ Set up a PRNG context for dropping random packets
+ */
void udpInitProxy(void)
{
- /* This function is no longer needed, since we are
- using matrixCryptoGetPrngData instead of psGetPrng. */
+ /* This function is no longer needed, since we are
+ using psGetPrngLocked instead of psGetPrng. */
}
/******************************************************************************/
/*
- Wrapper around sendto to easily plug in and out the dropped packet tests
-*/
+ Wrapper around sendto to easily plug in and out the dropped packet tests
+ */
int32 udpSend(SOCKET s, unsigned char *buf, int len,
- const struct sockaddr *to, int tolen, int flags,
- int packet_loss_prob, int *drop_rehandshake_cipher_spec)
+ const struct sockaddr *to, int tolen, int flags,
+ int packet_loss_prob, int *drop_rehandshake_cipher_spec)
{
- int32 sent;
+ int32 sent;
-#ifdef DTLS_PACKET_LOSS_TEST
-#ifdef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
- if (drop_rehandshake_cipher_spec != NULL
- && *drop_rehandshake_cipher_spec == 1) {
- /* Test dropping a CIPHER_SPEC_CHANGE containing the new cipher spec
- during a re-handshake. */
- if (buf[12] == 0x40 ||
- buf[12] == 0x26 /* Quick hack: use record length to find our re-handshake
- CIPHER_SPEC_CHANGE. Note: this trick will probably
- only work in our current test scenario and may stop
- working if e.g. the ciphers used in the test
- are changed. */
- ) {
- *drop_rehandshake_cipher_spec = 0;
- psTraceIntDtls("Didn't send (CHANGE_CIPHER_SPEC flight): %d\n", len);
- ++num_dropped;
- }
- else {
- if ((sent = sendto(s, buf, len, 0, to, tolen)) < 0) {
- return -1;
- }
- psTraceIntDtls("Sent %d bytes\n", sent);
- }
- }
- else {
-#endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
- /* Test random packet loss. */
- uint32 randInt;
- (void)matrixCryptoGetPrngData((unsigned char*)&randInt,
- sizeof(uint32), NULL);
+# ifdef DTLS_PACKET_LOSS_TEST
+# ifdef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
+ if (drop_rehandshake_cipher_spec != NULL
+ && *drop_rehandshake_cipher_spec == 1)
+ {
+ /* Test dropping a CIPHER_SPEC_CHANGE containing the new cipher spec
+ during a re-handshake. */
+ if (buf[12] == 0x40 ||
+ buf[12] == 0x26 /* Quick hack: use record length to find our re-handshake
+ CIPHER_SPEC_CHANGE. Note: this trick will probably
+ only work in our current test scenario and may stop
+ working if e.g. the ciphers used in the test
+ are changed. */
+ )
+ {
+ *drop_rehandshake_cipher_spec = 0;
+ psTraceIntDtls("Didn't send (CHANGE_CIPHER_SPEC flight): %d\n", len);
+ ++num_dropped;
+ }
+ else
+ {
+ if ((sent = sendto(s, buf, len, 0, to, tolen)) < 0)
+ {
+ return -1;
+ }
+ psTraceIntDtls("Sent %d bytes\n", sent);
+ }
+ }
+ else
+ {
+# endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
+ /* Test random packet loss. */
+ uint32 randInt;
+ (void) psGetPrngLocked((unsigned char *) &randInt,
+ sizeof(uint32), NULL);
- if ((packet_loss_prob == 0) || (randInt % packet_loss_prob)) {
- if ((sent = sendto(s, buf, len, 0, to, tolen)) < 0) {
- return -1;
- }
- psTraceIntDtls("Sent %d bytes\n", sent);
- } else {
- /* flags is used here as the current timeout value. if it's too high
- we've already skipped a few sends so let's not timeout */
- if (flags >= 16) {
- if ((sent = sendto(s, buf, len, 0, to, tolen)) < 0) {
- return -1;
- }
- psTraceIntDtls("Sent %d bytes\n", sent);
- } else {
- psTraceIntDtls("Didn't send: %d\n", len);
- ++num_dropped;
- }
- }
-#ifdef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
- }
-#endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
-#else
- if ((sent = (int32)sendto(s, buf, len, 0, to, tolen)) < 0) {
- return -1;
- }
- psTraceIntDtls("Sent %d bytes\n", sent);
-#endif /* DTLS_PACKET_LOSS_TEST */
-#ifdef DTLS_PACKET_LOSS_TEST
- psTraceIntDtls("%d packets dropped so far\n",
- num_dropped);
-#endif /* DTLS_PACKET_LOSS_TEST */
- return len;
+ if ((packet_loss_prob == 0) || (randInt % packet_loss_prob))
+ {
+ if ((sent = sendto(s, buf, len, 0, to, tolen)) < 0)
+ {
+ return -1;
+ }
+ psTraceIntDtls("Sent %d bytes\n", sent);
+ }
+ else
+ {
+ /* flags is used here as the current timeout value. if it's too high
+ we've already skipped a few sends so let's not timeout */
+ if (flags >= 16)
+ {
+ if ((sent = sendto(s, buf, len, 0, to, tolen)) < 0)
+ {
+ return -1;
+ }
+ psTraceIntDtls("Sent %d bytes\n", sent);
+ }
+ else
+ {
+ psTraceIntDtls("Didn't send: %d\n", len);
+ ++num_dropped;
+ }
+ }
+# ifdef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
+}
+# endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
+# else
+ if ((sent = (int32) sendto(s, buf, len, 0, to, tolen)) < 0)
+ {
+ return -1;
+ }
+ psTraceIntDtls("Sent %d bytes\n", sent);
+# endif /* DTLS_PACKET_LOSS_TEST */
+# ifdef DTLS_PACKET_LOSS_TEST
+ psTraceIntDtls("%d packets dropped so far\n",
+ num_dropped);
+# endif /* DTLS_PACKET_LOSS_TEST */
+ return len;
}
#endif /* USE_DTLS */
diff --git a/apps/dtls/dtlsCommon.h b/apps/dtls/dtlsCommon.h
index 326d04c..5da80e5 100644
--- a/apps/dtls/dtlsCommon.h
+++ b/apps/dtls/dtlsCommon.h
@@ -1,118 +1,118 @@
/**
- * @file dtlsCommon.h
- * @version $Format:%h%d$
+ * @file dtlsCommon.h
+ * @version $Format:%h%d$
*/
/*
- * Copyright (c) 2014-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2014-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
#ifndef _h_DTLSCOMMON
-#define _h_DTLSCOMMON
+# define _h_DTLSCOMMON
-#include "matrixssl/matrixsslApi.h"
+# include "matrixssl/matrixsslApi.h"
-#ifdef USE_DTLS
+# ifdef USE_DTLS
-#include
-#include
-#include
-#include /* Defines FD_CLOEXEC, etc. */
-#include /* Defines EWOULDBLOCK, etc. */
+# include
+# include
+# include
+# include /* Defines FD_CLOEXEC, etc. */
+# include /* Defines EWOULDBLOCK, etc. */
-#ifdef POSIX
-#include
-#include /* Defines AF_INET, etc. */
-#include /* sockaddr */
-#include /* inet_addr */
-#endif /* POSIX */
+# ifdef POSIX
+# include
+# include /* Defines AF_INET, etc. */
+# include /* sockaddr */
+# include /* inet_addr */
+# endif /* POSIX */
-#ifdef WIN32
-#include
-#include
+# ifdef WIN32
+# include
+# include
-#define SIGPIPE SIGABRT
-#define close closesocket
-#define MSG_DONTWAIT 0
-#endif /* WIN32 */
+# define SIGPIPE SIGABRT
+# define close closesocket
+# define MSG_DONTWAIT 0
+# endif /* WIN32 */
-#ifdef __cplusplus
+# ifdef __cplusplus
extern "C" {
-#endif
+# endif
-#ifndef SOCKET
+# ifndef SOCKET
typedef int SOCKET;
-#endif
+# endif
/*
- Timeout and debug settings
-*/
-#define MIN_WAIT_SECS 1 /* SHOULD be 1. Also the default */
-#define MAX_WAIT_SECS 32 /* SHOULD be 2^x as time is doubled on timeout */
+ Timeout and debug settings
+ */
+# define MIN_WAIT_SECS 1 /* SHOULD be 1. Also the default */
+# define MAX_WAIT_SECS 32 /* SHOULD be 2^x as time is doubled on timeout */
/*
- Enable to intentially not send some datagrams for testing purposes
-*/
-#ifndef DTLS_PACKET_LOSS_TEST
+ Enable to intentially not send some datagrams for testing purposes
+ */
+# ifndef DTLS_PACKET_LOSS_TEST
/* #define DTLS_PACKET_LOSS_TEST */
-#endif /* DTLS_PACKET_LOSS_TEST */
+# endif /* DTLS_PACKET_LOSS_TEST */
/*
- Enable a test where the client tries to change the cipher spec during
- a re-handshake and the resulting CHANGE_CIPHER_SPEC message is lost.
- Requires #define DTLS_PACKET_LOST_TEST.
-*/
-#ifdef DTLS_PACKET_LOSS_TEST
-#ifndef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
+ Enable a test where the client tries to change the cipher spec during
+ a re-handshake and the resulting CHANGE_CIPHER_SPEC message is lost.
+ Requires #define DTLS_PACKET_LOST_TEST.
+ */
+# ifdef DTLS_PACKET_LOSS_TEST
+# ifndef DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE
/* #define DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
-#endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
-#endif /* DTLS_PACKET_LOSS_TEST */
+# endif /* DTLS_TEST_LOST_CIPHERSPEC_CHANGE_REHANDSHAKE */
+# endif /* DTLS_PACKET_LOSS_TEST */
-#define DTLS_FATAL -1
+# define DTLS_FATAL -1
-#ifdef WIN32
-#define SOCKET_ERRNO WSAGetLastError()
-#else
-#define SOCKET_ERRNO errno
-#endif
+# ifdef WIN32
+# define SOCKET_ERRNO WSAGetLastError()
+# else
+# define SOCKET_ERRNO errno
+# endif
-#ifndef INVALID_SOCKET
-#define INVALID_SOCKET -1
-#endif
+# ifndef INVALID_SOCKET
+# define INVALID_SOCKET -1
+# endif
extern void udpInitProxy(void);
extern int32 udpSend(SOCKET s, unsigned char *buf, int len,
- const struct sockaddr *to, int tolen, int flags,
- int packet_loss_prob, int *drop_rehandshake_cipher_spec);
+ const struct sockaddr *to, int tolen, int flags,
+ int packet_loss_prob, int *drop_rehandshake_cipher_spec);
-#ifdef __cplusplus
+# ifdef __cplusplus
}
-#endif
+# endif
-#endif /* USE_DTLS */
-#endif /* _h_DTLSCOMMON */
+# endif /* USE_DTLS */
+#endif /* _h_DTLSCOMMON */
/******************************************************************************/
diff --git a/apps/dtls/dtlsServer.c b/apps/dtls/dtlsServer.c
index d291b0a..1360236 100644
--- a/apps/dtls/dtlsServer.c
+++ b/apps/dtls/dtlsServer.c
@@ -1,79 +1,83 @@
/**
- * @file dtlsServer.c
- * @version $Format:%h%d$
+ * @file dtlsServer.c
+ * @version $Format:%h%d$
*
- * Sample DTLS server.
- * Supports multiple simultaneous clients and non-blocking sockets
+ * Sample DTLS server.
+ * Supports multiple simultaneous clients and non-blocking sockets
*/
/*
- * Copyright (c) 2014-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2014-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
-#include /* Defines SIGTERM, etc. */
+#include /* Defines SIGTERM, etc. */
#ifdef OSX
-#include /* Defines fd_set, etc. */
-#define MSG_NOSIGNAL 0
+# include /* Defines fd_set, etc. */
+# define MSG_NOSIGNAL 0
#endif
#include "dtlsCommon.h"
+/* Currently this example uses _psTrace for tracing, so osdep.h is needed: */
+#include "core/osdep.h"
+#include "core/psUtil.h"
#ifdef USE_DTLS
-#include "../../crypto/cryptoApi.h"
+# include "../../crypto/cryptoApi.h"
/* #define USE_CERT_VALIDATOR */
static int packet_loss_prob = 0; /* Reciprocal of packet loss probability
- (i.e. P(packet loss) = 1/x).
- Default value is 0 (no packet loss). */
+ (i.e. P(packet loss) = 1/x).
+ Default value is 0 (no packet loss). */
/*
- Client management
-*/
-#define MAX_CLIENTS 16
+ Client management
+ */
+# define MAX_CLIENTS 16
-typedef struct {
- psTime_t lastRecvTime;
- uint32 timeout; /* in seconds */
- uint32 connStatus;
- SOCKET fd;
- struct sockaddr_in addr;
- ssl_t *ssl;
+typedef struct
+{
+ psTime_t lastRecvTime;
+ uint32 timeout; /* in seconds */
+ uint32 connStatus;
+ SOCKET fd;
+ struct sockaddr_in addr;
+ ssl_t *ssl;
} serverDtls_t;
-static serverDtls_t *clientTable;
-static uint16 tableSize;
+static serverDtls_t *clientTable;
+static psSize_t tableSize;
-#define RESUMED_HANDSHAKE_COMPLETE 1
+# define RESUMED_HANDSHAKE_COMPLETE 1
/* Static Prototypes */
static int32 initClientList(uint16 maxPeers);
static int32 handleResends(SOCKET sock);
static serverDtls_t *findClient(struct sockaddr_in addr);
static serverDtls_t *registerClient(struct sockaddr_in addr, SOCKET sock,
- ssl_t *ssl);
+ ssl_t *ssl);
static void clearClient(serverDtls_t *dtls);
static void closeClientList();
static SOCKET newUdpSocket(char *ip, short port, int *err);
@@ -83,1197 +87,1300 @@ static void sigintterm_handler(int);
static void usage(void);
static int32 process_cmd_options(int32 argc, char **argv);
-#ifdef USE_DTLS_DEBUG_TRACE
-static unsigned char * getaddrstring(struct sockaddr *addr, int withport);
-#endif
+# ifdef USE_DTLS_DEBUG_TRACE
+static unsigned char *getaddrstring(struct sockaddr *addr, int withport);
+# endif
-#ifdef WIN32
-#pragma message("DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS.")
-#else
-#warning "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
-#endif
+# ifndef MATRIX_TESTING_ENVIRONMENT /* Omit the message when testing. */
+# ifdef WIN32
+# pragma message("DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS.")
+# else
+# warning "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
+# endif
+# endif
-/* Pick ONE cipher suite type you want to use to auto select a certificate
- and private key identity that support those algorithms.
+/* Pick ONE cipher suite type you want to use to auto select a certificate
+ and private key identity that support those algorithms.
- In general, it works the other way: a server would obtain an identity
- certificate and private key and then only enable cipher suites that the
- material supports.
-*/
-//#define ID_RSA /* Standard RSA suites. RSA Key Exchange and Authentication */
-//#define ID_DHE_RSA /* Diffie-Hellman key exchange. RSA Authentication */
-//#define ID_DH_ANON /* Diffie-Hellman key exchange. No auth */
-//#define ID_DHE_PSK /* Diffie-Hellman key exchange. Pre-Shared Key Auth */
-//#define ID_PSK /* Basic Pre-Shared Key suites */
-//#define ID_ECDH_ECDSA /* Elliptic Curve Key Exchange and Authentication */
-//#define ID_ECDHE_ECDSA /* Same as above with ephemeral Key Exchange */
-//#define ID_ECDHE_RSA /* Ephemeral EC Key Exchange, RSA Authentication */
-//#define ID_ECDH_RSA /* EC Key Exchange, RSA Authentication */
+ In general, it works the other way: a server would obtain an identity
+ certificate and private key and then only enable cipher suites that the
+ material supports.
+ */
+/* #define ID_RSA / * Standard RSA suites. RSA Key Exchange and Authentication * / */
+/* #define ID_DHE_RSA / * Diffie-Hellman key exchange. RSA Authentication * / */
+/* #define ID_DH_ANON / * Diffie-Hellman key exchange. No auth * / */
+/* #define ID_DHE_PSK / * Diffie-Hellman key exchange. Pre-Shared Key Auth * / */
+/* #define ID_PSK / * Basic Pre-Shared Key suites * / */
+/* #define ID_ECDH_ECDSA / * Elliptic Curve Key Exchange and Authentication * / */
+/* #define ID_ECDHE_ECDSA / * Same as above with ephemeral Key Exchange * / */
+/* #define ID_ECDHE_RSA / * Ephemeral EC Key Exchange, RSA Authentication * / */
+/* #define ID_ECDH_RSA / * EC Key Exchange, RSA Authentication * / */
-#ifdef ID_RSA
-#ifndef USE_RSA
-#error USE_RSA shall be defined for ID_RSA
-#endif /* USE_RSA */
-#endif /* ID_RSA */
+# ifdef ID_RSA
+# ifndef USE_RSA
+# error USE_RSA shall be defined for ID_RSA
+# endif /* USE_RSA */
+# endif /* ID_RSA */
-#ifdef ID_DHE_RSA
-#if !defined(USE_DH) || !defined(USE_RSA)
-#error USE_DH and USE_RSA shall be defined for ID_DHE_RSA
-#endif /* USE_DH || USE_RSA */
-#endif /* ID_DHE_RSA */
+# ifdef ID_DHE_RSA
+# if !defined(USE_DH) || !defined(USE_RSA)
+# error USE_DH and USE_RSA shall be defined for ID_DHE_RSA
+# endif /* USE_DH || USE_RSA */
+# endif /* ID_DHE_RSA */
-#if defined(ID_DH_ANON) || defined(ID_DHE_PSK)
-#ifndef USE_DH
-#error USE_DH shall be defined for ID_DH_ANON and ID_DHE_PSK
-#endif /* USE_DH */
-#endif /* ID_DH_ANON */
+# if defined(ID_DH_ANON) || defined(ID_DHE_PSK)
+# ifndef USE_DH
+# error USE_DH shall be defined for ID_DH_ANON and ID_DHE_PSK
+# endif /* USE_DH */
+# endif /* ID_DH_ANON */
-#if defined(ID_ECDH_ECDSA) || defined(ID_ECDHE_ECDSA)
-#ifndef USE_ECC
-#error USE_ECC shall be defined for ID_ECDH_ECDSA and ID_ECDHE_ECDSA
-#endif /* USE_ECC */
-#endif /* ID_ECDH_ECDSA || ID_ECDHE_ECDSA */
+# if defined(ID_ECDH_ECDSA) || defined(ID_ECDHE_ECDSA)
+# ifndef USE_ECC
+# error USE_ECC shall be defined for ID_ECDH_ECDSA and ID_ECDHE_ECDSA
+# endif /* USE_ECC */
+# endif /* ID_ECDH_ECDSA || ID_ECDHE_ECDSA */
-#if defined(ID_ECDHE_RSA) || defined(ID_ECDH_RSA)
-#if !defined(USE_ECC) || !defined(USE_RSA)
-#error USE_ECC and USE_RSA shall be defined for ID_ECDHE_RSA and ID_ECDH_RSA
-#endif /* USE_ECC || USE_RSA */
-#endif /* ID_ECDHE_RSA || ID_ECDH_RSA */
+# if defined(ID_ECDHE_RSA) || defined(ID_ECDH_RSA)
+# if !defined(USE_ECC) || !defined(USE_RSA)
+# error USE_ECC and USE_RSA shall be defined for ID_ECDHE_RSA and ID_ECDH_RSA
+# endif /* USE_ECC || USE_RSA */
+# endif /* ID_ECDHE_RSA || ID_ECDH_RSA */
-#define ALLOW_ANON_CONNECTIONS 1
-#define USE_HEADER_KEYS
+# define ALLOW_ANON_CONNECTIONS 1
+# define USE_HEADER_KEYS
-/* The keys that are loaded are compatible with the MatrixSSL sample client.
- The CA files loaded assume the same authentication mechanism as the
- cipher suite
-*/
-#ifdef USE_HEADER_KEYS
+/* The keys that are loaded are compatible with the MatrixSSL sample client.
+ The CA files loaded assume the same authentication mechanism as the
+ cipher suite
+ */
+# ifdef USE_HEADER_KEYS
/* Identity Key and Cert */
-#ifdef ID_RSA
-#define EXAMPLE_RSA_KEYS
-#include "testkeys/RSA/1024_RSA.h"
-#include "testkeys/RSA/1024_RSA_KEY.h"
-#include "testkeys/RSA/2048_RSA.h"
-#include "testkeys/RSA/2048_RSA_KEY.h"
-#include "testkeys/RSA/3072_RSA.h"
-#include "testkeys/RSA/3072_RSA_KEY.h"
-#include "testkeys/RSA/4096_RSA.h"
-#include "testkeys/RSA/4096_RSA_KEY.h"
-#endif
+# ifdef ID_RSA
+# define EXAMPLE_RSA_KEYS
+# include "testkeys/RSA/1024_RSA.h"
+# include "testkeys/RSA/1024_RSA_KEY.h"
+# include "testkeys/RSA/2048_RSA.h"
+# include "testkeys/RSA/2048_RSA_KEY.h"
+# include "testkeys/RSA/3072_RSA.h"
+# include "testkeys/RSA/3072_RSA_KEY.h"
+# include "testkeys/RSA/4096_RSA.h"
+# include "testkeys/RSA/4096_RSA_KEY.h"
+# endif
-#if defined(ID_DHE_RSA) || defined(ID_ECDHE_RSA)
-#define EXAMPLE_RSA_KEYS
-#include "testkeys/RSA/1024_RSA.h"
-#include "testkeys/RSA/1024_RSA_KEY.h"
-#include "testkeys/RSA/2048_RSA.h"
-#include "testkeys/RSA/2048_RSA_KEY.h"
-#include "testkeys/RSA/3072_RSA.h"
-#include "testkeys/RSA/3072_RSA_KEY.h"
-#include "testkeys/RSA/4096_RSA.h"
-#include "testkeys/RSA/4096_RSA_KEY.h"
-#endif
+# if defined(ID_DHE_RSA) || defined(ID_ECDHE_RSA)
+# define EXAMPLE_RSA_KEYS
+# include "testkeys/RSA/1024_RSA.h"
+# include "testkeys/RSA/1024_RSA_KEY.h"
+# include "testkeys/RSA/2048_RSA.h"
+# include "testkeys/RSA/2048_RSA_KEY.h"
+# include "testkeys/RSA/3072_RSA.h"
+# include "testkeys/RSA/3072_RSA_KEY.h"
+# include "testkeys/RSA/4096_RSA.h"
+# include "testkeys/RSA/4096_RSA_KEY.h"
+# endif
-#if defined(ID_ECDHE_ECDSA) || defined(ID_ECDH_ECDSA)
-#define EXAMPLE_EC_KEYS
-#include "testkeys/EC/192_EC.h"
-#include "testkeys/EC/192_EC_KEY.h"
-#include "testkeys/EC/224_EC.h"
-#include "testkeys/EC/224_EC_KEY.h"
-#include "testkeys/EC/256_EC.h"
-#include "testkeys/EC/256_EC_KEY.h"
-#include "testkeys/EC/384_EC.h"
-#include "testkeys/EC/384_EC_KEY.h"
-#include "testkeys/EC/521_EC.h"
-#include "testkeys/EC/521_EC_KEY.h"
-#endif
+# if defined(ID_ECDHE_ECDSA) || defined(ID_ECDH_ECDSA)
+# define EXAMPLE_EC_KEYS
+# include "testkeys/EC/192_EC.h"
+# include "testkeys/EC/192_EC_KEY.h"
+# include "testkeys/EC/224_EC.h"
+# include "testkeys/EC/224_EC_KEY.h"
+# include "testkeys/EC/256_EC.h"
+# include "testkeys/EC/256_EC_KEY.h"
+# include "testkeys/EC/384_EC.h"
+# include "testkeys/EC/384_EC_KEY.h"
+# include "testkeys/EC/521_EC.h"
+# include "testkeys/EC/521_EC_KEY.h"
+# endif
-#ifdef ID_ECDH_RSA
-#define EXAMPLE_ECDH_RSA_KEYS
-#include "testkeys/ECDH_RSA/256_ECDH-RSA.h"
-#include "testkeys/ECDH_RSA/256_ECDH-RSA_KEY.h"
-#include "testkeys/ECDH_RSA/521_ECDH-RSA.h"
-#include "testkeys/ECDH_RSA/521_ECDH-RSA_KEY.h"
-#endif
+# ifdef ID_ECDH_RSA
+# define EXAMPLE_ECDH_RSA_KEYS
+# include "testkeys/ECDH_RSA/256_ECDH-RSA.h"
+# include "testkeys/ECDH_RSA/256_ECDH-RSA_KEY.h"
+# include "testkeys/ECDH_RSA/521_ECDH-RSA.h"
+# include "testkeys/ECDH_RSA/521_ECDH-RSA_KEY.h"
+# endif
-#ifdef REQUIRE_DH_PARAMS
-#include "testkeys/DH/2048_DH_PARAMS.h"
-#endif
+# ifdef REQUIRE_DH_PARAMS
+# include "testkeys/DH/2048_DH_PARAMS.h"
+# endif
-/* CA files for client auth are selected more generously. If the algorithm
- type is supported, we'll load it */
-#ifdef USE_RSA
-#include "testkeys/RSA/ALL_RSA_CAS.h"
-#ifdef USE_ECC
-#include "testkeys/ECDH_RSA/ALL_ECDH-RSA_CAS.h"
-#endif /* USE_ECC */
-#endif /* USE_RSA */
-#ifdef USE_ECC
+/* CA files for client auth are selected more generously. If the algorithm
+ type is supported, we'll load it */
+# ifdef USE_RSA
+# include "testkeys/RSA/ALL_RSA_CAS.h"
+# ifdef USE_ECC
+# include "testkeys/ECDH_RSA/ALL_ECDH-RSA_CAS.h"
+# endif /* USE_ECC */
+# endif /* USE_RSA */
+# ifdef USE_ECC
-#if defined(USE_SECP192R1) && defined(USE_SECP224R1) && defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS.h"
-#endif /* USE_SECP192R1 && USE_SECP224R1 && USE_SECP521R1 */
+# if defined(USE_SECP192R1) && defined(USE_SECP224R1) && defined(USE_SECP521R1)
+# include "testkeys/EC/ALL_EC_CAS.h"
+# endif /* USE_SECP192R1 && USE_SECP224R1 && USE_SECP521R1 */
-#if !defined(USE_SECP192R1) && defined(USE_SECP224R1) && defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192.h"
-#endif /* !USE_SECP192R1 && USE_SECP224R1 && USE_SECP521R1 */
+# if !defined(USE_SECP192R1) && defined(USE_SECP224R1) && defined(USE_SECP521R1)
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192.h"
+# endif /* !USE_SECP192R1 && USE_SECP224R1 && USE_SECP521R1 */
-#if defined(USE_SECP192R1) && !defined(USE_SECP224R1) && defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P224.h"
-#endif /* USE_SECP192R1 && !USE_SECP224R1 && USE_SECP521R1 */
+# if defined(USE_SECP192R1) && !defined(USE_SECP224R1) && defined(USE_SECP521R1)
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P224.h"
+# endif /* USE_SECP192R1 && !USE_SECP224R1 && USE_SECP521R1 */
-#if defined(USE_SECP192R1) && defined(USE_SECP224R1) && !defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P521.h"
-#endif /* USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
+# if defined(USE_SECP192R1) && defined(USE_SECP224R1) && !defined(USE_SECP521R1)
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P521.h"
+# endif /* USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
-#if !defined(USE_SECP192R1) && !defined(USE_SECP224R1) && defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P224.h"
-#endif /* !USE_SECP192R1 && !USE_SECP224R1 && USE_SECP521R1 */
+# if !defined(USE_SECP192R1) && !defined(USE_SECP224R1) && defined(USE_SECP521R1)
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P224.h"
+# endif /* !USE_SECP192R1 && !USE_SECP224R1 && USE_SECP521R1 */
-#if !defined(USE_SECP192R1) && defined(USE_SECP224R1) && !defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P521.h"
-#endif /* !USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
+# if !defined(USE_SECP192R1) && defined(USE_SECP224R1) && !defined(USE_SECP521R1)
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P521.h"
+# endif /* !USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
-#if defined(USE_SECP192R1) && !defined(USE_SECP224R1) && !defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P224_AND_P521.h"
-#endif /* USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
+# if defined(USE_SECP192R1) && !defined(USE_SECP224R1) && !defined(USE_SECP521R1)
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P224_AND_P521.h"
+# endif /* USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
-#if !defined(USE_SECP192R1) && !defined(USE_SECP224R1) && !defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_P224_AND_P521.h"
-#endif /* !USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
+# if !defined(USE_SECP192R1) && !defined(USE_SECP224R1) && !defined(USE_SECP521R1)
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_P224_AND_P521.h"
+# endif /* !USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
-#endif /* USE_ECC */
+# endif /* USE_ECC */
/* File-based keys */
-#else
-#ifdef ID_RSA
-#define EXAMPLE_RSA_KEYS
+# else
+# ifdef ID_RSA
+# define EXAMPLE_RSA_KEYS
static char rsaCertFile[] = "testkeys/RSA/2048_RSA.pem";
static char rsaPrivkeyFile[] = "testkeys/RSA/2048_RSA_KEY.pem";
-#endif
+# endif
-#if defined(ID_DHE_RSA) || defined(ID_ECDHE_RSA)
-#define EXAMPLE_RSA_KEYS
+# if defined(ID_DHE_RSA) || defined(ID_ECDHE_RSA)
+# define EXAMPLE_RSA_KEYS
static char rsaCertFile[] = "testkeys/RSA/2048_RSA.pem";
static char rsaPrivkeyFile[] = "testkeys/RSA/2048_RSA_KEY.pem";
-#endif
+# endif
-#if defined(ID_ECDHE_ECDSA) || defined(ID_ECDH_ECDSA)
-#define EXAMPLE_EC_KEYS
+# if defined(ID_ECDHE_ECDSA) || defined(ID_ECDH_ECDSA)
+# define EXAMPLE_EC_KEYS
static char ecCertFile[] = "testkeys/EC/256_EC.pem";
static char ecPrivkeyFile[] = "testkeys/EC/256_EC_KEY.pem";
-#endif
+# endif
-#ifdef ID_ECDH_RSA
-#define EXAMPLE_ECDH_RSA_KEYS
+# ifdef ID_ECDH_RSA
+# define EXAMPLE_ECDH_RSA_KEYS
static char ecdhRsaCertFile[] = "testkeys/ECDH_RSA/256_ECDH-RSA.pem";
static char ecdhRsaPrivkeyFile[] = "testkeys/ECDH_RSA/256_ECDH-RSA_KEY.pem";
-#endif
+# endif
-#ifdef REQUIRE_DH_PARAMS
+# ifdef REQUIRE_DH_PARAMS
static char dhParamFile[] = "testkeys/DH/2048_DH_PARAMS.pem";
-#endif
+# endif
-/* CA files for client auth are selected more generously. If the algorithm
- type is supported, we'll load it */
-#ifdef USE_RSA
+/* CA files for client auth are selected more generously. If the algorithm
+ type is supported, we'll load it */
+# ifdef USE_RSA
static char rsaCAFile[] = "testkeys/RSA/ALL_RSA_CAS.pem";
static char rsaCA3072File[] = "testkeys/RSA/3072_RSA_CA.pem";
-#ifdef USE_ECC
+# ifdef USE_ECC
static char ecdhRsaCAFile[] = "testkeys/ECDH_RSA/ALL_ECDH-RSA_CAS.pem";
-#endif /* USE_ECC */
-#endif /* USE_RSA */
-#ifdef USE_ECC
+# endif /* USE_ECC */
+# endif /* USE_RSA */
+# ifdef USE_ECC
-#if defined(USE_SECP192R1) && defined(USE_SECP521R1)
+# if defined(USE_SECP192R1) && defined(USE_SECP521R1)
static char ecCAFile[] = "testkeys/EC/ALL_EC_CAS.pem";
-#endif /* USE_SECP192R1 && USE_SECP521R1 */
+# endif /* USE_SECP192R1 && USE_SECP521R1 */
-#if !defined(USE_SECP192R1) && defined(USE_SECP521R1)
+# if !defined(USE_SECP192R1) && defined(USE_SECP521R1)
static char ecCAFile[] = "testkeys/EC/ALL_EC_CAS_EXCEPT_P192.pem";
-#endif /* USE_SECP192R1 && USE_SECP521R1 */
+# endif /* USE_SECP192R1 && USE_SECP521R1 */
-#if defined(USE_SECP192R1) && !defined(USE_SECP521R1)
+# if defined(USE_SECP192R1) && !defined(USE_SECP521R1)
static char ecCAFile[] = "testkeys/EC/ALL_EC_CAS_EXCEPT_P521.pem";
-#endif /* USE_SECP192R1 && USE_SECP521R1 */
+# endif /* USE_SECP192R1 && USE_SECP521R1 */
-#if !defined(USE_SECP192R1) && !defined(USE_SECP521R1)
+# if !defined(USE_SECP192R1) && !defined(USE_SECP521R1)
static char ecCAFile[] = "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P521.pem";
-#endif /* USE_SECP192R1 && USE_SECP521R1 */
+# endif /* USE_SECP192R1 && USE_SECP521R1 */
-#endif /* USE_ECC */
+# endif /* USE_ECC */
-#endif /* USE_FILE_KEYS */
+# endif /* USE_FILE_KEYS */
-#ifdef USE_PSK_CIPHER_SUITE
-#include "testkeys/PSK/psk.h"
-#endif /* PSK */
+# ifdef USE_PSK_CIPHER_SUITE
+# include "testkeys/PSK/psk.h"
+# endif /* PSK */
-static int exitFlag;
+static int exitFlag;
static uint32_t g_rsaKeySize;
static uint32_t g_eccKeySize;
static uint32_t g_ecdhKeySize;
static int g_port;
-#ifdef USE_CERT_VALIDATOR
+# ifdef USE_CERT_VALIDATOR
/******************************************************************************/
/*
- Stub for a user-level certificate validator. Just using
- the default validation value here.
+ Stub for a user-level certificate validator. Just using
+ the default validation value here.
*/
static int32 certValidator(ssl_t *ssl, psX509Cert_t *cert, int32 alert)
{
- /* Example to allow anonymous connections based on a define */
- if (alert > 0) {
- if (ALLOW_ANON_CONNECTIONS) {
- /* Could be NULL if SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */
- if (cert) {
- _psTraceStr("Allowing anonymous connection for: %s.\n",
- cert->subject.commonName);
- } else {
- _psTrace("Client didn't send certificate. Reverting to standard handshake due to SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG\n");
- }
- return SSL_ALLOW_ANON_CONNECTION;
- }
- _psTrace("Certificate callback returning fatal alert\n");
- return alert;
- }
- _psTraceStr("Validated cert for: %s.\n", cert->subject.commonName);
- return 0;
+ /* Example to allow anonymous connections based on a define */
+ if (alert > 0)
+ {
+ if (ALLOW_ANON_CONNECTIONS)
+ {
+ /* Could be NULL if SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */
+ if (cert)
+ {
+ _psTraceStr("Allowing anonymous connection for: %s.\n",
+ cert->subject.commonName);
+ }
+ else
+ {
+ _psTrace("Client didn't send certificate. Reverting to standard handshake due to SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG\n");
+ }
+ return SSL_ALLOW_ANON_CONNECTION;
+ }
+ _psTrace("Certificate callback returning fatal alert\n");
+ return alert;
+ }
+ _psTraceStr("Validated cert for: %s.\n", cert->subject.commonName);
+ return 0;
}
-#else
+# else
/* No certificate validator is needed */
-#define certValidator NULL
-#endif /* USE_CERT_VALIDATOR */
+# define certValidator NULL
+# endif /* USE_CERT_VALIDATOR */
static void usage(void)
{
- printf("\nusage: dltsServer { option }\n"
- "\n"
- "where option can be one of the following:\n"
- "\n"
- "-h - Print usage and exit\n"
- "-r - RSA keyLen (1024|2048|3072|4096)\n"
- "-e - ECC keyLen (192|224|256|384|521)"
- "-d - ECDH_RSA keyLen (256|521)\n"
-#ifdef DTLS_PACKET_LOSS_TEST
- "-l - Reciprocal of packet loss probability\n"
- " (for packet loss simulation tests)\n"
-#endif /* DTLS_PACKET_LOSS_TEST */
- "-p - Port number to use\n"
- );
+ printf("\nusage: dltsServer { option }\n"
+ "\n"
+ "where option can be one of the following:\n"
+ "\n"
+ "-h - Print usage and exit\n"
+ "-r - RSA keyLen (1024|2048|3072|4096)\n"
+ "-e - ECC keyLen (192|224|256|384|521)"
+ "-d - ECDH_RSA keyLen (256|521)\n"
+# ifdef DTLS_PACKET_LOSS_TEST
+ "-l - Reciprocal of packet loss probability\n"
+ " (for packet loss simulation tests)\n"
+# endif /* DTLS_PACKET_LOSS_TEST */
+ "-p - Port number to use\n"
+ );
}
/* Return 0 on good set of cmd options, return -1 if a bad cmd option is
encountered OR a request for help is seen (i.e. '-h' option). */
static int32 process_cmd_options(int32 argc, char **argv)
{
- int32 optionChar;
+ int32 optionChar;
- // Set some default options:
- g_rsaKeySize = 2048;
- g_eccKeySize = g_ecdhKeySize = 256;
+ /* Set some default options: */
+ g_rsaKeySize = 2048;
+ g_eccKeySize = g_ecdhKeySize = 256;
- opterr = 0;
- while ((optionChar = getopt(argc, argv, "hr:e:d:l:p:")) != -1)
- {
- switch (optionChar) {
- case '?':
- return -1;
+ opterr = 0;
+ while ((optionChar = getopt(argc, argv, "hr:e:d:l:p:")) != -1)
+ {
+ switch (optionChar)
+ {
+ case '?':
+ return -1;
- case 'h':
- break;
+ case 'h':
+ break;
- case 'r':
- g_rsaKeySize = atoi(optarg);
- if ((g_rsaKeySize != 1024) && (g_rsaKeySize != 2048)
- && (g_rsaKeySize != 3072) && (g_rsaKeySize != 4096)) {
- printf("invalid -r option\n");
- return -1;
- }
- break;
+ case 'r':
+ g_rsaKeySize = atoi(optarg);
+ if ((g_rsaKeySize != 1024) && (g_rsaKeySize != 2048)
+ && (g_rsaKeySize != 3072) && (g_rsaKeySize != 4096))
+ {
+ printf("invalid -r option\n");
+ return -1;
+ }
+ break;
- case 'e':
- g_eccKeySize = atoi(optarg);
- if ((g_eccKeySize != 192) && (g_eccKeySize != 224)
- && (g_eccKeySize != 256) && (g_eccKeySize != 384)
- && (g_eccKeySize != 521)) {
- printf("invalid -e option\n");
- return -1;
- }
- break;
+ case 'e':
+ g_eccKeySize = atoi(optarg);
+ if ((g_eccKeySize != 192) && (g_eccKeySize != 224)
+ && (g_eccKeySize != 256) && (g_eccKeySize != 384)
+ && (g_eccKeySize != 521))
+ {
+ printf("invalid -e option\n");
+ return -1;
+ }
+ break;
- case 'd':
- g_ecdhKeySize = atoi(optarg);
- if ((g_ecdhKeySize != 256) && (g_ecdhKeySize != 521)) {
- printf("invalid -d option\n");
- return -1;
- }
- break;
+ case 'd':
+ g_ecdhKeySize = atoi(optarg);
+ if ((g_ecdhKeySize != 256) && (g_ecdhKeySize != 521))
+ {
+ printf("invalid -d option\n");
+ return -1;
+ }
+ break;
-#ifdef DTLS_PACKET_LOSS_TEST
- case 'l':
- packet_loss_prob = atoi(optarg);
- if (packet_loss_prob < 0) {
- printf("invalid -l option\n");
- return -1;
- }
- if (packet_loss_prob > 0) {
- printf("Server simulating packet loss with probability 1/%d\n",
- packet_loss_prob);
- }
- break;
-#endif /* DTLS_PACKET_LOSS_TEST */
- case 'p':
- g_port = atoi(optarg);
- if (g_port < 0) {
- printf("invalid -p option\n");
- return -1;
- }
- }
- }
+# ifdef DTLS_PACKET_LOSS_TEST
+ case 'l':
+ packet_loss_prob = atoi(optarg);
+ if (packet_loss_prob < 0)
+ {
+ printf("invalid -l option\n");
+ return -1;
+ }
+ if (packet_loss_prob > 0)
+ {
+ printf("Server simulating packet loss with probability 1/%d\n",
+ packet_loss_prob);
+ }
+ break;
+# endif /* DTLS_PACKET_LOSS_TEST */
+ case 'p':
+ g_port = atoi(optarg);
+ if (g_port < 0)
+ {
+ printf("invalid -p option\n");
+ return -1;
+ }
+ }
+ }
- return 0;
+ return 0;
}
/******************************************************************************/
/*
- Main
-*/
-int main(int argc, char ** argv)
+ Main
+ */
+int main(int argc, char **argv)
{
- struct sockaddr_in inaddr;
- socklen_t inaddrlen;
- struct timeval timeout;
- ssl_t *ssl;
- serverDtls_t *dtlsCtx;
- SOCKET sock;
- fd_set readfd;
- unsigned char *sslBuf, *recvfromBuf, *CAstream;
-#ifdef USE_DTLS_DEBUG_TRACE
- unsigned char *addrstr;
-#endif
-#if !defined(ID_PSK) && !defined(ID_DHE_PSK)
- unsigned char *keyValue, *certValue;
- int32 keyLen, certLen;
-#endif
- sslKeys_t *keys;
- int32 freeBufLen, rc, val, recvLen, err, CAstreamLen;
- int32 sslBufLen, rcr, rcs, sendLen, recvfromBufLen;
- sslSessOpts_t options;
+ struct sockaddr_in inaddr;
+ socklen_t inaddrlen;
+ struct timeval timeout;
+ ssl_t *ssl;
+ serverDtls_t *dtlsCtx;
+ SOCKET sock;
+ fd_set readfd;
+ unsigned char *sslBuf, *recvfromBuf, *CAstream;
-#ifdef WIN32
- WSADATA wsaData;
- WSAStartup(MAKEWORD(1, 1), &wsaData);
-#endif
+# ifdef USE_DTLS_DEBUG_TRACE
+ unsigned char *addrstr;
+# endif
+# if !defined(ID_PSK) && !defined(ID_DHE_PSK)
+ unsigned char *keyValue, *certValue;
+ int32 keyLen, certLen;
+# endif
+ sslKeys_t *keys;
+ int32 freeBufLen, rc, val, recvLen, err, CAstreamLen;
+ int32 sslBufLen, rcr, rcs, sendLen, recvfromBufLen;
+ sslSessOpts_t options;
- rc = 0;
- ssl = NULL;
- dtlsCtx = NULL;
- CAstream = NULL;
- sock = INVALID_SOCKET;
+# ifdef WIN32
+ WSADATA wsaData;
+ WSAStartup(MAKEWORD(1, 1), &wsaData);
+# endif
- if (0 != process_cmd_options(argc, argv)) {
- usage();
- return 0;
- }
- if (sigsetup() < 0) {
- _psTrace("Init error creating signal handlers\n");
- return DTLS_FATAL;
- }
- if (matrixSslOpen() < 0) {
- _psTrace("Init error opening MatrixDTLS library\n");
- return DTLS_FATAL;
- }
- if (matrixSslNewKeys(&keys, NULL) < 0) {
- _psTrace("Init error allocating key structure\n");
- matrixSslClose();
- return DTLS_FATAL;
- }
- if ((rc = initClientList(MAX_CLIENTS)) < 0) {
- _psTrace("Init error opening client list\n");
- goto MATRIX_EXIT;
- }
+ rc = 0;
+ ssl = NULL;
+ dtlsCtx = NULL;
+ CAstream = NULL;
+ sock = INVALID_SOCKET;
-#ifdef USE_HEADER_KEYS
+ if (0 != process_cmd_options(argc, argv))
+ {
+ usage();
+ return 0;
+ }
+ if (sigsetup() < 0)
+ {
+ _psTrace("Init error creating signal handlers\n");
+ return DTLS_FATAL;
+ }
+ if (matrixSslOpen() < 0)
+ {
+ _psTrace("Init error opening MatrixDTLS library\n");
+ return DTLS_FATAL;
+ }
+ if (matrixSslNewKeys(&keys, NULL) < 0)
+ {
+ _psTrace("Init error allocating key structure\n");
+ matrixSslClose();
+ return DTLS_FATAL;
+ }
+ if ((rc = initClientList(MAX_CLIENTS)) < 0)
+ {
+ _psTrace("Init error opening client list\n");
+ goto MATRIX_EXIT;
+ }
+
+# ifdef USE_HEADER_KEYS
/*
- In-memory based keys
- Build the CA list first for potential client auth usage
-*/
- CAstreamLen = 0;
-#ifdef USE_RSA
- CAstreamLen += sizeof(RSACAS);
-#ifdef USE_ECC
- CAstreamLen += sizeof(ECDHRSACAS);
-#endif
-#endif
-#ifdef USE_ECC
- CAstreamLen += sizeof(ECCAS);
-#endif
- CAstream = psMalloc(NULL, CAstreamLen);
+ In-memory based keys
+ Build the CA list first for potential client auth usage
+ */
+ CAstreamLen = 0;
+# ifdef USE_RSA
+ CAstreamLen += sizeof(RSACAS);
+# ifdef USE_ECC
+ CAstreamLen += sizeof(ECDHRSACAS);
+# endif
+# endif
+# ifdef USE_ECC
+ CAstreamLen += sizeof(ECCAS);
+# endif
+ CAstream = psMalloc(NULL, CAstreamLen);
- CAstreamLen = 0;
-#ifdef USE_RSA
- memcpy(CAstream, RSACAS, sizeof(RSACAS));
- CAstreamLen += sizeof(RSACAS);
-#ifdef USE_ECC
- memcpy(CAstream + CAstreamLen, ECDHRSACAS, sizeof(ECDHRSACAS));
- CAstreamLen += sizeof(ECDHRSACAS);
-#endif
-#endif
-#ifdef USE_ECC
- memcpy(CAstream + CAstreamLen, ECCAS, sizeof(ECCAS));
- CAstreamLen += sizeof(ECCAS);
-#endif
+ CAstreamLen = 0;
+# ifdef USE_RSA
+ memcpy(CAstream, RSACAS, sizeof(RSACAS));
+ CAstreamLen += sizeof(RSACAS);
+# ifdef USE_ECC
+ memcpy(CAstream + CAstreamLen, ECDHRSACAS, sizeof(ECDHRSACAS));
+ CAstreamLen += sizeof(ECDHRSACAS);
+# endif
+# endif
+# ifdef USE_ECC
+ memcpy(CAstream + CAstreamLen, ECCAS, sizeof(ECCAS));
+ CAstreamLen += sizeof(ECCAS);
+# endif
-#ifdef EXAMPLE_RSA_KEYS
- switch (g_rsaKeySize) {
- case 1024:
- certValue = (unsigned char *)RSA1024;
- certLen = sizeof(RSA1024);
- keyValue = (unsigned char *)RSA1024KEY;
- keyLen = sizeof(RSA1024KEY);
- break;
- case 2048:
- certValue = (unsigned char *)RSA2048;
- certLen = sizeof(RSA2048);
- keyValue = (unsigned char *)RSA2048KEY;
- keyLen = sizeof(RSA2048KEY);
- break;
- case 3072:
- certValue = (unsigned char *)RSA3072;
- certLen = sizeof(RSA3072);
- keyValue = (unsigned char *)RSA3072KEY;
- keyLen = sizeof(RSA3072KEY);
- break;
- case 4096:
- certValue = (unsigned char *)RSA4096;
- certLen = sizeof(RSA4096);
- keyValue = (unsigned char *)RSA4096KEY;
- keyLen = sizeof(RSA4096KEY);
- break;
- default:
- _psTraceInt("Invalid RSA key length (%d)\n", g_rsaKeySize);
- goto CLIENT_EXIT;
- }
+# ifdef EXAMPLE_RSA_KEYS
+ switch (g_rsaKeySize)
+ {
+ case 1024:
+ certValue = (unsigned char *) RSA1024;
+ certLen = sizeof(RSA1024);
+ keyValue = (unsigned char *) RSA1024KEY;
+ keyLen = sizeof(RSA1024KEY);
+ break;
+ case 2048:
+ certValue = (unsigned char *) RSA2048;
+ certLen = sizeof(RSA2048);
+ keyValue = (unsigned char *) RSA2048KEY;
+ keyLen = sizeof(RSA2048KEY);
+ break;
+ case 3072:
+ certValue = (unsigned char *) RSA3072;
+ certLen = sizeof(RSA3072);
+ keyValue = (unsigned char *) RSA3072KEY;
+ keyLen = sizeof(RSA3072KEY);
+ break;
+ case 4096:
+ certValue = (unsigned char *) RSA4096;
+ certLen = sizeof(RSA4096);
+ keyValue = (unsigned char *) RSA4096KEY;
+ keyLen = sizeof(RSA4096KEY);
+ break;
+ default:
+ _psTraceInt("Invalid RSA key length (%d)\n", g_rsaKeySize);
+ goto CLIENT_EXIT;
+ }
- if ((rc = matrixSslLoadRsaKeysMem(keys, (const unsigned char *)certValue,
- certLen, (const unsigned char *)keyValue, keyLen, CAstream,
- CAstreamLen)) < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- goto CLIENT_EXIT;
- }
-#endif
+ if ((rc = matrixSslLoadRsaKeysMem(keys, (const unsigned char *) certValue,
+ certLen, (const unsigned char *) keyValue, keyLen, CAstream,
+ CAstreamLen)) < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ goto CLIENT_EXIT;
+ }
+# endif
-#ifdef EXAMPLE_ECDH_RSA_KEYS
- switch (g_ecdhKeySize) {
- case 256:
- certValue = (unsigned char *)ECDHRSA256;
- certLen = sizeof(ECDHRSA256);
- keyValue = (unsigned char *)ECDHRSA256KEY;
- keyLen = sizeof(ECDHRSA256KEY);
- break;
- case 521:
- certValue = (unsigned char *)ECDHRSA521;
- certLen = sizeof(ECDHRSA521);
- keyValue = (unsigned char *)ECDHRSA521KEY;
- keyLen = sizeof(ECDHRSA521KEY);
- break;
- default:
- _psTraceInt("Invalid ECDH_RSA key length (%d)\n", g_ecdhKeySize);
- goto CLIENT_EXIT;
- }
+# ifdef EXAMPLE_ECDH_RSA_KEYS
+ switch (g_ecdhKeySize)
+ {
+ case 256:
+ certValue = (unsigned char *) ECDHRSA256;
+ certLen = sizeof(ECDHRSA256);
+ keyValue = (unsigned char *) ECDHRSA256KEY;
+ keyLen = sizeof(ECDHRSA256KEY);
+ break;
+ case 521:
+ certValue = (unsigned char *) ECDHRSA521;
+ certLen = sizeof(ECDHRSA521);
+ keyValue = (unsigned char *) ECDHRSA521KEY;
+ keyLen = sizeof(ECDHRSA521KEY);
+ break;
+ default:
+ _psTraceInt("Invalid ECDH_RSA key length (%d)\n", g_ecdhKeySize);
+ goto CLIENT_EXIT;
+ }
- if ((rc = matrixSslLoadEcKeysMem(keys, (const unsigned char *)certValue,
- certLen, (const unsigned char *)keyValue, keyLen, CAstream,
- CAstreamLen)) < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- goto CLIENT_EXIT;
- }
-#endif
+ if ((rc = matrixSslLoadEcKeysMem(keys, (const unsigned char *) certValue,
+ certLen, (const unsigned char *) keyValue, keyLen, CAstream,
+ CAstreamLen)) < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ goto CLIENT_EXIT;
+ }
+# endif
-#ifdef EXAMPLE_EC_KEYS
- switch (g_eccKeySize) {
- case 192:
- certValue = (unsigned char *)EC192;
- certLen = sizeof(EC192);
- keyValue = (unsigned char *)EC192KEY;
- keyLen = sizeof(EC192KEY);
- break;
- case 224:
- certValue = (unsigned char *)EC224;
- certLen = sizeof(EC224);
- keyValue = (unsigned char *)EC224KEY;
- keyLen = sizeof(EC224KEY);
- break;
- case 256:
- certValue = (unsigned char *)EC256;
- certLen = sizeof(EC256);
- keyValue = (unsigned char *)EC256KEY;
- keyLen = sizeof(EC256KEY);
- break;
- case 384:
- certValue = (unsigned char *)EC384;
- certLen = sizeof(EC384);
- keyValue = (unsigned char *)EC384KEY;
- keyLen = sizeof(EC384KEY);
- break;
- case 521:
- certValue = (unsigned char *)EC521;
- certLen = sizeof(EC521);
- keyValue = (unsigned char *)EC521KEY;
- keyLen = sizeof(EC521KEY);
- break;
- default:
- _psTraceInt("Invalid ECC key length (%d)\n", g_eccKeySize);
- goto CLIENT_EXIT;
- }
+# ifdef EXAMPLE_EC_KEYS
+ switch (g_eccKeySize)
+ {
+ case 192:
+ certValue = (unsigned char *) EC192;
+ certLen = sizeof(EC192);
+ keyValue = (unsigned char *) EC192KEY;
+ keyLen = sizeof(EC192KEY);
+ break;
+ case 224:
+ certValue = (unsigned char *) EC224;
+ certLen = sizeof(EC224);
+ keyValue = (unsigned char *) EC224KEY;
+ keyLen = sizeof(EC224KEY);
+ break;
+ case 256:
+ certValue = (unsigned char *) EC256;
+ certLen = sizeof(EC256);
+ keyValue = (unsigned char *) EC256KEY;
+ keyLen = sizeof(EC256KEY);
+ break;
+ case 384:
+ certValue = (unsigned char *) EC384;
+ certLen = sizeof(EC384);
+ keyValue = (unsigned char *) EC384KEY;
+ keyLen = sizeof(EC384KEY);
+ break;
+ case 521:
+ certValue = (unsigned char *) EC521;
+ certLen = sizeof(EC521);
+ keyValue = (unsigned char *) EC521KEY;
+ keyLen = sizeof(EC521KEY);
+ break;
+ default:
+ _psTraceInt("Invalid ECC key length (%d)\n", g_eccKeySize);
+ goto CLIENT_EXIT;
+ }
- if ((rc = matrixSslLoadEcKeysMem(keys, certValue, certLen,
- keyValue, keyLen, CAstream, CAstreamLen)) < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- goto CLIENT_EXIT;
- }
-#endif
+ if ((rc = matrixSslLoadEcKeysMem(keys, certValue, certLen,
+ keyValue, keyLen, CAstream, CAstreamLen)) < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ goto CLIENT_EXIT;
+ }
+# endif
-#ifdef REQUIRE_DH_PARAMS
- if (matrixSslLoadDhParamsMem(keys, DHPARAM2048, DHPARAM2048_SIZE) < 0) {
- _psTrace("Unable to load DH parameters\n");
- }
-#endif /* DH_PARAMS */
+# ifdef REQUIRE_DH_PARAMS
+ if (matrixSslLoadDhParamsMem(keys, DHPARAM2048, DHPARAM2048_SIZE) < 0)
+ {
+ _psTrace("Unable to load DH parameters\n");
+ }
+# endif /* DH_PARAMS */
-#else /* USE_HEADER_KEYS */
+# else /* USE_HEADER_KEYS */
/*
- File based keys
- Build the CA list first for potential client auth usage
-*/
- CAstreamLen = 0;
-#ifdef USE_RSA
- if (g_rsaKeySize == 3072) {
- CAstreamLen += (int32)strlen(rsaCA3072File) + 1;
- } else {
- CAstreamLen += (int32)strlen(rsaCAFile) + 1;
- }
- #ifdef USE_ECC
- CAstreamLen += (int32)strlen(ecdhRsaCAFile) + 1;
- #endif
-#endif
-#ifdef USE_ECC
- CAstreamLen += (int32)strlen(ecCAFile) + 1;
-#endif
- CAstream = psMalloc(NULL, CAstreamLen);
- memset(CAstream, 0x0, CAstreamLen);
+ File based keys
+ Build the CA list first for potential client auth usage
+ */
+ CAstreamLen = 0;
+# ifdef USE_RSA
+ if (g_rsaKeySize == 3072)
+ {
+ CAstreamLen += (int32) strlen(rsaCA3072File) + 1;
+ }
+ else
+ {
+ CAstreamLen += (int32) strlen(rsaCAFile) + 1;
+ }
+# ifdef USE_ECC
+ CAstreamLen += (int32) strlen(ecdhRsaCAFile) + 1;
+# endif
+# endif
+# ifdef USE_ECC
+ CAstreamLen += (int32) strlen(ecCAFile) + 1;
+# endif
+ CAstream = psMalloc(NULL, CAstreamLen);
+ memset(CAstream, 0x0, CAstreamLen);
- CAstreamLen = 0;
-#ifdef USE_RSA
- if (g_rsaKeySize == 3072) {
- memcpy(CAstream, rsaCA3072File, strlen(rsaCA3072File));
- CAstreamLen += strlen(rsaCA3072File);
- } else {
- memcpy(CAstream, rsaCAFile, strlen(rsaCAFile));
- CAstreamLen += strlen(rsaCAFile);
- }
-#ifdef USE_ECC
- memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
- memcpy(CAstream + CAstreamLen, ecdhRsaCAFile, strlen(ecdhRsaCAFile));
- CAstreamLen += strlen(ecdhRsaCAFile);
-#endif
-#endif
-#ifdef USE_ECC
- if (CAstreamLen > 0) {
- memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
- }
- memcpy(CAstream + CAstreamLen, ecCAFile, strlen(ecCAFile));
-#endif
+ CAstreamLen = 0;
+# ifdef USE_RSA
+ if (g_rsaKeySize == 3072)
+ {
+ memcpy(CAstream, rsaCA3072File, strlen(rsaCA3072File));
+ CAstreamLen += strlen(rsaCA3072File);
+ }
+ else
+ {
+ memcpy(CAstream, rsaCAFile, strlen(rsaCAFile));
+ CAstreamLen += strlen(rsaCAFile);
+ }
+# ifdef USE_ECC
+ memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
+ memcpy(CAstream + CAstreamLen, ecdhRsaCAFile, strlen(ecdhRsaCAFile));
+ CAstreamLen += strlen(ecdhRsaCAFile);
+# endif
+# endif
+# ifdef USE_ECC
+ if (CAstreamLen > 0)
+ {
+ memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
+ }
+ memcpy(CAstream + CAstreamLen, ecCAFile, strlen(ecCAFile));
+# endif
/* Load Identiy */
-#ifdef EXAMPLE_RSA_KEYS
- if ((rc = matrixSslLoadRsaKeys(keys, rsaCertFile, rsaPrivkeyFile, NULL,
- (char*)CAstream)) < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- goto CLIENT_EXIT;
- }
-#endif
-
-#ifdef EXAMPLE_ECDH_RSA_KEYS
- if ((rc = matrixSslLoadEcKeys(keys, ecdhRsaCertFile, ecdhRsaPrivkeyFile,
- NULL, (char*)CAstream)) < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- goto CLIENT_EXIT;
- }
-#endif
-
-#ifdef EXAMPLE_EC_KEYS
- if ((rc = matrixSslLoadEcKeys(keys, ecCertFile, ecPrivkeyFile, NULL,
- (char*)CAstream)) < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- goto CLIENT_EXIT;
- }
-#endif
-
-#ifdef REQUIRE_DH_PARAMS
- if (matrixSslLoadDhParams(keys, dhParamFile) < 0) {
- _psTrace("Unable to load DH parameters\n");
- }
-#endif
-
-#endif /* USE_HEADER_KEYS */
-
- psFree(CAstream, NULL);
- CAstream = NULL;
-
-#ifdef USE_PSK_CIPHER_SUITE
- /* The first ID is considered as null-terminiated string for
- compatibility with OpenSSL's s_client default client identity
- "Client_identity" */
-
- matrixSslLoadPsk(keys,
- PSK_HEADER_TABLE[0].key,
- sizeof(PSK_HEADER_TABLE[0].key),
- PSK_HEADER_TABLE[0].id,
- strlen((const char *)PSK_HEADER_TABLE[0].id));
-
- for (rc = 1; rc < PSK_HEADER_TABLE_COUNT; rc++) {
- matrixSslLoadPsk(keys,
- PSK_HEADER_TABLE[rc].key,
- sizeof(PSK_HEADER_TABLE[rc].key),
- PSK_HEADER_TABLE[rc].id,
- sizeof(PSK_HEADER_TABLE[rc].id));
+# ifdef EXAMPLE_RSA_KEYS
+ if ((rc = matrixSslLoadRsaKeys(keys, rsaCertFile, rsaPrivkeyFile, NULL,
+ (char *) CAstream)) < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ goto CLIENT_EXIT;
}
-#endif /* PSK */
+# endif
- recvfromBufLen = matrixDtlsGetPmtu();
- if ((recvfromBuf = psMalloc(MATRIX_NO_POOL, recvfromBufLen)) == NULL) {
- rc = PS_MEM_FAIL;
- _psTrace("Init error allocating receive buffer\n");
- goto CLIENT_EXIT;
- }
+# ifdef EXAMPLE_ECDH_RSA_KEYS
+ if ((rc = matrixSslLoadEcKeys(keys, ecdhRsaCertFile, ecdhRsaPrivkeyFile,
+ NULL, (char *) CAstream)) < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ goto CLIENT_EXIT;
+ }
+# endif
- if ((sock = newUdpSocket(NULL, g_port, &err)) == INVALID_SOCKET) {
- _psTrace("Error creating UDP socket\n");
- goto DTLS_EXIT;
- }
- _psTraceInt("DTLS server running on port %d\n", g_port);
+# ifdef EXAMPLE_EC_KEYS
+ if ((rc = matrixSslLoadEcKeys(keys, ecCertFile, ecPrivkeyFile, NULL,
+ (char *) CAstream)) < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ goto CLIENT_EXIT;
+ }
+# endif
- /* Server loop */
- for (exitFlag = 0; exitFlag == 0;) {
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
- FD_ZERO(&readfd);
- FD_SET(sock, &readfd);
+# ifdef REQUIRE_DH_PARAMS
+ if (matrixSslLoadDhParams(keys, dhParamFile) < 0)
+ {
+ _psTrace("Unable to load DH parameters\n");
+ }
+# endif
+
+# endif /* USE_HEADER_KEYS */
+
+ psFree(CAstream, NULL);
+ CAstream = NULL;
+
+# ifdef USE_PSK_CIPHER_SUITE
+ /* The first ID is considered as null-terminiated string for
+ compatibility with OpenSSL's s_client default client identity
+ "Client_identity" */
+
+ matrixSslLoadPsk(keys,
+ PSK_HEADER_TABLE[0].key,
+ sizeof(PSK_HEADER_TABLE[0].key),
+ PSK_HEADER_TABLE[0].id,
+ strlen((const char *) PSK_HEADER_TABLE[0].id));
+
+ for (rc = 1; rc < PSK_HEADER_TABLE_COUNT; rc++)
+ {
+ matrixSslLoadPsk(keys,
+ PSK_HEADER_TABLE[rc].key,
+ sizeof(PSK_HEADER_TABLE[rc].key),
+ PSK_HEADER_TABLE[rc].id,
+ sizeof(PSK_HEADER_TABLE[rc].id));
+ }
+# endif /* PSK */
+
+ recvfromBufLen = matrixDtlsGetPmtu();
+ if ((recvfromBuf = psMalloc(MATRIX_NO_POOL, recvfromBufLen)) == NULL)
+ {
+ rc = PS_MEM_FAIL;
+ _psTrace("Init error allocating receive buffer\n");
+ goto CLIENT_EXIT;
+ }
+
+ if ((sock = newUdpSocket(NULL, g_port, &err)) == INVALID_SOCKET)
+ {
+ _psTrace("Error creating UDP socket\n");
+ goto DTLS_EXIT;
+ }
+ _psTraceInt("DTLS server running on port %d\n", g_port);
+
+ /* Server loop */
+ for (exitFlag = 0; exitFlag == 0; )
+ {
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+ FD_ZERO(&readfd);
+ FD_SET(sock, &readfd);
/*
- Always just wait a second for any incoming data. The primary loop
- mechanism reads data from one source and replies with handshake data
- if needed (that reply may be a resend if reading a repeat message).
- Individual client timeouts are then handled
-*/
- val = select(sock+1, &readfd, NULL, NULL, &timeout);
+ Always just wait a second for any incoming data. The primary loop
+ mechanism reads data from one source and replies with handshake data
+ if needed (that reply may be a resend if reading a repeat message).
+ Individual client timeouts are then handled
+ */
+ val = select(sock + 1, &readfd, NULL, NULL, &timeout);
- if (val > 0 && FD_ISSET(sock, &readfd)) {
- psTraceIntDtls("Select woke %d\n", val);
- /* recvfrom data must always go into generic buffer becuase we
- don't yet know who it is from */
- inaddrlen = sizeof(struct sockaddr_in);
- if ((recvLen = (int32)recvfrom(sock, recvfromBuf, recvfromBufLen, 0,
- (struct sockaddr *)&inaddr, &inaddrlen)) < 0) {
-#ifdef WIN32
- if (SOCKET_ERRNO != EWOULDBLOCK &&
- SOCKET_ERRNO != WSAECONNRESET) {
-#else
- if (SOCKET_ERRNO != EWOULDBLOCK) {
-#endif
- _psTraceInt("recvfrom error %d. Exiting\n", SOCKET_ERRNO);
- goto DTLS_EXIT;
- }
- continue;
- }
-#ifdef USE_DTLS_DEBUG_TRACE
- /* nice for debugging */
- {
- const char *addrstr;
- addrstr = getaddrstring((struct sockaddr *)&inaddr, 1);
- psTraceIntDtls("Read %d bytes ", recvLen);
- psTraceStrDtls("from %s\n", (char*)addrstr);
- psFree(addrstr, NULL);
- }
-#endif
+ if (val > 0 && FD_ISSET(sock, &readfd))
+ {
+ psTraceIntDtls("Select woke %d\n", val);
+ /* recvfrom data must always go into generic buffer becuase we
+ don't yet know who it is from */
+ inaddrlen = sizeof(struct sockaddr_in);
+ if ((recvLen = (int32) recvfrom(sock, recvfromBuf, recvfromBufLen, 0,
+ (struct sockaddr *) &inaddr, &inaddrlen)) < 0)
+ {
+# ifdef WIN32
+ if (SOCKET_ERRNO != EWOULDBLOCK &&
+ SOCKET_ERRNO != WSAECONNRESET)
+ {
+# else
+ if (SOCKET_ERRNO != EWOULDBLOCK)
+ {
+# endif
+ _psTraceInt("recvfrom error %d. Exiting\n", SOCKET_ERRNO);
+ goto DTLS_EXIT;
+ }
+ continue;
+ }
+# ifdef USE_DTLS_DEBUG_TRACE
+ /* nice for debugging */
+ {
+ const char *addrstr;
+ addrstr = getaddrstring((struct sockaddr *) &inaddr, 1);
+ psTraceIntDtls("Read %d bytes ", recvLen);
+ psTraceStrDtls("from %s\n", (char *) addrstr);
+ psFree(addrstr, NULL);
+ }
+# endif
- /* Locate the SSL context of this receive and create a new session
- if not found */
- if ((dtlsCtx = findClient(inaddr)) == NULL) {
- memset(&options, 0x0, sizeof(sslSessOpts_t));
- options.versionFlag = SSL_FLAGS_DTLS;
- options.truncHmac = -1;
+ /* Locate the SSL context of this receive and create a new session
+ if not found */
+ if ((dtlsCtx = findClient(inaddr)) == NULL)
+ {
+ memset(&options, 0x0, sizeof(sslSessOpts_t));
+ options.versionFlag = SSL_FLAGS_DTLS;
+ options.truncHmac = -1;
- if (matrixSslNewServerSession(&ssl, keys,
- certValidator, &options) < 0) {
- rc = DTLS_FATAL; goto DTLS_EXIT;
- }
- if ((dtlsCtx = registerClient(inaddr, sock, ssl)) == NULL) {
- /* Client list is full. Just have to ignore */
- matrixSslDeleteSession(ssl);
- continue;
- }
- }
+ if (matrixSslNewServerSession(&ssl, keys,
+ certValidator, &options) < 0)
+ {
+ rc = DTLS_FATAL; goto DTLS_EXIT;
+ }
+ if ((dtlsCtx = registerClient(inaddr, sock, ssl)) == NULL)
+ {
+ /* Client list is full. Just have to ignore */
+ matrixSslDeleteSession(ssl);
+ continue;
+ }
+ }
- ssl = dtlsCtx->ssl;
- /* Move socket data into internal buffer */
- freeBufLen = matrixSslGetReadbuf(ssl, &sslBuf);
- psAssert(freeBufLen >= recvLen);
- psAssert(freeBufLen == matrixDtlsGetPmtu());
- memcpy(sslBuf, recvfromBuf, recvLen);
+ ssl = dtlsCtx->ssl;
+ /* Move socket data into internal buffer */
+ freeBufLen = matrixSslGetReadbuf(ssl, &sslBuf);
+ psAssert(freeBufLen >= recvLen);
+ psAssert(freeBufLen == matrixDtlsGetPmtu());
+ memcpy(sslBuf, recvfromBuf, recvLen);
- /* Notify SSL state machine that we've received more data into the
- ssl buffer retreived with matrixSslGetReadbuf. */
- if ((rcr = matrixSslReceivedData(ssl, recvLen, &sslBuf,
- (uint32*)&freeBufLen)) < 0) {
- clearClient(dtlsCtx);
- continue; /* Next connection */
- }
- /* Update last activity time and reset timeout*/
- psGetTime(&dtlsCtx->lastRecvTime, NULL);
- dtlsCtx->timeout = MIN_WAIT_SECS;
+ /* Notify SSL state machine that we've received more data into the
+ ssl buffer retreived with matrixSslGetReadbuf. */
+ if ((rcr = matrixSslReceivedData(ssl, recvLen, &sslBuf,
+ (uint32 *) &freeBufLen)) < 0)
+ {
+ clearClient(dtlsCtx);
+ continue; /* Next connection */
+ }
+ /* Update last activity time and reset timeout*/
+ psGetTime(&dtlsCtx->lastRecvTime, NULL);
+ dtlsCtx->timeout = MIN_WAIT_SECS;
PROCESS_MORE_FROM_BUFFER:
- /* Process any incoming plaintext application data */
- switch (rcr) {
- case MATRIXSSL_HANDSHAKE_COMPLETE:
- /* This is a resumed handshake case which means we are
- the last to receive handshake flights and we know the
- handshake is complete. However, the internal workings
- will not flag us officially complete until we receive
- application data from the peer so we need a local flag
- to handle this case so we are not resending our final
- flight */
- dtlsCtx->connStatus = RESUMED_HANDSHAKE_COMPLETE;
- psTraceDtls("Got HANDSHAKE_COMPLETE out of ReceivedData\n");
- break;
- case MATRIXSSL_APP_DATA:
- /* Now safe to clear the connStatus flag that was keeping
- track of the state between receiving the final flight of
- a resumed handshake and receiving application data. The
- reciept of app data has now internally disabled flight
- resends */
- dtlsCtx->connStatus = 0;
- _psTrace("Client connected. Received...\n");
- _psTraceStr("%s\n", (char*)sslBuf);
- break;
- case MATRIXSSL_REQUEST_SEND:
- /* Still handshaking with this particular client */
- while ((sslBufLen = matrixDtlsGetOutdata(ssl,
- &sslBuf)) > 0) {
- if ((sendLen = udpSend(dtlsCtx->fd, sslBuf, sslBufLen,
- (struct sockaddr*)&inaddr,
- sizeof(struct sockaddr_in),
- dtlsCtx->timeout,
- packet_loss_prob,
- NULL)) < 0) {
- psTraceDtls("udpSend error. Ignoring\n");
- }
- /* Always indicate the entire datagram was sent as
- there is no way for DTLS to handle partial records.
- Resends and timeouts will handle any problems */
- rcs = matrixDtlsSentData(ssl, sslBufLen);
+ /* Process any incoming plaintext application data */
+ switch (rcr)
+ {
+ case MATRIXSSL_HANDSHAKE_COMPLETE:
+ /* This is a resumed handshake case which means we are
+ the last to receive handshake flights and we know the
+ handshake is complete. However, the internal workings
+ will not flag us officially complete until we receive
+ application data from the peer so we need a local flag
+ to handle this case so we are not resending our final
+ flight */
+ dtlsCtx->connStatus = RESUMED_HANDSHAKE_COMPLETE;
+ psTraceDtls("Got HANDSHAKE_COMPLETE out of ReceivedData\n");
+ break;
+ case MATRIXSSL_APP_DATA:
+ /* Now safe to clear the connStatus flag that was keeping
+ track of the state between receiving the final flight of
+ a resumed handshake and receiving application data. The
+ reciept of app data has now internally disabled flight
+ resends */
+ dtlsCtx->connStatus = 0;
+ _psTrace("Client connected. Received...\n");
+ _psTraceStr("%s\n", (char *) sslBuf);
+ break;
+ case MATRIXSSL_REQUEST_SEND:
+ /* Still handshaking with this particular client */
+ while ((sslBufLen = matrixDtlsGetOutdata(ssl,
+ &sslBuf)) > 0)
+ {
+ if ((sendLen = udpSend(dtlsCtx->fd, sslBuf, sslBufLen,
+ (struct sockaddr *) &inaddr,
+ sizeof(struct sockaddr_in),
+ dtlsCtx->timeout,
+ packet_loss_prob,
+ NULL)) < 0)
+ {
+ psTraceDtls("udpSend error. Ignoring\n");
+ }
+ /* Always indicate the entire datagram was sent as
+ there is no way for DTLS to handle partial records.
+ Resends and timeouts will handle any problems */
+ rcs = matrixDtlsSentData(ssl, sslBufLen);
- if (rcs == MATRIXSSL_REQUEST_CLOSE) {
- psTraceDtls("Got REQUEST_CLOSE out of SentData\n");
- clearClient(dtlsCtx);
- break;
- }
- if (rcs == MATRIXSSL_HANDSHAKE_COMPLETE) {
- /* This is the standard handshake case */
- _psTrace("Got HANDSHAKE_COMPLETE from SentData\n");
- break;
- }
- /* SSL_REQUEST_SEND is handled by loop logic */
- }
- break;
- case MATRIXSSL_REQUEST_RECV:
- psTraceDtls("Got REQUEST_RECV from ReceivedData\n");
- break;
- case MATRIXSSL_RECEIVED_ALERT:
- /* The first byte of the buffer is the level */
- /* The second byte is the description */
- if (*sslBuf == SSL_ALERT_LEVEL_FATAL) {
- psTraceIntDtls("Fatal alert: %d, closing connection.\n",
- *(sslBuf + 1));
- clearClient(dtlsCtx);
- continue; /* Next connection */
- }
- /* Closure alert is normal (and best) way to close */
- if (*(sslBuf + 1) == SSL_ALERT_CLOSE_NOTIFY) {
- clearClient(dtlsCtx);
- continue; /* Next connection */
- }
- psTraceIntDtls("Warning alert: %d\n", *(sslBuf + 1));
- if ((rcr = matrixSslProcessedData(ssl, &sslBuf,
- (uint32*)&freeBufLen)) == 0) {
- continue;
- }
- goto PROCESS_MORE_FROM_BUFFER;
+ if (rcs == MATRIXSSL_REQUEST_CLOSE)
+ {
+ psTraceDtls("Got REQUEST_CLOSE out of SentData\n");
+ clearClient(dtlsCtx);
+ break;
+ }
+ if (rcs == MATRIXSSL_HANDSHAKE_COMPLETE)
+ {
+ /* This is the standard handshake case */
+ _psTrace("Got HANDSHAKE_COMPLETE from SentData\n");
+ break;
+ }
+ /* SSL_REQUEST_SEND is handled by loop logic */
+ }
+ break;
+ case MATRIXSSL_REQUEST_RECV:
+ psTraceDtls("Got REQUEST_RECV from ReceivedData\n");
+ break;
+ case MATRIXSSL_RECEIVED_ALERT:
+ /* The first byte of the buffer is the level */
+ /* The second byte is the description */
+ if (*sslBuf == SSL_ALERT_LEVEL_FATAL)
+ {
+ psTraceIntDtls("Fatal alert: %d, closing connection.\n",
+ *(sslBuf + 1));
+ clearClient(dtlsCtx);
+ continue; /* Next connection */
+ }
+ /* Closure alert is normal (and best) way to close */
+ if (*(sslBuf + 1) == SSL_ALERT_CLOSE_NOTIFY)
+ {
+ clearClient(dtlsCtx);
+ continue; /* Next connection */
+ }
+ psTraceIntDtls("Warning alert: %d\n", *(sslBuf + 1));
+ if ((rcr = matrixSslProcessedData(ssl, &sslBuf,
+ (uint32 *) &freeBufLen)) == 0)
+ {
+ continue;
+ }
+ goto PROCESS_MORE_FROM_BUFFER;
- default:
- continue; /* Next connection */
- }
- } else if (val < 0) {
- if (SOCKET_ERRNO != EINTR) {
- psTraceIntDtls("unhandled error %d from select", SOCKET_ERRNO);
- }
- }
+ default:
+ continue; /* Next connection */
+ }
+ }
+ else if (val < 0)
+ {
+ if (SOCKET_ERRNO != EINTR)
+ {
+ psTraceIntDtls("unhandled error %d from select", SOCKET_ERRNO);
+ }
+ }
/*
- Have either timed out waiting for a read or have processed a single
- recv. Now check to see if any timeout resends are required
-*/
- rc = handleResends(sock);
- } /* Main Select Loop */
+ Have either timed out waiting for a read or have processed a single
+ recv. Now check to see if any timeout resends are required
+ */
+ rc = handleResends(sock);
+ } /* Main Select Loop */
DTLS_EXIT:
- psFree(recvfromBuf, NULL);
+ psFree(recvfromBuf, NULL);
CLIENT_EXIT:
- if (CAstream) {
- psFree(CAstream, NULL);
- }
- closeClientList();
+ if (CAstream)
+ {
+ psFree(CAstream, NULL);
+ }
+ closeClientList();
MATRIX_EXIT:
- matrixSslDeleteKeys(keys);
- matrixSslClose();
- if (sock != INVALID_SOCKET) close(sock);
- return rc;
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ if (sock != INVALID_SOCKET)
+ {
+ close(sock);
+ }
+ return rc;
}
/******************************************************************************/
/*
- Work through client list and resend handshake flight if haven't heard
- from them in a while
-*/
+ Work through client list and resend handshake flight if haven't heard
+ from them in a while
+ */
static int32 handleResends(SOCKET sock)
{
- serverDtls_t *dtlsCtx;
- ssl_t *ssl;
- psTime_t now;
- unsigned char *sslBuf;
- int16_t i;
- int32_t sendLen, sslBufLen, rc;
- uint32_t timeout, clientCount;
+ serverDtls_t *dtlsCtx;
+ ssl_t *ssl;
+ psTime_t now;
+ unsigned char *sslBuf;
+ int16_t i;
+ int32_t sendLen, sslBufLen, rc;
+ uint32_t timeout, clientCount;
- clientCount = 0; /* return code is number of active clients or < 0 on error */
- psGetTime(&now, NULL);
- for (i = 0; i < tableSize; i++) {
- dtlsCtx = &clientTable[i];
- if (dtlsCtx->ssl != NULL) {
- clientCount++;
- timeout = psDiffMsecs(dtlsCtx->lastRecvTime, now, NULL) / 1000;
- /* Haven't heard from this client in a while. Might need resend */
- if (timeout > dtlsCtx->timeout) {
- /* if timeout is too great. clear conn */
- if (dtlsCtx->timeout >= MAX_WAIT_SECS) {
- clearClient(dtlsCtx);
- clientCount--;
- break;
- }
- /* Increase the timeout for next pass */
- dtlsCtx->timeout *= 2;
+ clientCount = 0; /* return code is number of active clients or < 0 on error */
+ psGetTime(&now, NULL);
+ for (i = 0; i < tableSize; i++)
+ {
+ dtlsCtx = &clientTable[i];
+ if (dtlsCtx->ssl != NULL)
+ {
+ clientCount++;
+ timeout = psDiffMsecs(dtlsCtx->lastRecvTime, now, NULL) / 1000;
+ /* Haven't heard from this client in a while. Might need resend */
+ if (timeout > dtlsCtx->timeout)
+ {
+ /* if timeout is too great. clear conn */
+ if (dtlsCtx->timeout >= MAX_WAIT_SECS)
+ {
+ clearClient(dtlsCtx);
+ clientCount--;
+ break;
+ }
+ /* Increase the timeout for next pass */
+ dtlsCtx->timeout *= 2;
- /* If we are in a RESUMED_HANDSHAKE_COMPLETE state that means
- we are positive the handshake is complete so we don't want to
- resend no matter what. This is an interim state before the
- internal mechaism sees an application data record and flags
- us as complete officially */
- if (dtlsCtx->connStatus == RESUMED_HANDSHAKE_COMPLETE) {
- psTraceDtls("Connected but awaiting data\n");
- continue;
- }
- ssl = dtlsCtx->ssl;
- while ((sslBufLen = matrixDtlsGetOutdata(ssl,
- &sslBuf)) > 0) {
- if ((sendLen = udpSend(dtlsCtx->fd, sslBuf, sslBufLen,
- (struct sockaddr*)&dtlsCtx->addr,
- sizeof(struct sockaddr_in),
- dtlsCtx->timeout / 2,
- packet_loss_prob,
- NULL)) < 0) {
- psTraceDtls("udpSend error. Ignoring\n");
- }
- /* Always indicate the entire datagram was sent as
- there is no way for DTLS to handle partial records.
- Resends and timeouts will handle any problems */
- if ((rc = matrixDtlsSentData(ssl, sslBufLen)) < 0) {
- psTraceDtls("internal error\n");
- clearClient(dtlsCtx);
- clientCount--;
- break;
- }
- if (rc == MATRIXSSL_REQUEST_CLOSE) {
- psTraceDtls("Got REQUEST_CLOSE out of SentData\n");
- clearClient(dtlsCtx);
- clientCount--;
- break;
- }
- if (rc == MATRIXSSL_HANDSHAKE_COMPLETE) {
- /* This is the standard handshake case */
- psTraceDtls("Got HANDSHAKE_COMPLETE out of SentData\n");
- break;
- }
- /* SSL_REQUEST_SEND is handled by loop logic */
- }
+ /* If we are in a RESUMED_HANDSHAKE_COMPLETE state that means
+ we are positive the handshake is complete so we don't want to
+ resend no matter what. This is an interim state before the
+ internal mechaism sees an application data record and flags
+ us as complete officially */
+ if (dtlsCtx->connStatus == RESUMED_HANDSHAKE_COMPLETE)
+ {
+ psTraceDtls("Connected but awaiting data\n");
+ continue;
+ }
+ ssl = dtlsCtx->ssl;
+ while ((sslBufLen = matrixDtlsGetOutdata(ssl,
+ &sslBuf)) > 0)
+ {
+ if ((sendLen = udpSend(dtlsCtx->fd, sslBuf, sslBufLen,
+ (struct sockaddr *) &dtlsCtx->addr,
+ sizeof(struct sockaddr_in),
+ dtlsCtx->timeout / 2,
+ packet_loss_prob,
+ NULL)) < 0)
+ {
+ psTraceDtls("udpSend error. Ignoring\n");
+ }
+ /* Always indicate the entire datagram was sent as
+ there is no way for DTLS to handle partial records.
+ Resends and timeouts will handle any problems */
+ if ((rc = matrixDtlsSentData(ssl, sslBufLen)) < 0)
+ {
+ psTraceDtls("internal error\n");
+ clearClient(dtlsCtx);
+ clientCount--;
+ break;
+ }
+ if (rc == MATRIXSSL_REQUEST_CLOSE)
+ {
+ psTraceDtls("Got REQUEST_CLOSE out of SentData\n");
+ clearClient(dtlsCtx);
+ clientCount--;
+ break;
+ }
+ if (rc == MATRIXSSL_HANDSHAKE_COMPLETE)
+ {
+ /* This is the standard handshake case */
+ psTraceDtls("Got HANDSHAKE_COMPLETE out of SentData\n");
+ break;
+ }
+ /* SSL_REQUEST_SEND is handled by loop logic */
+ }
- }
- }
- }
- return clientCount;
+ }
+ }
+ }
+ return clientCount;
}
/******************************************************************************/
/*
- Make sure the socket is not inherited by exec'd processes
- Set the REUSE flag to minimize the number of sockets in TIME_WAIT
- Then we set REUSEADDR, NODELAY and NONBLOCK on the socket
-*/
+ Make sure the socket is not inherited by exec'd processes
+ Set the REUSE flag to minimize the number of sockets in TIME_WAIT
+ Then we set REUSEADDR, NODELAY and NONBLOCK on the socket
+ */
static int32_t setSocketOptions(SOCKET fd)
{
- int32 rc;
+ int32 rc;
-#ifdef POSIX
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
- return PS_PLATFORM_FAIL;
- }
-#endif
- rc = 1;
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&rc, sizeof(rc)) < 0) {
- return PS_PLATFORM_FAIL;
- }
- return PS_SUCCESS;
+# ifdef POSIX
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
+ {
+ return PS_PLATFORM_FAIL;
+ }
+# endif
+ rc = 1;
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &rc, sizeof(rc)) < 0)
+ {
+ return PS_PLATFORM_FAIL;
+ }
+ return PS_SUCCESS;
}
static SOCKET newUdpSocket(char *ip, short port, int *err)
{
- struct sockaddr_in addr = { 0 };
- SOCKET fd;
+ struct sockaddr_in addr = { 0 };
+ SOCKET fd;
- if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
- _psTraceInt("Error creating socket %d\n", SOCKET_ERRNO);
- *err = SOCKET_ERRNO;
- return INVALID_SOCKET;
- }
+ if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+ {
+ _psTraceInt("Error creating socket %d\n", SOCKET_ERRNO);
+ *err = SOCKET_ERRNO;
+ return INVALID_SOCKET;
+ }
- if (setSocketOptions(fd) < 0) {
- *err = SOCKET_ERRNO;
- close(fd);
- return INVALID_SOCKET;
- }
+ if (setSocketOptions(fd) < 0)
+ {
+ *err = SOCKET_ERRNO;
+ close(fd);
+ return INVALID_SOCKET;
+ }
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- if (ip == NULL) {
- addr.sin_addr.s_addr = INADDR_ANY;
- if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- _psTrace("Can't bind socket. Port in use or permission problem\n");
- *err = SOCKET_ERRNO;
- close(fd);
- return INVALID_SOCKET;
- }
- }
- return fd;
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ if (ip == NULL)
+ {
+ addr.sin_addr.s_addr = INADDR_ANY;
+ if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
+ {
+ _psTrace("Can't bind socket. Port in use or permission problem\n");
+ *err = SOCKET_ERRNO;
+ close(fd);
+ return INVALID_SOCKET;
+ }
+ }
+ return fd;
}
/* catch any segvs */
static void sigsegv_handler(int arg)
{
- _psTrace("Aiee, segfault! You should probably report "
- "this as a bug to the developer\n");
- exit(EXIT_FAILURE);
+ _psTrace("Aiee, segfault! You should probably report "
+ "this as a bug to the developer\n");
+ exit(EXIT_FAILURE);
}
/* catch ctrl-c or sigterm */
static void sigintterm_handler(int arg)
{
- exitFlag = 1; /* Rudimentary exit flagging */
+ exitFlag = 1; /* Rudimentary exit flagging */
}
static int sigsetup(void)
{
- /* set up cleanup handler */
- if (signal(SIGINT, sigintterm_handler) == SIG_ERR ||
-#ifndef DEBUG_VALGRIND
- signal(SIGTERM, sigintterm_handler) == SIG_ERR ||
-#endif
- signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
- return -1;
- }
- if (signal(SIGSEGV, sigsegv_handler) == SIG_ERR) {
- return -1;
- }
+ /* set up cleanup handler */
+ if (signal(SIGINT, sigintterm_handler) == SIG_ERR ||
+# ifndef DEBUG_VALGRIND
+ signal(SIGTERM, sigintterm_handler) == SIG_ERR ||
+# endif
+ signal(SIGPIPE, SIG_IGN) == SIG_ERR)
+ {
+ return -1;
+ }
+ if (signal(SIGSEGV, sigsegv_handler) == SIG_ERR)
+ {
+ return -1;
+ }
- return 0;
+ return 0;
}
-#ifdef USE_DTLS_DEBUG_TRACE
+# ifdef USE_DTLS_DEBUG_TRACE
/******************************************************************************/
/* Return a string representation of the socket address passed. The return
* value is allocated with malloc() */
-static unsigned char * getaddrstring(struct sockaddr *addr,
- int withport) {
+static unsigned char *getaddrstring(struct sockaddr *addr,
+ int withport)
+{
- char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
- char *retstring = NULL;
- int ret;
- unsigned int len;
+ char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
+ char *retstring = NULL;
+ int ret;
+ unsigned int len;
- len = sizeof(struct sockaddr_storage);
- /* Some platforms such as Solaris 8 require that len is the length
- * of the specific structure. Some older linux systems (glibc 2.1.3
- * such as debian potato) have sockaddr_storage.__ss_family instead
- * but we'll ignore them */
-#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
- if (addr->ss_family == AF_INET) {
- len = sizeof(struct sockaddr_in);
- }
-#ifdef AF_INET6
- if (addr->ss_family == AF_INET6) {
- len = sizeof(struct sockaddr_in6);
- }
-#endif
-#endif
+ len = sizeof(struct sockaddr_storage);
+ /* Some platforms such as Solaris 8 require that len is the length
+ * of the specific structure. Some older linux systems (glibc 2.1.3
+ * such as debian potato) have sockaddr_storage.__ss_family instead
+ * but we'll ignore them */
+# ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
+ if (addr->ss_family == AF_INET)
+ {
+ len = sizeof(struct sockaddr_in);
+ }
+# ifdef AF_INET6
+ if (addr->ss_family == AF_INET6)
+ {
+ len = sizeof(struct sockaddr_in6);
+ }
+# endif
+# endif
- ret = getnameinfo((struct sockaddr*)addr, len, hbuf, sizeof(hbuf),
- sbuf, sizeof(sbuf), NI_NUMERICSERV | NI_NUMERICHOST);
+ ret = getnameinfo((struct sockaddr *) addr, len, hbuf, sizeof(hbuf),
+ sbuf, sizeof(sbuf), NI_NUMERICSERV | NI_NUMERICHOST);
- if (ret != 0) {
- /* This is a fairly bad failure - it'll fallback to IP if it
- * just can't resolve */
- _psTrace("failed lookup for getaddrstring");
- strcpy(hbuf, "UNKNOWN");
- strcpy(sbuf, "?");
- }
+ if (ret != 0)
+ {
+ /* This is a fairly bad failure - it'll fallback to IP if it
+ * just can't resolve */
+ _psTrace("failed lookup for getaddrstring");
+ strcpy(hbuf, "UNKNOWN");
+ strcpy(sbuf, "?");
+ }
- if (withport) {
- len = strlen(hbuf) + 2 + strlen(sbuf);
- retstring = (char*)psMalloc(MATRIX_NO_POOL, len);
- snprintf(retstring, len, "%s:%s", hbuf, sbuf);
- } else {
- retstring = strdup(hbuf);
- }
+ if (withport)
+ {
+ len = strlen(hbuf) + 2 + strlen(sbuf);
+ retstring = (char *) psMalloc(MATRIX_NO_POOL, len);
+ snprintf(retstring, len, "%s:%s", hbuf, sbuf);
+ }
+ else
+ {
+ retstring = strdup(hbuf);
+ }
- return (unsigned char *)retstring;
+ return (unsigned char *) retstring;
}
-#endif /* USE_DTLS_DEBUG_TRACE */
+# endif /* USE_DTLS_DEBUG_TRACE */
/******************************************************************************/
/*
- Client management
-*/
+ Client management
+ */
/******************************************************************************/
static int32 initClientList(uint16 maxPeers)
{
- clientTable = psCalloc(NULL, maxPeers, sizeof(serverDtls_t));
- if (clientTable == NULL) {
- return PS_MEM_FAIL;
- }
- tableSize = maxPeers;
+ clientTable = psCalloc(NULL, maxPeers, sizeof(serverDtls_t));
+ if (clientTable == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ tableSize = maxPeers;
- udpInitProxy();
- return PS_SUCCESS;
+ udpInitProxy();
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- Associates a new sockaddr with an existing ssl context and returns context
+ Associates a new sockaddr with an existing ssl context and returns context
*/
serverDtls_t *registerClient(struct sockaddr_in addr, SOCKET sock,
- ssl_t *ssl)
+ ssl_t *ssl)
{
- int16 i;
- serverDtls_t *dtlsCtx;
+ int16 i;
+ serverDtls_t *dtlsCtx;
- for (i = 0; i < tableSize && clientTable[i].ssl != NULL &&
- (clientTable[i].addr.sin_addr.s_addr != addr.sin_addr.s_addr ||
- clientTable[i].addr.sin_port != addr.sin_port); i++);
- if (i >= tableSize) {
- /* no available slots */
- return NULL;
- }
+ for (i = 0; i < tableSize && clientTable[i].ssl != NULL &&
+ (clientTable[i].addr.sin_addr.s_addr != addr.sin_addr.s_addr ||
+ clientTable[i].addr.sin_port != addr.sin_port); i++)
+ {
+ ;
+ }
+ if (i >= tableSize)
+ {
+ /* no available slots */
+ return NULL;
+ }
- dtlsCtx = &clientTable[i];
+ dtlsCtx = &clientTable[i];
- dtlsCtx->addr = addr;
- dtlsCtx->fd = sock;
- dtlsCtx->timeout = MIN_WAIT_SECS;
- dtlsCtx->connStatus = 0;
- psGetTime(&dtlsCtx->lastRecvTime, NULL);
- dtlsCtx->ssl = ssl;
- return dtlsCtx;
+ dtlsCtx->addr = addr;
+ dtlsCtx->fd = sock;
+ dtlsCtx->timeout = MIN_WAIT_SECS;
+ dtlsCtx->connStatus = 0;
+ psGetTime(&dtlsCtx->lastRecvTime, NULL);
+ dtlsCtx->ssl = ssl;
+ return dtlsCtx;
}
static void clearClient(serverDtls_t *dtls)
{
- ssl_t *ssl;
- unsigned char *buf;
- int32 len;
+ ssl_t *ssl;
+ unsigned char *buf;
+ int32 len;
- ssl = dtls->ssl;
+ ssl = dtls->ssl;
- /* Quick attempt to send a closure alert, don't worry about failure */
- if (matrixSslEncodeClosureAlert(ssl) >= 0) {
- if ((len = matrixDtlsGetOutdata(ssl, &buf)) > 0) {
- if (sendto(dtls->fd, buf, len, 0, (struct sockaddr*)&dtls->addr,
- sizeof(struct sockaddr_in)) >= 0) {
- matrixDtlsSentData(ssl, len);
- }
- }
- }
- matrixSslDeleteSession(ssl);
+ /* Quick attempt to send a closure alert, don't worry about failure */
+ if (matrixSslEncodeClosureAlert(ssl) >= 0)
+ {
+ if ((len = matrixDtlsGetOutdata(ssl, &buf)) > 0)
+ {
+ if (sendto(dtls->fd, buf, len, 0, (struct sockaddr *) &dtls->addr,
+ sizeof(struct sockaddr_in)) >= 0)
+ {
+ matrixDtlsSentData(ssl, len);
+ }
+ }
+ }
+ matrixSslDeleteSession(ssl);
/*
- Free up the entry in the client table
-*/
- dtls->ssl = NULL;
- dtls->connStatus = 0;
- dtls->fd = 0;
- memset(&dtls->addr, 0x0, sizeof(struct sockaddr_in));
- return;
+ Free up the entry in the client table
+ */
+ dtls->ssl = NULL;
+ dtls->connStatus = 0;
+ dtls->fd = 0;
+ memset(&dtls->addr, 0x0, sizeof(struct sockaddr_in));
+ return;
}
/******************************************************************************/
/*
- Return the ssl_t given the sockaddr or NULL if doesn't exist
-*/
+ Return the ssl_t given the sockaddr or NULL if doesn't exist
+ */
serverDtls_t *findClient(struct sockaddr_in addr)
{
- int i;
+ int i;
- for (i = 0; i < tableSize; i++) {
- if (clientTable[i].ssl != NULL) {
- if (clientTable[i].addr.sin_addr.s_addr == addr.sin_addr.s_addr &&
- clientTable[i].addr.sin_port == addr.sin_port) {
- return &clientTable[i];
- }
- }
- }
- return NULL;
+ for (i = 0; i < tableSize; i++)
+ {
+ if (clientTable[i].ssl != NULL)
+ {
+ if (clientTable[i].addr.sin_addr.s_addr == addr.sin_addr.s_addr &&
+ clientTable[i].addr.sin_port == addr.sin_port)
+ {
+ return &clientTable[i];
+ }
+ }
+ }
+ return NULL;
}
static void closeClientList()
{
- int i;
- /* Free any leftover clients */
- for (i = 0; i < tableSize && clientTable[i].ssl != NULL; i++) {
- matrixSslDeleteSession(clientTable[i].ssl);
- }
- psFree(clientTable, NULL);
- tableSize = 0;
+ int i;
+
+ /* Free any leftover clients */
+ for (i = 0; i < tableSize && clientTable[i].ssl != NULL; i++)
+ {
+ matrixSslDeleteSession(clientTable[i].ssl);
+ }
+ psFree(clientTable, NULL);
+ tableSize = 0;
}
#else
@@ -1281,11 +1388,11 @@ static void closeClientList()
/******************************************************************************/
/*
Stub main for compiling without dtls enabled
-*/
+ */
int32 main(int32 argc, char **argv)
{
printf("USE_DTLS must be enabled in " \
- "matrixsslConfig.h at build time to run this application\n");
+ "matrixsslConfig.h at build time to run this application\n");
return -1;
}
#endif /* USE_DTLS */
diff --git a/apps/ssl/Makefile b/apps/ssl/Makefile
index 54fc2dd..70ad43e 100644
--- a/apps/ssl/Makefile
+++ b/apps/ssl/Makefile
@@ -9,10 +9,11 @@
MATRIXSSL_ROOT:=../..
SERVER_SRC:=server.c http.c
CLIENT_SRC:=client.c http.c
+NET_SRC:=net.c
SRC=$(SERVER_SRC) $(CLIENT_SRC)
-
SERVER_EXE:=server$(E)
CLIENT_EXE:=client$(E)
+NET_EXE:=matrixnet$(E)
EXE=$(SERVER_EXE) $(CLIENT_EXE)
#The Mac OS X Xcode project has a target name of 'server' or 'client'
@@ -26,13 +27,18 @@ ifneq (,$(TARGET_NAME))
endif
endif
+# Optional extensions to CFLAGS/LDFLAGS
+CFLAGS+=$(CFLAGS_INTERNAL)
+LDFLAGS+=$(LDFLAGS_INTERNAL)
+
include $(MATRIXSSL_ROOT)/common.mk
# Linked files
STATIC:=\
$(MATRIXSSL_ROOT)/matrixssl/libssl_s.a \
$(MATRIXSSL_ROOT)/crypto/libcrypt_s.a \
- $(MATRIXSSL_ROOT)/core/libcore_s.a
+ $(MATRIXSSL_ROOT)/core/libcore_s.a \
+ $(STATIC_INTERNAL)
# Allow selecting the client auth identity (ID_RSA, ID_ECDH_ECDSA,
# etc.) via an environment variable.
@@ -51,6 +57,9 @@ $(SERVER_EXE): $(SERVER_SRC:.c=.o) $(STATIC)
$(CLIENT_EXE): $(CLIENT_SRC:.c=.o) $(STATIC)
$(CC) -o $@ $^ $(LDFLAGS) $(CFLAGS)
+$(NET_EXE): $(NET_SRC:.c=.o) $(STATIC)
+ $(CC) -o $@ $^ $(LDFLAGS) $(CFLAGS)
+
clean:
rm -f $(EXE) $(OBJS) TLS_*.tmp SSL_*.tmp
diff --git a/apps/ssl/XGetopt.c b/apps/ssl/XGetopt.c
index 081d139..795469c 100644
--- a/apps/ssl/XGetopt.c
+++ b/apps/ssl/XGetopt.c
@@ -1,210 +1,221 @@
-// XGetopt.cpp Version 1.2
-//
-// Author: Hans Dietrich
-// hdietrich2@hotmail.com
-//
-// Description:
-// XGetopt.cpp implements getopt(), a function to parse command lines.
-//
-// History
-// Version 1.2 - 2003 May 17
-// - Added Unicode support
-//
-// Version 1.1 - 2002 March 10
-// - Added example to XGetopt.cpp module header
-//
-// This software is released into the public domain.
-// You are free to use it in any way you like.
-//
-// This software is provided "as is" with no expressed
-// or implied warranty. I accept no liability for any
-// damage or loss of business that this software may cause.
-//
-///////////////////////////////////////////////////////////////////////////////
+/* XGetopt.cpp Version 1.2 */
+/* */
+/* Author: Hans Dietrich */
+/* hdietrich2@hotmail.com */
+/* */
+/* Description: */
+/* XGetopt.cpp implements getopt(), a function to parse command lines. */
+/* */
+/* History */
+/* Version 1.2 - 2003 May 17 */
+/* - Added Unicode support */
+/* */
+/* Version 1.1 - 2002 March 10 */
+/* - Added example to XGetopt.cpp module header */
+/* */
+/* This software is released into the public domain. */
+/* You are free to use it in any way you like. */
+/* */
+/* This software is provided "as is" with no expressed */
+/* or implied warranty. I accept no liability for any */
+/* damage or loss of business that this software may cause. */
+/* */
+/* ///////////////////////////////////////////////////////////////////////////// */
#include "app.h"
#ifdef WIN32
-#include "XGetopt.h"
+# include "XGetopt.h"
-///////////////////////////////////////////////////////////////////////////////
-//
-// X G e t o p t . c p p
-//
-//
-// NAME
-// getopt -- parse command line options
-//
-// SYNOPSIS
-// int getopt(int argc, TCHAR *argv[], TCHAR *optstring)
-//
-// extern TCHAR *optarg;
-// extern int optind;
-//
-// DESCRIPTION
-// The getopt() function parses the command line arguments. Its
-// arguments argc and argv are the argument count and array as
-// passed into the application on program invocation. In the case
-// of Visual C++ programs, argc and argv are available via the
-// variables __argc and __argv (double underscores), respectively.
-// getopt returns the next option letter in argv that matches a
-// letter in optstring. (Note: Unicode programs should use
-// __targv instead of __argv. Also, all character and string
-// literals should be enclosed in _T( ) ).
-//
-// optstring is a string of recognized option letters; if a letter
-// is followed by a colon, the option is expected to have an argument
-// that may or may not be separated from it by white space. optarg
-// is set to point to the start of the option argument on return from
-// getopt.
-//
-// Option letters may be combined, e.g., "-ab" is equivalent to
-// "-a -b". Option letters are case sensitive.
-//
-// getopt places in the external variable optind the argv index
-// of the next argument to be processed. optind is initialized
-// to 0 before the first call to getopt.
-//
-// When all options have been processed (i.e., up to the first
-// non-option argument), getopt returns EOF, optarg will point
-// to the argument, and optind will be set to the argv index of
-// the argument. If there are no non-option arguments, optarg
-// will be set to NULL.
-//
-// The special option "--" may be used to delimit the end of the
-// options; EOF will be returned, and "--" (and everything after it)
-// will be skipped.
-//
-// RETURN VALUE
-// For option letters contained in the string optstring, getopt
-// will return the option letter. getopt returns a question mark (?)
-// when it encounters an option letter not included in optstring.
-// EOF is returned when processing is finished.
-//
-// BUGS
-// 1) Long options are not supported.
-// 2) The GNU double-colon extension is not supported.
-// 3) The environment variable POSIXLY_CORRECT is not supported.
-// 4) The + syntax is not supported.
-// 5) The automatic permutation of arguments is not supported.
-// 6) This implementation of getopt() returns EOF if an error is
-// encountered, instead of -1 as the latest standard requires.
-//
-// EXAMPLE
-// BOOL CMyApp::ProcessCommandLine(int argc, TCHAR *argv[])
-// {
-// int c;
-//
-// while ((c = getopt(argc, argv, _T("aBn:"))) != EOF)
-// {
-// switch (c)
-// {
-// case _T('a'):
-// TRACE(_T("option a\n"));
-// //
-// // set some flag here
-// //
-// break;
-//
-// case _T('B'):
-// TRACE( _T("option B\n"));
-// //
-// // set some other flag here
-// //
-// break;
-//
-// case _T('n'):
-// TRACE(_T("option n: value=%d\n"), atoi(optarg));
-// //
-// // do something with value here
-// //
-// break;
-//
-// case _T('?'):
-// TRACE(_T("ERROR: illegal option %s\n"), argv[optind-1]);
-// return FALSE;
-// break;
-//
-// default:
-// TRACE(_T("WARNING: no handler for option %c\n"), c);
-// return FALSE;
-// break;
-// }
-// }
-// //
-// // check for non-option args here
-// //
-// return TRUE;
-// }
-//
-///////////////////////////////////////////////////////////////////////////////
+/* ///////////////////////////////////////////////////////////////////////////// */
+/* */
+/* X G e t o p t . c p p */
+/* */
+/* */
+/* NAME */
+/* getopt -- parse command line options */
+/* */
+/* SYNOPSIS */
+/* int getopt(int argc, TCHAR *argv[], TCHAR *optstring) */
+/* */
+/* extern TCHAR *optarg; */
+/* extern int optind; */
+/* */
+/* DESCRIPTION */
+/* The getopt() function parses the command line arguments. Its */
+/* arguments argc and argv are the argument count and array as */
+/* passed into the application on program invocation. In the case */
+/* of Visual C++ programs, argc and argv are available via the */
+/* variables __argc and __argv (double underscores), respectively. */
+/* getopt returns the next option letter in argv that matches a */
+/* letter in optstring. (Note: Unicode programs should use */
+/* __targv instead of __argv. Also, all character and string */
+/* literals should be enclosed in _T( ) ). */
+/* */
+/* optstring is a string of recognized option letters; if a letter */
+/* is followed by a colon, the option is expected to have an argument */
+/* that may or may not be separated from it by white space. optarg */
+/* is set to point to the start of the option argument on return from */
+/* getopt. */
+/* */
+/* Option letters may be combined, e.g., "-ab" is equivalent to */
+/* "-a -b". Option letters are case sensitive. */
+/* */
+/* getopt places in the external variable optind the argv index */
+/* of the next argument to be processed. optind is initialized */
+/* to 0 before the first call to getopt. */
+/* */
+/* When all options have been processed (i.e., up to the first */
+/* non-option argument), getopt returns EOF, optarg will point */
+/* to the argument, and optind will be set to the argv index of */
+/* the argument. If there are no non-option arguments, optarg */
+/* will be set to NULL. */
+/* */
+/* The special option "--" may be used to delimit the end of the */
+/* options; EOF will be returned, and "--" (and everything after it) */
+/* will be skipped. */
+/* */
+/* RETURN VALUE */
+/* For option letters contained in the string optstring, getopt */
+/* will return the option letter. getopt returns a question mark (?) */
+/* when it encounters an option letter not included in optstring. */
+/* EOF is returned when processing is finished. */
+/* */
+/* BUGS */
+/* 1) Long options are not supported. */
+/* 2) The GNU double-colon extension is not supported. */
+/* 3) The environment variable POSIXLY_CORRECT is not supported. */
+/* 4) The + syntax is not supported. */
+/* 5) The automatic permutation of arguments is not supported. */
+/* 6) This implementation of getopt() returns EOF if an error is */
+/* encountered, instead of -1 as the latest standard requires. */
+/* */
+/* EXAMPLE */
+/* BOOL CMyApp::ProcessCommandLine(int argc, TCHAR *argv[]) */
+/* { */
+/* int c; */
+/* */
+/* while ((c = getopt(argc, argv, _T("aBn:"))) != EOF) */
+/* { */
+/* switch (c) */
+/* { */
+/* case _T('a'): */
+/* TRACE(_T("option a\n")); */
+/* // */
+/* // set some flag here */
+/* // */
+/* break; */
+/* */
+/* case _T('B'): */
+/* TRACE( _T("option B\n")); */
+/* // */
+/* // set some other flag here */
+/* // */
+/* break; */
+/* */
+/* case _T('n'): */
+/* TRACE(_T("option n: value=%d\n"), atoi(optarg)); */
+/* // */
+/* // do something with value here */
+/* // */
+/* break; */
+/* */
+/* case _T('?'): */
+/* TRACE(_T("ERROR: illegal option %s\n"), argv[optind-1]); */
+/* return FALSE; */
+/* break; */
+/* */
+/* default: */
+/* TRACE(_T("WARNING: no handler for option %c\n"), c); */
+/* return FALSE; */
+/* break; */
+/* } */
+/* } */
+/* // */
+/* // check for non-option args here */
+/* // */
+/* return TRUE; */
+/* } */
+/* */
+/* ///////////////////////////////////////////////////////////////////////////// */
-char *optarg; // global argument pointer
-int optind = 0; // global argv index
-int opterr = 0;
+char *optarg; /* global argument pointer */
+int optind = 0; /* global argv index */
+int opterr = 0;
int getopt(int argc, char *argv[], char *optstring)
{
- static char *next = NULL;
- char c;
- char *cp;
- if (optind == 0)
- next = NULL;
+ static char *next = NULL;
+ char c;
+ char *cp;
- optarg = NULL;
+ if (optind == 0)
+ {
+ next = NULL;
+ }
- if (next == NULL || *next == '\0')
- {
- if (optind == 0)
- optind++;
+ optarg = NULL;
- if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
- {
- optarg = NULL;
- if (optind < argc)
- optarg = argv[optind];
- return EOF;
- }
+ if (next == NULL || *next == '\0')
+ {
+ if (optind == 0)
+ {
+ optind++;
+ }
- if (strcmp(argv[optind], "--") == 0)
- {
- optind++;
- optarg = NULL;
- if (optind < argc)
- optarg = argv[optind];
- return EOF;
- }
+ if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
+ {
+ optarg = NULL;
+ if (optind < argc)
+ {
+ optarg = argv[optind];
+ }
+ return EOF;
+ }
- next = argv[optind];
- next++; // skip past -
- optind++;
- }
+ if (strcmp(argv[optind], "--") == 0)
+ {
+ optind++;
+ optarg = NULL;
+ if (optind < argc)
+ {
+ optarg = argv[optind];
+ }
+ return EOF;
+ }
- c = *next++;
- cp = strchr(optstring, c);
+ next = argv[optind];
+ next++; /* skip past - */
+ optind++;
+ }
- if (cp == NULL || c == ':')
- return '?';
+ c = *next++;
+ cp = strchr(optstring, c);
- cp++;
- if (*cp == ':')
- {
- if (*next != '\0')
- {
- optarg = next;
- next = NULL;
- }
- else if (optind < argc)
- {
- optarg = argv[optind];
- optind++;
- }
- else
- {
- return '?';
- }
- }
+ if (cp == NULL || c == ':')
+ {
+ return '?';
+ }
- return c;
+ cp++;
+ if (*cp == ':')
+ {
+ if (*next != '\0')
+ {
+ optarg = next;
+ next = NULL;
+ }
+ else if (optind < argc)
+ {
+ optarg = argv[optind];
+ optind++;
+ }
+ else
+ {
+ return '?';
+ }
+ }
+
+ return c;
}
#endif /* WIN32 */
diff --git a/apps/ssl/XGetopt.h b/apps/ssl/XGetopt.h
index db6ea60..44b2313 100644
--- a/apps/ssl/XGetopt.h
+++ b/apps/ssl/XGetopt.h
@@ -1,16 +1,16 @@
-// XGetopt.h Version 1.2
-//
-// Author: Hans Dietrich
-// hdietrich2@hotmail.com
-//
-// This software is released into the public domain.
-// You are free to use it in any way you like.
-//
-// This software is provided "as is" with no expressed
-// or implied warranty. I accept no liability for any
-// damage or loss of business that this software may cause.
-//
-///////////////////////////////////////////////////////////////////////////////
+/* XGetopt.h Version 1.2 */
+/* */
+/* Author: Hans Dietrich */
+/* hdietrich2@hotmail.com */
+/* */
+/* This software is released into the public domain. */
+/* You are free to use it in any way you like. */
+/* */
+/* This software is provided "as is" with no expressed */
+/* or implied warranty. I accept no liability for any */
+/* damage or loss of business that this software may cause. */
+/* */
+/* ///////////////////////////////////////////////////////////////////////////// */
#ifndef XGETOPT_H
#define XGETOPT_H
@@ -23,4 +23,4 @@ extern char *optarg;
int getopt(int argc, char *argv[], char *optstring);
-#endif //XGETOPT_H
+#endif /* XGETOPT_H */
diff --git a/apps/ssl/app.h b/apps/ssl/app.h
index 182a3c4..b06ce8b 100644
--- a/apps/ssl/app.h
+++ b/apps/ssl/app.h
@@ -1,128 +1,129 @@
/**
- * @file app.h
- * @version $Format:%h%d$
+ * @file app.h
+ * @version $Format:%h%d$
*
- * Header for MatrixSSL example sockets client and server applications.
+ * Header for MatrixSSL example sockets client and server applications.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_MATRIXSSLAPP
-#define _h_MATRIXSSLAPP
+# define _h_MATRIXSSLAPP
-#ifdef __cplusplus
+# ifdef __cplusplus
extern "C" {
-#endif
+# endif
/******************************************************************************/
-#include "core/coreApi.h"
-#include "matrixssl/matrixsslApi.h"
+# include "core/coreApi.h"
+# include "matrixssl/matrixsslApi.h"
-#include /* Defines EWOULDBLOCK, etc. */
-#include /* Defines FD_CLOEXEC, etc. */
-#include /* Defines malloc, exit, etc. */
+# include /* Defines EWOULDBLOCK, etc. */
+# include /* Defines FD_CLOEXEC, etc. */
+# include /* Defines malloc, exit, etc. */
-#ifdef POSIX
-#include /* Defines AF_INET, etc. */
-#include /* Defines close() */
-#include /* Defines TCP_NODELAY, etc. */
-#include /* inet_addr */
-#endif
+# ifdef POSIX
+# include /* Defines AF_INET, etc. */
+# include /* Defines close() */
+# include /* Defines TCP_NODELAY, etc. */
+# include /* inet_addr */
+# endif
-#ifdef WIN32
-#define SIGPIPE SIGABRT
-#define snprintf _snprintf
-#define close closesocket
-#define MSG_DONTWAIT 0
-#ifndef EWOULDBLOCK
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#endif
-#ifndef EINPROGRESS
-#define EINPROGRESS WSAEINPROGRESS
-#endif
-#endif /* WIN32 */
+# ifdef WIN32
+# define SIGPIPE SIGABRT
+# define snprintf _snprintf
+# define close closesocket
+# define MSG_DONTWAIT 0
+# ifndef EWOULDBLOCK
+# define EWOULDBLOCK WSAEWOULDBLOCK
+# endif
+# ifndef EINPROGRESS
+# define EINPROGRESS WSAEINPROGRESS
+# endif
+# endif /* WIN32 */
/******************************************************************************/
/*
- Platform independent socket defines for convenience
+ Platform independent socket defines for convenience
*/
-#ifndef INVALID_SOCKET
- #define INVALID_SOCKET (-1)
- typedef int32 SOCKET;
-#endif
+# ifndef INVALID_SOCKET
+# define INVALID_SOCKET (-1)
+typedef int32 SOCKET;
+# endif
-#ifdef WIN32
- #define SOCKET_ERRNO WSAGetLastError()
-#else
- #define SOCKET_ERRNO errno
-#endif
+# ifdef WIN32
+# define SOCKET_ERRNO WSAGetLastError()
+# else
+# define SOCKET_ERRNO errno
+# endif
/******************************************************************************/
/*
- Configuration Options
-*/
-#define HTTPS_PORT 4433 /* Port to run the server/client on */
+ Configuration Options
+ */
+# define HTTPS_PORT 4433 /* Port to run the server/client on */
/******************************************************************************/
/*
- Protocol specific defines
+ Protocol specific defines
*/
/* Maximum size of parseable http element. In this case, a HTTP header line. */
-#define HTTPS_BUFFER_MAX 256
+# define HTTPS_BUFFER_MAX 256
/* Return codes from http parsing routine */
-#define HTTPS_COMPLETE 1 /* Full request/response parsed */
-#define HTTPS_PARTIAL 0 /* Only a partial request/response was received */
-#define HTTPS_ERROR MATRIXSSL_ERROR /* Invalid/unsupported HTTP syntax */
+# define HTTPS_COMPLETE 1 /* Full request/response parsed */
+# define HTTPS_PARTIAL 0 /* Only a partial request/response was received */
+# define HTTPS_ERROR MATRIXSSL_ERROR /* Invalid/unsupported HTTP syntax */
-typedef struct {
- DLListEntry List;
- ssl_t *ssl;
- SOCKET fd;
- psTime_t time; /* Last time there was activity */
- uint32 timeout; /* in milliseconds*/
- uint32 flags;
- unsigned char *parsebuf; /* Partial data */
- uint32 parsebuflen;
- uint32 bytes_received;
- uint32 bytes_requested;
- uint32 bytes_sent;
- psPool_t *bufPool; /* Mem pool to allocate inbuf and outbuf */
+typedef struct
+{
+ DLListEntry List;
+ ssl_t *ssl;
+ SOCKET fd;
+ psTime_t time; /* Last time there was activity */
+ uint32 timeout; /* in milliseconds*/
+ uint32 flags;
+ unsigned char *parsebuf; /* Partial data */
+ uint32 parsebuflen;
+ uint32 bytes_received;
+ uint32 bytes_requested;
+ uint32 bytes_sent;
+ psPool_t *bufPool; /* Mem pool to allocate inbuf and outbuf */
} httpConn_t;
extern int32 httpBasicParse(httpConn_t *cp, unsigned char *buf, uint32 len,
- int32 trace);
+ int32 trace);
/******************************************************************************/
-#ifdef __cplusplus
+# ifdef __cplusplus
}
-#endif
+# endif
#endif /* _h_MATRIXSSLAPP */
diff --git a/apps/ssl/client.c b/apps/ssl/client.c
index 0f35340..b64061c 100644
--- a/apps/ssl/client.c
+++ b/apps/ssl/client.c
@@ -1,34 +1,34 @@
/**
- * @file client.c
- * @version $Format:%h%d$
+ * @file client.c
+ * @version $Format:%h%d$
*
- * Simple MatrixSSL blocking client example.
+ * Simple MatrixSSL blocking client example.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
@@ -39,185 +39,224 @@
#include
#include "app.h"
#ifndef WIN32
-#include
+# include
#else
-#include "XGetopt.h"
+# include "XGetopt.h"
#endif
#include "matrixssl/matrixsslApi.h"
+/* Currently this example uses _psTrace for tracing, so osdep.h is needed: */
+#include "core/osdep.h"
+#include "core/psUtil.h"
#ifdef USE_CLIENT_SIDE_SSL
-#ifdef WIN32
-#pragma message("DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS.")
-#else
-#warning "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
-#endif
+# ifndef MATRIX_TESTING_ENVIRONMENT /* Omit the message when testing. */
+# ifdef WIN32
+# pragma message("DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS.")
+# else
+# warning "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
+# endif
+# endif
/*
- If supporting client authentication, pick ONE identity to auto select a
- certificate and private key that support desired algorithms.
-*/
-//#define ID_RSA /* RSA Certificate and Key */
-//#define ID_ECDH_ECDSA /* EC Certificate and Key */
-//#define ID_ECDH_RSA /* EC Key with RSA signed certificate */
+ If supporting client authentication, pick ONE identity to auto select a
+ certificate and private key that support desired algorithms.
+ */
+/* #define ID_RSA / * RSA Certificate and Key * / */
+/* #define ID_ECDH_ECDSA / * EC Certificate and Key * / */
+/* #define ID_ECDH_RSA / * EC Key with RSA signed certificate * / */
-#if !defined(ID_RSA) && !defined(ID_ECDH_ECDSA) && !defined(ID_ECDH_RSA)
+# if !defined(ID_RSA) && !defined(ID_ECDH_ECDSA) && !defined(ID_ECDH_RSA)
/* Choose a default identity based on which algorithms are supported. */
-#ifdef USE_RSA_CIPHER_SUITE
-#define ID_RSA
-#else
-#ifdef USE_ECC_CIPHER_SUITE
-#define ID_ECDH_ECDSA
-#else
-#ifndef USE_PSK_CIPHER_SUITE
-#error "Please enable either RSA or ECC for client when not using PSK"
-#endif /* !USE_PSK_CIPHER_SUITE */
-#endif /* USE_ECC_CIPHER_SUITE */
-#endif /* USE_RSA_CIPHER_SUITE */
-#endif /* !ID_RSA && !ID_ECDH_ECDSA && !ID_ECDH_RSA */
+# ifdef USE_RSA_CIPHER_SUITE
+# define ID_RSA
+# else
+# ifdef USE_ECC_CIPHER_SUITE
+# define ID_ECDH_ECDSA
+# else
+# ifndef USE_PSK_CIPHER_SUITE
+# error "Please enable either RSA or ECC for client when not using PSK"
+# endif /* !USE_PSK_CIPHER_SUITE */
+# endif /* USE_ECC_CIPHER_SUITE */
+# endif /* USE_RSA_CIPHER_SUITE */
+# endif /* !ID_RSA && !ID_ECDH_ECDSA && !ID_ECDH_RSA */
-#define USE_HEADER_KEYS
-#define ALLOW_ANON_CONNECTIONS 1
-#define CRL_MAX_LENGTH 1048576 /* Maximum length for CRL: 1 megabyte. */
+# define USE_HEADER_KEYS
+# define ALLOW_ANON_CONNECTIONS 1
+# define CRL_MAX_LENGTH 1048576 /* Maximum length for CRL: 1 megabyte. */
-/* If the algorithm type is supported, load a CA for it */
-#ifdef USE_HEADER_KEYS
+/* If the algorithm type is supported, load a CA for it */
+# ifdef USE_ECC_CIPHER_SUITE
+
+# if defined(USE_SECP192R1) && defined(USE_SECP224R1) && defined(USE_SECP521R1)
+# ifdef USE_HEADER_KEYS
+# include "testkeys/EC/ALL_EC_CAS.h"
+# else
+static char ecCAFile[] = "../../testkeys/EC/ALL_EC_CAS.pem";
+# endif /* USE_HEADER_KEYS */
+# endif /* USE_SECP192R1 && USE_SECP224R1 && USE_SECP521R1 */
+
+# if !defined(USE_SECP192R1) && defined(USE_SECP224R1) && defined(USE_SECP521R1)
+# ifdef USE_HEADER_KEYS
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192.h"
+# else
+static char ecCAFile[] = "../../testkeys/EC/ALL_EC_CAS_EXCEPT_P192.pem";
+# endif /* USE_HEADER_KEYS */
+# endif /* !USE_SECP192R1 && USE_SECP224R1 && USE_SECP521R1 */
+
+# if defined(USE_SECP192R1) && !defined(USE_SECP224R1) && defined(USE_SECP521R1)
+# ifdef USE_HEADER_KEYS
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P224.h"
+# else
+static char ecCAFile[] = "../../testkeys/EC/ALL_EC_CAS_EXCEPT_P224.pem";
+# endif /* USE_HEADER_KEYS */
+# endif /* USE_SECP192R1 && !USE_SECP224R1 && USE_SECP521R1 */
+
+# if defined(USE_SECP192R1) && defined(USE_SECP224R1) && !defined(USE_SECP521R1)
+# ifdef USE_HEADER_KEYS
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P521.h"
+# else
+static char ecCAFile[] = "../../testkeys/EC/ALL_EC_CAS_EXCEPT_P521.pem";
+# endif /* USE_HEADER_KEYS */
+# endif /* USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
+
+# if !defined(USE_SECP192R1) && !defined(USE_SECP224R1) && defined(USE_SECP521R1)
+# ifdef USE_HEADER_KEYS
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P224.h"
+# else
+static char ecCAFile[] = "../../testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P224.pem";
+# endif /* USE_HEADER_KEYS */
+# endif /* !USE_SECP192R1 && !USE_SECP224R1 && USE_SECP521R1 */
+
+# if !defined(USE_SECP192R1) && defined(USE_SECP224R1) && !defined(USE_SECP521R1)
+# ifdef USE_HEADER_KEYS
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P521.h"
+# else
+static char ecCAFile[] = "../../testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P521.pem";
+# endif /* USE_HEADER_KEYS */
+# endif /* !USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
+
+# if defined(USE_SECP192R1) && !defined(USE_SECP224R1) && !defined(USE_SECP521R1)
+# ifdef USE_HEADER_KEYS
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P224_AND_P521.h"
+# else
+static char ecCAFile[] = "../../testkeys/EC/ALL_EC_CAS_EXCEPT_P224_AND_P521.pem";
+# endif /* USE_HEADER_KEYS */
+# endif /* USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
+
+# if !defined(USE_SECP192R1) && !defined(USE_SECP224R1) && !defined(USE_SECP521R1)
+# ifdef USE_HEADER_KEYS
+# include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_P224_AND_P521.h"
+# else
+static char ecCAFile[] = "../../testkeys/EC/ALL_EC_CAS_EXCEPT_P192_P224_AND_P521.pem";
+# endif /* USE_HEADER_KEYS */
+# endif /* !USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
+
+# ifndef USE_HEADER_KEYS
+/*
+ Pointer to filename. We shall increment this when we need to
+ skip over the ../../ prefix.
+ */
+static char *pEcCAFile = ecCAFile;
+# endif /* !USE_HEADER_KEYS */
+
+# endif /* USE_ECC_CIPHER_SUITE */
+
+# ifdef USE_HEADER_KEYS
/* CAs */
-#ifdef USE_RSA_CIPHER_SUITE
-#include "testkeys/RSA/ALL_RSA_CAS.h"
-#ifdef USE_ECC_CIPHER_SUITE
-#include "testkeys/ECDH_RSA/ALL_ECDH-RSA_CAS.h"
-#endif
-#endif
-
-#ifdef USE_ECC_CIPHER_SUITE
-
-#if defined(USE_SECP192R1) && defined(USE_SECP224R1) && defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS.h"
-#endif /* USE_SECP192R1 && USE_SECP224R1 && USE_SECP521R1 */
-
-#if !defined(USE_SECP192R1) && defined(USE_SECP224R1) && defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192.h"
-#endif /* !USE_SECP192R1 && USE_SECP224R1 && USE_SECP521R1 */
-
-#if defined(USE_SECP192R1) && !defined(USE_SECP224R1) && defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P224.h"
-#endif /* USE_SECP192R1 && !USE_SECP224R1 && USE_SECP521R1 */
-
-#if defined(USE_SECP192R1) && defined(USE_SECP224R1) && !defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P521.h"
-#endif /* USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
-
-#if !defined(USE_SECP192R1) && !defined(USE_SECP224R1) && defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P224.h"
-#endif /* !USE_SECP192R1 && !USE_SECP224R1 && USE_SECP521R1 */
-
-#if !defined(USE_SECP192R1) && defined(USE_SECP224R1) && !defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P521.h"
-#endif /* !USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
-
-#if defined(USE_SECP192R1) && !defined(USE_SECP224R1) && !defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P224_AND_P521.h"
-#endif /* USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
-
-#if !defined(USE_SECP192R1) && !defined(USE_SECP224R1) && !defined(USE_SECP521R1)
-#include "testkeys/EC/ALL_EC_CAS_EXCEPT_P192_P224_AND_P521.h"
-#endif /* !USE_SECP192R1 && USE_SECP224R1 && !USE_SECP521R1 */
-
-#endif /* USE_ECC_CIPHER_SUITE */
+# ifdef USE_RSA_CIPHER_SUITE
+# include "testkeys/RSA/ALL_RSA_CAS.h"
+# ifdef USE_ECC_CIPHER_SUITE
+# include "testkeys/ECDH_RSA/ALL_ECDH-RSA_CAS.h"
+# endif
+# endif
/* Identity Certs and Keys for use with Client Authentication */
-#ifdef ID_RSA
-#define EXAMPLE_RSA_KEYS
-#include "testkeys/RSA/1024_RSA.h"
-#include "testkeys/RSA/1024_RSA_KEY.h"
-#include "testkeys/RSA/2048_RSA.h"
-#include "testkeys/RSA/2048_RSA_KEY.h"
-#include "testkeys/RSA/4096_RSA.h"
-#include "testkeys/RSA/4096_RSA_KEY.h"
-#endif
+# ifdef ID_RSA
+# define EXAMPLE_RSA_KEYS
+# include "testkeys/RSA/1024_RSA.h"
+# include "testkeys/RSA/1024_RSA_KEY.h"
+# include "testkeys/RSA/2048_RSA.h"
+# include "testkeys/RSA/2048_RSA_KEY.h"
+# include "testkeys/RSA/3072_RSA.h"
+# include "testkeys/RSA/3072_RSA_KEY.h"
+# include "testkeys/RSA/4096_RSA.h"
+# include "testkeys/RSA/4096_RSA_KEY.h"
+# endif
-#ifdef ID_ECDH_ECDSA
-#define EXAMPLE_EC_KEYS
-#include "testkeys/EC/384_EC.h"
-#include "testkeys/EC/384_EC_KEY.h"
-#endif
+# ifdef ID_ECDH_ECDSA
+# define EXAMPLE_EC_KEYS
+# include "testkeys/EC/384_EC.h"
+# include "testkeys/EC/384_EC_KEY.h"
+# endif
-#ifdef ID_ECDH_RSA
-#define EXAMPLE_ECDH_RSA_KEYS
-#include "testkeys/ECDH_RSA/521_ECDH-RSA.h"
-#include "testkeys/ECDH_RSA/521_ECDH-RSA_KEY.h"
-#endif
+# ifdef ID_ECDH_RSA
+# define EXAMPLE_ECDH_RSA_KEYS
+# include "testkeys/ECDH_RSA/521_ECDH-RSA.h"
+# include "testkeys/ECDH_RSA/521_ECDH-RSA_KEY.h"
+# endif
/* File-based keys */
-#else
+# else /* USE_HEADER_KEYS */
/* CAs */
-#ifdef USE_RSA_CIPHER_SUITE
+# ifdef USE_RSA_CIPHER_SUITE
static char rsaCAFile[] = "../../testkeys/RSA/ALL_RSA_CAS.pem";
-#ifdef USE_ECC_CIPHER_SUITE
+static char *pRsaCAFile = rsaCAFile;
+# ifdef USE_ECC_CIPHER_SUITE
static char ecdhRsaCAFile[] = "../../testkeys/ECDH_RSA/ALL_ECDH-RSA_CAS.pem";
-#endif
-#endif
-
-#ifdef USE_ECC_CIPHER_SUITE
-#if defined(USE_SECP192R1) && defined(USE_SECP521R1)
-static char ecCAFile[] = "../../testkeys/EC/ALL_EC_CAS.pem";
-#endif /* USE_SECP192R1 && USE_SECP521R1 */
-
-#if !defined(USE_SECP192R1) && defined(USE_SECP521R1)
-static char ecCAFile[] = "../../testkeys/EC/ALL_EC_CAS_EXCEPT_P192.pem";
-#endif /* USE_SECP192R1 && USE_SECP521R1 */
-
-#if defined(USE_SECP192R1) && !defined(USE_SECP521R1)
-static char ecCAFile[] = "../../testkeys/EC/ALL_EC_CAS_EXCEPT_P521.pem";
-#endif /* USE_SECP192R1 && USE_SECP521R1 */
-
-#if !defined(USE_SECP192R1) && !defined(USE_SECP521R1)
-static char ecCAFile[] = "../../testkeys/EC/ALL_EC_CAS_EXCEPT_P192_AND_P521.pem";
-#endif /* USE_SECP192R1 && USE_SECP521R1 */
-
-#endif /* USE_ECC_CIPHER_SUITE */
+static char *pEcdhRsaCAFile = ecdhRsaCAFile;
+# endif
+# endif
/* Identity Certs and Keys for use with Client Authentication */
-#ifdef ID_RSA
-#define EXAMPLE_RSA_KEYS
+# ifdef ID_RSA
+# define EXAMPLE_RSA_KEYS
static char rsaCertFile[] = "../../testkeys/RSA/2048_RSA.pem";
static char rsaPrivkeyFile[] = "../../testkeys/RSA/2048_RSA_KEY.pem";
-#endif
+static char *pRsaCertFile = rsaCertFile;
+static char *pRsaPrivkeyFile = rsaPrivkeyFile;
+# endif
-#ifdef ID_ECDH_ECDSA
-#define EXAMPLE_EC_KEYS
-static char ecCertFile[] = "../../testkeys/EC/521_EC.pem";
-static char ecPrivkeyFile[] = "../../testkeys/EC/521_EC_KEY.pem";
-#endif
+# ifdef ID_ECDH_ECDSA
+# define EXAMPLE_EC_KEYS
+static char ecCertFile[] = "../../testkeys/EC/384_EC.pem";
+static char ecPrivkeyFile[] = "../../testkeys/EC/384_EC_KEY.pem";
+static char *pEcCertFile = ecCertFile;
+static char *pEcPrivkeyFile = ecPrivkeyFile;
+# endif
-#ifdef ID_ECDH_RSA
-#define EXAMPLE_ECDH_RSA_KEYS
+# ifdef ID_ECDH_RSA
+# define EXAMPLE_ECDH_RSA_KEYS
static char ecdhRsaCertFile[] = "../../testkeys/ECDH_RSA/521_ECDH-RSA.pem";
static char ecdhRsaPrivkeyFile[] = "../../testkeys/ECDH_RSA/521_ECDH-RSA_KEY.pem";
-#endif
+static char *pEcdhRsaCertFile = ecdhRsaCertFile;
+static char *pEcdhRsaPrivkeyFile = ecdhRsaPrivkeyFile;
+# endif
-#endif /* USE_HEADER_KEYS */
-
-#ifdef USE_PSK_CIPHER_SUITE
-/* Defines PSK_HEADER_TABLE and PSK_HEADER_TABLE_COUNT */
-#include "../../testkeys/PSK/psk.h"
-#endif
-
-//#define REHANDSHAKE_TEST
-#ifdef REHANDSHAKE_TEST
+/* #define REHANDSHAKE_TEST */
+# ifdef REHANDSHAKE_TEST
static int g_rehandshakeFlag = 0;
-#endif
+# endif
+# endif /* USE_HEADER_KEYS */
+
+/*
+ No file-based keys for PSK.
+ Include psk.h even when USE_HEADER_KEYS is not defined.
+ */
+# ifdef USE_PSK_CIPHER_SUITE
+/* Defines PSK_HEADER_TABLE and PSK_HEADER_TABLE_COUNT */
+# include "../../testkeys/PSK/psk.h"
+# endif
/********************************** Globals ***********************************/
static unsigned char g_httpRequestHdr[] = "GET %s HTTP/1.0\r\n"
- "User-Agent: MatrixSSL/" MATRIXSSL_VERSION "\r\n"
- "Accept: */*\r\n"
- "Content-Length: 0\r\n"
- "\r\n";
+ "User-Agent: MatrixSSL/" MATRIXSSL_VERSION "\r\n"
+ "Accept: */*\r\n"
+ "Content-Length: 0\r\n"
+ "\r\n";
static const char g_strver[][8] =
- { "SSL 3.0", "TLS 1.0", "TLS 1.1", "TLS 1.2" };
+{ "SSL 3.0", "TLS 1.0", "TLS 1.1", "TLS 1.2" };
static unsigned char g_matrixShutdownServer[] = "MATRIX_SHUTDOWN";
@@ -226,6 +265,7 @@ static char g_ip[16];
static char g_path[256];
static int g_port, g_new, g_resumed, g_ciphers, g_version, g_closeServer;
static int g_key_len, g_disableCertNameChk;
+static int g_max_verify_depth;
static uint16_t g_cipher[16];
static int g_trace;
static int g_keepalive;
@@ -233,12 +273,23 @@ static int g_keepalive;
static uint32_t g_bytes_requested;
static uint8_t g_send_closure_alert;
-struct g_sslstats {
- int rbytes; /* Bytes read */
- int64 hstime;
- int64 datatime;
+struct g_sslstats
+{
+ int rbytes; /* Bytes read */
+ int64 hstime;
+ int64 datatime;
};
+# ifndef USE_HEADER_KEYS
+/*
+ Are we in MatrixSSL root dir? If yes, we shall to skip
+ the "../.." prefix in the key and cert filenames.
+ */
+static int g_at_matrixssl_root = 0;
+# endif /* USE_HEADER_KEYS */
+
+static int g_enable_ext_cv_sig_op = 0;
+
/********************************** Defines ***********************************/
/****************************** Local Functions *******************************/
@@ -248,1774 +299,2210 @@ static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert);
static SOCKET lsocketConnect(char *ip, int32 port, int32 *err);
static void closeConn(ssl_t *ssl, SOCKET fd);
static int32_t extensionCb(ssl_t *ssl,
- uint16_t extType, uint8_t extLen, void *e);
+ uint16_t extType, uint8_t extLen, void *e);
-#ifdef USE_CRL
+# ifdef USE_CRL
static int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
- unsigned char **crlBuf, uint32_t *crlBufLen);
+ unsigned char **crlBuf, uint32_t *crlBufLen);
static int32_t fetchParseAndAuthCRLfromCert(psPool_t *pool, psX509Cert_t *cert,
- psX509Cert_t *potentialIssuers);
+ psX509Cert_t *potentialIssuers);
/* Enable the example on how to fetch CRLs mid-handshake. If disabled, the
- example will show how to halt the handshake to go out and fetch and retry
- the connection (command line option -n must be specified for multiple
- connection attempts) */
-//#define MIDHANDSHAKE_CRL_FETCH
+ example will show how to halt the handshake to go out and fetch and retry
+ the connection (command line option -n must be specified for multiple
+ connection attempts) */
+/* #define MIDHANDSHAKE_CRL_FETCH */
-#ifndef MIDHANDSHAKE_CRL_FETCH
+# ifndef MIDHANDSHAKE_CRL_FETCH
/* In the example where we stop the handhsake to go fetch the CRL files, we
- need storage to hold the CRL URL distribution points since those are
- coming from the server cert chain which we do not keep around */
-#define CRL_MAX_SERVER_CERT_CHAIN 3
-#define CRL_MAX_URL_LEN 256
-static unsigned char g_crlDistURLs[CRL_MAX_SERVER_CERT_CHAIN][CRL_MAX_URL_LEN];
+ need storage to hold the CRL URL distribution points since those are
+ coming from the server cert chain which we do not keep around */
+# define CRL_MAX_SERVER_CERT_CHAIN 3
+# define CRL_MAX_URL_LEN 256
+static unsigned char g_crlDistURLs[CRL_MAX_SERVER_CERT_CHAIN][CRL_MAX_URL_LEN];
static int32_t fetchParseAndAuthCRLfromUrl(psPool_t *pool, unsigned char *url,
- uint32_t urlLen, psX509Cert_t *potentialIssuers);
+ uint32_t urlLen, psX509Cert_t *potentialIssuers);
static void fetchSavedCRL(psX509Cert_t *potentialIssuers);
-#endif
-#endif /* USE_CRL */
+# endif
+# endif /* USE_CRL */
+# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING
+# endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */
/******************************************************************************/
/*
- Make a secure HTTP request to a defined IP and port
- Connection is made in blocking socket mode
- The connection is considered successful if the SSL/TLS session is
- negotiated successfully, a request is sent, and a HTTP response is received.
+ Make a secure HTTP request to a defined IP and port
+ Connection is made in blocking socket mode
+ The connection is considered successful if the SSL/TLS session is
+ negotiated successfully, a request is sent, and a HTTP response is received.
*/
static int g_alreadyopen = 0;
static int32 httpsClientConnection(sslKeys_t *keys, sslSessionId_t *sid,
- struct g_sslstats *stats)
+ struct g_sslstats *stats)
{
- tlsExtension_t *extension;
- int32 rc, transferred, len, sessionFlag, extLen;
- ssl_t *ssl;
- unsigned char *buf, *ext;
- httpConn_t cp;
- SOCKET fd;
- psTime_t t1, t2;
- sslSessOpts_t options;
-#ifdef USE_ALPN
- unsigned char *alpn[MAX_PROTO_EXT];
- int32 alpnLen[MAX_PROTO_EXT];
-#endif
+ tlsExtension_t *extension;
+ int32 rc, transferred, len, sessionFlag, extLen;
+ ssl_t *ssl;
+ unsigned char *buf, *ext;
+ httpConn_t cp;
+ SOCKET fd;
+ psTime_t t1, t2;
+ sslSessOpts_t options;
- memset(&cp, 0x0, sizeof(httpConn_t));
- if (g_alreadyopen == 0) {
- fd = lsocketConnect(g_ip, g_port, &rc);
- if (g_keepalive == 1) {
- g_alreadyopen = fd;
- }
- } else {
- fd = g_alreadyopen;
- rc = PS_SUCCESS;
- }
- if (fd == INVALID_SOCKET || rc != PS_SUCCESS) {
- return PS_PLATFORM_FAIL;
- }
+# ifdef USE_ALPN
+ unsigned char *alpn[MAX_PROTO_EXT];
+ int32 alpnLen[MAX_PROTO_EXT];
+# endif
-#ifdef SSL_FLAGS_SSLV3
- /* Corresponds to version 3.g_version */
- switch (g_version) {
- case 0:
- sessionFlag = SSL_FLAGS_SSLV3;
- break;
- case 1:
- sessionFlag = SSL_FLAGS_TLS_1_0;
- break;
- case 2:
- sessionFlag = SSL_FLAGS_TLS_1_1;
- break;
- case 3:
- sessionFlag = SSL_FLAGS_TLS_1_2;
- break;
- default:
- sessionFlag = SSL_FLAGS_TLS_1_0;
- break;
- }
-#else
- /* MatrixSSL <= 3.4.2 don't support setting version on request */
- sessionFlag = 0;
-#endif
+ memset(&cp, 0x0, sizeof(httpConn_t));
+ if (g_alreadyopen == 0)
+ {
+ fd = lsocketConnect(g_ip, g_port, &rc);
+ if (g_keepalive == 1)
+ {
+ g_alreadyopen = fd;
+ }
+ }
+ else
+ {
+ fd = g_alreadyopen;
+ rc = PS_SUCCESS;
+ }
+ if (fd == INVALID_SOCKET || rc != PS_SUCCESS)
+ {
+ return PS_PLATFORM_FAIL;
+ }
- memset(&options, 0x0, sizeof(sslSessOpts_t));
- options.versionFlag = sessionFlag;
- options.userPtr = keys;
- //options.maxFragLen = 512;
- //options.truncHmac = PS_TRUE;
- //options.ticketResumption = PS_TRUE;
- //options.ecFlags |= SSL_OPT_SECP521R1;
- //options.ecFlags |= SSL_OPT_SECP384R1;
- //options.ecFlags |= SSL_OPT_SECP256R1;
- //options.ecFlags |= SSL_OPT_SECP224R1;
- //options.ecFlags |= SSL_OPT_SECP192R1;
+# ifdef SSL_FLAGS_SSLV3
+ /* Corresponds to version 3.g_version */
+ switch (g_version)
+ {
+ case 0:
+ sessionFlag = SSL_FLAGS_SSLV3;
+ break;
+ case 1:
+ sessionFlag = SSL_FLAGS_TLS_1_0;
+ break;
+ case 2:
+ sessionFlag = SSL_FLAGS_TLS_1_1;
+ break;
+ case 3:
+ sessionFlag = SSL_FLAGS_TLS_1_2;
+ break;
+ default:
+ sessionFlag = SSL_FLAGS_TLS_1_0;
+ break;
+ }
+# else
+ /* MatrixSSL <= 3.4.2 don't support setting version on request */
+ sessionFlag = 0;
+# endif
- matrixSslNewHelloExtension(&extension, NULL);
- matrixSslCreateSNIext(NULL, (unsigned char*)g_ip, (uint32)strlen(g_ip),
- &ext, &extLen);
- matrixSslLoadHelloExtension(extension, ext, extLen, EXT_SNI);
- psFree(ext, NULL);
+ memset(&options, 0x0, sizeof(sslSessOpts_t));
+ options.versionFlag = sessionFlag;
+ options.userPtr = keys;
+ /* options.maxFragLen = 512; */
+ /* options.truncHmac = PS_TRUE; */
+ /* options.ticketResumption = PS_TRUE; */
+ /* options.ecFlags |= SSL_OPT_SECP521R1; */
+ /* options.ecFlags |= SSL_OPT_SECP384R1; */
+ /* options.ecFlags |= SSL_OPT_SECP256R1; */
+ /* options.ecFlags |= SSL_OPT_SECP224R1; */
+ /* options.ecFlags |= SSL_OPT_SECP192R1; */
+# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING
+# endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */
+# ifdef TEST_KEEP_PEER_CERTS
+ options.keep_peer_certs = 1;
+ options.keep_peer_cert_der = 1;
+# endif
+ if (g_max_verify_depth != 0)
+ options.validateCertsOpts.max_verify_depth = g_max_verify_depth;
-#ifdef USE_ALPN
- /* Application Layer Protocol Negotiation */
- alpn[0] = psMalloc(NULL, strlen("http/1.0"));
- memcpy(alpn[0], "http/1.0", strlen("http/1.0"));
- alpnLen[0] = strlen("http/1.0");
+ matrixSslNewHelloExtension(&extension, NULL);
+ matrixSslCreateSNIext(NULL, (unsigned char *) g_ip, (uint32) strlen(g_ip),
+ &ext, &extLen);
+ matrixSslLoadHelloExtension(extension, ext, extLen, EXT_SNI);
+ psFree(ext, NULL);
- alpn[1] = psMalloc(NULL, strlen("http/1.1"));
- memcpy(alpn[1], "http/1.1", strlen("http/1.1"));
- alpnLen[1] = strlen("http/1.1");
+# ifdef USE_ALPN
+ /* Application Layer Protocol Negotiation */
+ alpn[0] = psMalloc(NULL, strlen("http/1.0"));
+ memcpy(alpn[0], "http/1.0", strlen("http/1.0"));
+ alpnLen[0] = strlen("http/1.0");
- matrixSslCreateALPNext(NULL, 2, alpn, alpnLen, &ext, &extLen);
- matrixSslLoadHelloExtension(extension, ext, extLen, EXT_ALPN);
- psFree(alpn[0], NULL);
- psFree(alpn[1], NULL);
-#endif
+ alpn[1] = psMalloc(NULL, strlen("http/1.1"));
+ memcpy(alpn[1], "http/1.1", strlen("http/1.1"));
+ alpnLen[1] = strlen("http/1.1");
- /* We are passing the IP address of the server as the expected name */
- /* To skip certificate subject name tests, pass NULL instead of g_ip */
- if (g_disableCertNameChk == 0) {
- rc = matrixSslNewClientSession(&ssl, keys, sid, g_cipher, g_ciphers,
- certCb, g_ip, extension, extensionCb, &options);
-
+ matrixSslCreateALPNext(NULL, 2, alpn, alpnLen, &ext, &extLen);
+ matrixSslLoadHelloExtension(extension, ext, extLen, EXT_ALPN);
+ psFree(alpn[0], NULL);
+ psFree(alpn[1], NULL);
+# endif
- } else {
- rc = matrixSslNewClientSession(&ssl, keys, sid, g_cipher, g_ciphers,
- certCb, NULL, extension, extensionCb, &options);
- }
+ /* We are passing the IP address of the server as the expected name */
+ /* To skip certificate subject name tests, pass NULL instead of g_ip */
+ if (g_disableCertNameChk == 0)
+ {
+ rc = matrixSslNewClientSession(&ssl, keys, sid, g_cipher, g_ciphers,
+ certCb, g_ip, extension, extensionCb, &options);
- matrixSslDeleteHelloExtension(extension);
- if (rc != MATRIXSSL_REQUEST_SEND) {
- _psTraceInt("New Client Session Failed: %d. Exiting\n", rc);
- close(fd);
- return PS_ARG_FAIL;
- }
+
+ }
+ else
+ {
+ rc = matrixSslNewClientSession(&ssl, keys, sid, g_cipher, g_ciphers,
+ certCb, NULL, extension, extensionCb, &options);
+ }
+
+ matrixSslDeleteHelloExtension(extension);
+ if (rc != MATRIXSSL_REQUEST_SEND)
+ {
+ _psTraceInt("New Client Session Failed: %d. Exiting\n", rc);
+ close(fd);
+ return PS_ARG_FAIL;
+ }
WRITE_MORE:
- while ((len = matrixSslGetOutdata(ssl, &buf)) > 0) {
- if (g_trace) psTraceBytes("SEND", buf, len);
- transferred = send(fd, buf, len, 0);
- if (transferred <= 0) {
- printf("Error sending\n");
- goto L_CLOSE_ERR;
- } else {
- /* Indicate that we've written > 0 bytes of data */
- if ((rc = matrixSslSentData(ssl, transferred)) < 0) {
- goto L_CLOSE_ERR;
- }
- if (rc == MATRIXSSL_REQUEST_CLOSE) {
- closeConn(ssl, fd);
- return MATRIXSSL_SUCCESS;
- }
- if (rc == MATRIXSSL_HANDSHAKE_COMPLETE) {
- /* If we sent the Finished SSL message, initiate the HTTP req */
- /* (This occurs on a resumption handshake) */
- if ((rc = httpWriteRequest(ssl)) < 0) {
- goto L_CLOSE_ERR;
- }
- if (rc == MATRIXSSL_REQUEST_SEND) {
- /* We have a HTTP request to send */
- goto WRITE_MORE;
- }
- closeConn(ssl, fd);
- return MATRIXSSL_SUCCESS;
- }
- /* MATRIXSSL_REQUEST_SEND is handled by loop logic */
- }
- }
+ while ((len = matrixSslGetOutdata(ssl, &buf)) > 0)
+ {
+ if (g_trace)
+ {
+ psTraceBytes("SEND", buf, len);
+ }
+ transferred = send(fd, buf, len, 0);
+ if (transferred <= 0)
+ {
+ printf("Error sending\n");
+ goto L_CLOSE_ERR;
+ }
+ else
+ {
+ /* Indicate that we've written > 0 bytes of data */
+ if ((rc = matrixSslSentData(ssl, transferred)) < 0)
+ {
+ goto L_CLOSE_ERR;
+ }
+ if (rc == MATRIXSSL_REQUEST_CLOSE)
+ {
+ closeConn(ssl, fd);
+ return MATRIXSSL_SUCCESS;
+ }
+ if (rc == MATRIXSSL_HANDSHAKE_COMPLETE)
+ {
+ /* If we sent the Finished SSL message, initiate the HTTP req */
+ /* (This occurs on a resumption handshake) */
+ if ((rc = httpWriteRequest(ssl)) < 0)
+ {
+ goto L_CLOSE_ERR;
+ }
+ if (rc == MATRIXSSL_REQUEST_SEND)
+ {
+ /* We have a HTTP request to send */
+ goto WRITE_MORE;
+ }
+ closeConn(ssl, fd);
+ return MATRIXSSL_SUCCESS;
+ }
+ /* MATRIXSSL_REQUEST_SEND is handled by loop logic */
+ }
+ }
READ_MORE:
- if ((len = matrixSslGetReadbuf(ssl, &buf)) <= 0) {
- goto L_CLOSE_ERR;
- }
- if ((transferred = recv(fd, buf, len, 0)) < 0) {
- goto L_CLOSE_ERR;
- }
- if (g_trace) psTraceBytes("RECV", buf, transferred);
- /* If EOF, remote socket closed. But we haven't received the HTTP response
- so we consider it an error in the case of an HTTP client */
- if (transferred == 0) {
- goto L_CLOSE_ERR;
- }
- psGetTime(&t1, NULL);
- if ((rc = matrixSslReceivedData(ssl, (int32)transferred, &buf,
- (uint32*)&len)) < 0) {
- psGetTime(&t2, NULL);
- if (ssl->hsState == SSL_HS_DONE) {
-#ifdef USE_HIGHRES_TIME
- stats->datatime += psDiffUsecs(t1, t2);
-#else
- stats->datatime += psDiffMsecs(t1, t2, NULL);
-#endif
- } else {
-#ifdef USE_HIGHRES_TIME
- stats->hstime += psDiffUsecs(t1, t2);
-#else
- stats->hstime += psDiffMsecs(t1, t2, NULL);
-#endif
- }
- goto L_CLOSE_ERR;
- }
- psGetTime(&t2, NULL);
- if (ssl->hsState == SSL_HS_DONE) {
-#ifdef USE_HIGHRES_TIME
- stats->datatime += psDiffUsecs(t1, t2);
-#else
- stats->datatime += psDiffMsecs(t1, t2, NULL);
-#endif
- } else {
-#ifdef USE_HIGHRES_TIME
- stats->hstime += psDiffUsecs(t1, t2);
-#else
- stats->hstime += psDiffMsecs(t1, t2, NULL);
-#endif
- }
+ if ((len = matrixSslGetReadbuf(ssl, &buf)) <= 0)
+ {
+ goto L_CLOSE_ERR;
+ }
+ if ((transferred = recv(fd, buf, len, 0)) < 0)
+ {
+ goto L_CLOSE_ERR;
+ }
+ if (g_trace)
+ {
+ psTraceBytes("RECV", buf, transferred);
+ }
+ /* If EOF, remote socket closed. But we haven't received the HTTP response
+ so we consider it an error in the case of an HTTP client */
+ if (transferred == 0)
+ {
+ goto L_CLOSE_ERR;
+ }
+ psGetTime(&t1, NULL);
+ if ((rc = matrixSslReceivedData(ssl, (int32) transferred, &buf,
+ (uint32 *) &len)) < 0)
+ {
+ psGetTime(&t2, NULL);
+# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING
+# endif /* USE_EXT_CERTIFICATE_VERIFY_SIGNING */
+ if (ssl->hsState == SSL_HS_DONE)
+ {
+# ifdef USE_HIGHRES_TIME
+ stats->datatime += psDiffUsecs(t1, t2);
+# else
+ stats->datatime += psDiffMsecs(t1, t2, NULL);
+# endif
+ }
+ else
+ {
+# ifdef USE_HIGHRES_TIME
+ stats->hstime += psDiffUsecs(t1, t2);
+# else
+ stats->hstime += psDiffMsecs(t1, t2, NULL);
+# endif
+ }
+ goto L_CLOSE_ERR;
+ }
+ psGetTime(&t2, NULL);
+ if (ssl->hsState == SSL_HS_DONE)
+ {
+# ifdef USE_HIGHRES_TIME
+ stats->datatime += psDiffUsecs(t1, t2);
+# else
+ stats->datatime += psDiffMsecs(t1, t2, NULL);
+# endif
+ }
+ else
+ {
+# ifdef USE_HIGHRES_TIME
+ stats->hstime += psDiffUsecs(t1, t2);
+# else
+ stats->hstime += psDiffMsecs(t1, t2, NULL);
+# endif
+ }
PROCESS_MORE:
- switch (rc) {
- case MATRIXSSL_HANDSHAKE_COMPLETE:
-#ifdef REHANDSHAKE_TEST
+ switch (rc)
+ {
+ case MATRIXSSL_HANDSHAKE_COMPLETE:
+# ifdef REHANDSHAKE_TEST
/*
- Test rehandshake capabilities of server. A full re-handshake
- is first tested. After that, a session resmption rehandshake
- is attempted. In that case, this client will be last to
- send handshake data and MATRIXSSL_HANDSHAKE_COMPLETE will hit on
- the WRITE_MORE handler and httpWriteRequest will occur there.
+ Test rehandshake capabilities of server. A full re-handshake
+ is first tested. After that, a session resmption rehandshake
+ is attempted. In that case, this client will be last to
+ send handshake data and MATRIXSSL_HANDSHAKE_COMPLETE will hit on
+ the WRITE_MORE handler and httpWriteRequest will occur there.
- NOTE: If the server doesn't support session resumption it is
- possible to fall into an endless rehandshake loop
-*/
- if (g_rehandshakeFlag == 0) {
- /* Full rehandshake */
- if (matrixSslEncodeRehandshake(ssl, NULL, NULL,
- SSL_OPTION_FULL_HANDSHAKE, g_cipher, g_ciphers) < 0) {
- goto L_CLOSE_ERR;
- }
- g_rehandshakeFlag = 1;
- } else if (g_rehandshakeFlag == 1) {
- /* Resumed rehandshake */
- if (matrixSslEncodeRehandshake(ssl, NULL, NULL, 0,
- g_cipher, g_ciphers) < 0) {
- goto L_CLOSE_ERR;
- }
- g_rehandshakeFlag = 2;
- } else {
- if ((rc = httpWriteRequest(ssl)) < 0) {
- goto L_CLOSE_ERR;
- }
- if (rc != MATRIXSSL_REQUEST_SEND) {
- closeConn(ssl, fd);
- return MATRIXSSL_SUCCESS;
- }
- }
- goto WRITE_MORE;
-#else
- /* We got the Finished SSL message, initiate the HTTP req */
- if ((rc = httpWriteRequest(ssl)) < 0) {
- goto L_CLOSE_ERR;
- }
- if (rc == MATRIXSSL_REQUEST_SEND) {
- /* We have a HTTP request to send */
- goto WRITE_MORE;
- }
- closeConn(ssl, fd);
- return MATRIXSSL_SUCCESS;
-#endif
- case MATRIXSSL_APP_DATA:
- case MATRIXSSL_APP_DATA_COMPRESSED:
- if (g_trace) psTraceBytes("Decrypted app data", buf, len);
- if (cp.flags != HTTPS_COMPLETE) {
- rc = httpBasicParse(&cp, buf, len, g_trace);
- if (rc < 0) {
- closeConn(ssl, fd);
- if (cp.parsebuf) free(cp.parsebuf); cp.parsebuf = NULL;
- cp.parsebuflen = 0;
- return MATRIXSSL_ERROR;
- }
- if (rc == HTTPS_COMPLETE) {
- cp.flags = HTTPS_COMPLETE;
- }
- }
- cp.bytes_received += len;
- stats->rbytes += len;
- if (g_trace) {
- psTraceBytes("HTTP DATA", buf, len);
- }
- rc = matrixSslProcessedData(ssl, &buf, (uint32*)&len);
- if (rc < 0) {
- goto L_CLOSE_ERR;
- }
- if (g_bytes_requested > 0) {
- if (cp.bytes_received >= g_bytes_requested) {
- /* We've received all that was requested, so close */
- closeConn(ssl, fd);
- if (cp.parsebuf) free(cp.parsebuf); cp.parsebuf = NULL;
- cp.parsebuflen = 0;
- return MATRIXSSL_SUCCESS;
- }
- if (rc == 0) {
- /* We processed a partial HTTP message */
- goto READ_MORE;
- }
- }
- goto PROCESS_MORE;
- case MATRIXSSL_REQUEST_SEND:
- goto WRITE_MORE;
- case MATRIXSSL_REQUEST_RECV:
- goto READ_MORE;
- case MATRIXSSL_RECEIVED_ALERT:
- /* The first byte of the buffer is the level */
- /* The second byte is the description */
- if (*buf == SSL_ALERT_LEVEL_FATAL) {
- psTraceIntInfo("Fatal alert: %d, closing connection.\n",
- *(buf + 1));
- goto L_CLOSE_ERR;
- }
- /* Closure alert is normal (and best) way to close */
- if (*(buf + 1) == SSL_ALERT_CLOSE_NOTIFY) {
- closeConn(ssl, fd);
- if (cp.parsebuf) free(cp.parsebuf); cp.parsebuf = NULL;
- cp.parsebuflen = 0;
- return MATRIXSSL_SUCCESS;
- }
- psTraceIntInfo("Warning alert: %d\n", *(buf + 1));
- if ((rc = matrixSslProcessedData(ssl, &buf, (uint32*)&len)) == 0) {
- /* No more data in buffer. Might as well read for more. */
- goto READ_MORE;
- }
- goto PROCESS_MORE;
- default:
- /* If rc <= 0 we fall here */
- goto L_CLOSE_ERR;
- }
+ NOTE: If the server doesn't support session resumption it is
+ possible to fall into an endless rehandshake loop
+ */
+ if (g_rehandshakeFlag == 0)
+ {
+ /* Full rehandshake */
+ if (matrixSslEncodeRehandshake(ssl, NULL, NULL,
+ SSL_OPTION_FULL_HANDSHAKE, g_cipher, g_ciphers) < 0)
+ {
+ goto L_CLOSE_ERR;
+ }
+ g_rehandshakeFlag = 1;
+ }
+ else if (g_rehandshakeFlag == 1)
+ {
+ /* Resumed rehandshake */
+ if (matrixSslEncodeRehandshake(ssl, NULL, NULL, 0,
+ g_cipher, g_ciphers) < 0)
+ {
+ goto L_CLOSE_ERR;
+ }
+ g_rehandshakeFlag = 2;
+ }
+ else
+ {
+ if ((rc = httpWriteRequest(ssl)) < 0)
+ {
+ goto L_CLOSE_ERR;
+ }
+ if (rc != MATRIXSSL_REQUEST_SEND)
+ {
+ closeConn(ssl, fd);
+ return MATRIXSSL_SUCCESS;
+ }
+ }
+ goto WRITE_MORE;
+# else
+ /* We got the Finished SSL message, initiate the HTTP req */
+ if ((rc = httpWriteRequest(ssl)) < 0)
+ {
+ goto L_CLOSE_ERR;
+ }
+ if (rc == MATRIXSSL_REQUEST_SEND)
+ {
+ /* We have a HTTP request to send */
+ goto WRITE_MORE;
+ }
+# ifdef TEST_KEEP_PEER_CERTS
+ if (ssl->sec.cert == NULL)
+ {
+ printf("Error: peer cert not kept\n");
+ return MATRIXSSL_ERROR;
+ }
+ else
+ {
+ printf("OK: peer cert still available\n");
+ }
+ if (ssl->sec.cert->unparsedBin == NULL ||
+ ssl->sec.cert->binLen <= 0)
+ {
+ printf("Error: peer cert DER not kept\n");
+ return MATRIXSSL_ERROR;
+ }
+ else
+ {
+ printf("OK: peer cert DER still available\n");
+ }
+# endif
+ closeConn(ssl, fd);
+ return MATRIXSSL_SUCCESS;
+# endif
+ case MATRIXSSL_APP_DATA:
+ case MATRIXSSL_APP_DATA_COMPRESSED:
+ if (g_trace)
+ {
+ psTraceBytes("Decrypted app data", buf, len);
+ }
+ if (cp.flags != HTTPS_COMPLETE)
+ {
+ rc = httpBasicParse(&cp, buf, len, g_trace);
+ if (rc < 0)
+ {
+ closeConn(ssl, fd);
+ if (cp.parsebuf)
+ {
+ free(cp.parsebuf);
+ }
+ cp.parsebuf = NULL;
+ cp.parsebuflen = 0;
+ return MATRIXSSL_ERROR;
+ }
+ if (rc == HTTPS_COMPLETE)
+ {
+ cp.flags = HTTPS_COMPLETE;
+ }
+ }
+ cp.bytes_received += len;
+ stats->rbytes += len;
+ if (g_trace)
+ {
+ psTraceBytes("HTTP DATA", buf, len);
+ }
+ rc = matrixSslProcessedData(ssl, &buf, (uint32 *) &len);
+ if (rc < 0)
+ {
+ goto L_CLOSE_ERR;
+ }
+ if (g_bytes_requested > 0)
+ {
+ if (cp.bytes_received >= g_bytes_requested)
+ {
+ /* We've received all that was requested, so close */
+ closeConn(ssl, fd);
+ if (cp.parsebuf)
+ {
+ free(cp.parsebuf);
+ }
+ cp.parsebuf = NULL;
+ cp.parsebuflen = 0;
+ return MATRIXSSL_SUCCESS;
+ }
+ if (rc == 0)
+ {
+ /* We processed a partial HTTP message */
+ goto READ_MORE;
+ }
+ }
+ goto PROCESS_MORE;
+ case MATRIXSSL_REQUEST_SEND:
+ goto WRITE_MORE;
+ case MATRIXSSL_REQUEST_RECV:
+ goto READ_MORE;
+ case MATRIXSSL_RECEIVED_ALERT:
+ /* The first byte of the buffer is the level */
+ /* The second byte is the description */
+ if (*buf == SSL_ALERT_LEVEL_FATAL)
+ {
+ psTraceIntInfo("Fatal alert: %d, closing connection.\n",
+ *(buf + 1));
+ goto L_CLOSE_ERR;
+ }
+ /* Closure alert is normal (and best) way to close */
+ if (*(buf + 1) == SSL_ALERT_CLOSE_NOTIFY)
+ {
+ closeConn(ssl, fd);
+ if (cp.parsebuf)
+ {
+ free(cp.parsebuf);
+ }
+ cp.parsebuf = NULL;
+ cp.parsebuflen = 0;
+ return MATRIXSSL_SUCCESS;
+ }
+ psTraceIntInfo("Warning alert: %d\n", *(buf + 1));
+ if ((rc = matrixSslProcessedData(ssl, &buf, (uint32 *) &len)) == 0)
+ {
+ /* No more data in buffer. Might as well read for more. */
+ goto READ_MORE;
+ }
+ goto PROCESS_MORE;
+ default:
+ /* If rc <= 0 we fall here */
+ goto L_CLOSE_ERR;
+ }
L_CLOSE_ERR:
- if (cp.flags != HTTPS_COMPLETE) {
- _psTrace("FAIL: No HTTP Response\n");
- } else {
+ if (cp.flags != HTTPS_COMPLETE)
+ {
+ _psTrace("FAIL: No HTTP Response\n");
+ }
+ else
+ {
/*
- printf("Received %d bytes %d usecs, state %d\n",
- stats->rbytes, (int)stats->hstime, (int)stats->datatime,
- ssl->hsState);
-*/
- }
- matrixSslDeleteSession(ssl);
- if (g_keepalive == 0) {
- close(fd);
- }
- if (cp.parsebuf) free(cp.parsebuf); cp.parsebuf = NULL;
- cp.parsebuflen = 0;
- return rc;
+ printf("Received %d bytes %d usecs, state %d\n",
+ stats->rbytes, (int)stats->hstime, (int)stats->datatime,
+ ssl->hsState);
+ */
+ }
+ matrixSslDeleteSession(ssl);
+ if (g_keepalive == 0)
+ {
+ close(fd);
+ }
+ if (cp.parsebuf)
+ {
+ free(cp.parsebuf);
+ }
+ cp.parsebuf = NULL;
+ cp.parsebuflen = 0;
+ return rc;
}
/******************************************************************************/
/*
- Create an HTTP request and encode it to the SSL buffer
+ Create an HTTP request and encode it to the SSL buffer
*/
static int32 httpWriteRequest(ssl_t *ssl)
{
- unsigned char *buf;
- int32 available, requested;
+ unsigned char *buf;
+ int32 available, requested;
- /* If we don't have a path defined and are sending zero bytes, skip http */
- if (g_bytes_requested == 0 && *g_path == '\0') {
- return PS_SUCCESS;
- }
+ /* If we don't have a path defined and are sending zero bytes, skip http */
+ if (g_bytes_requested == 0 && *g_path == '\0')
+ {
+ return PS_SUCCESS;
+ }
- if (g_closeServer) {
- /* A value of 0 to the 'new' connections is the key to sending the
- server a shutdown message */
- requested = strlen((char *)g_matrixShutdownServer) + 1;
- if ((available = matrixSslGetWritebuf(ssl, &buf, requested)) < 0) {
- return PS_MEM_FAIL;
- }
- if (available < requested) {
- return PS_FAILURE;
- }
- memset(buf, 0x0, requested); /* So strlen will work below */
- strncpy((char *)buf, (char *)g_matrixShutdownServer,
- (uint32)strlen((char *)g_matrixShutdownServer));
- if (matrixSslEncodeWritebuf(ssl, (uint32)strlen((char *)buf)) < 0) {
- return PS_MEM_FAIL;
- }
- return MATRIXSSL_REQUEST_SEND;
- }
+ if (g_closeServer)
+ {
+ /* A value of 0 to the 'new' connections is the key to sending the
+ server a shutdown message */
+ requested = strlen((char *) g_matrixShutdownServer) + 1;
+ if ((available = matrixSslGetWritebuf(ssl, &buf, requested)) < 0)
+ {
+ return PS_MEM_FAIL;
+ }
+ if (available < requested)
+ {
+ return PS_FAILURE;
+ }
+ memset(buf, 0x0, requested); /* So strlen will work below */
+ strncpy((char *) buf, (char *) g_matrixShutdownServer,
+ (uint32) strlen((char *) g_matrixShutdownServer));
+ if (matrixSslEncodeWritebuf(ssl, (uint32) strlen((char *) buf)) < 0)
+ {
+ return PS_MEM_FAIL;
+ }
+ return MATRIXSSL_REQUEST_SEND;
+ }
- requested = strlen((char *)g_httpRequestHdr) + strlen(g_path) + 1;
- if ((available = matrixSslGetWritebuf(ssl, &buf, requested)) < 0) {
- return PS_MEM_FAIL;
- }
- requested = min(requested, available);
- snprintf((char *)buf, requested, (char *)g_httpRequestHdr, g_path);
+ requested = strlen((char *) g_httpRequestHdr) + strlen(g_path) + 1;
+ if ((available = matrixSslGetWritebuf(ssl, &buf, requested)) < 0)
+ {
+ return PS_MEM_FAIL;
+ }
+ requested = min(requested, available);
+ snprintf((char *) buf, requested, (char *) g_httpRequestHdr, g_path);
- if (g_trace) _psTraceStr("SEND: [%s]\n", (char*)buf);
- if (matrixSslEncodeWritebuf(ssl, strlen((char *)buf)) < 0) {
- return PS_MEM_FAIL;
- }
- return MATRIXSSL_REQUEST_SEND;
+ if (g_trace)
+ {
+ _psTraceStr("SEND: [%s]\n", (char *) buf);
+ }
+ if (matrixSslEncodeWritebuf(ssl, strlen((char *) buf)) < 0)
+ {
+ return PS_MEM_FAIL;
+ }
+ return MATRIXSSL_REQUEST_SEND;
}
-#ifdef ID_RSA
-#ifdef USE_HEADER_KEYS
+# ifdef ID_RSA
+# ifdef USE_HEADER_KEYS
static int32 loadRsaKeys(uint32 key_len, sslKeys_t *keys,
- unsigned char *CAstream, int32 CAstreamLen)
+ unsigned char *CAstream, int32 CAstreamLen)
{
- int32 rc;
+ int32 rc;
+ const unsigned char *key_buf = NULL;
+ const unsigned char *cert_buf = NULL;
+ int32 key_buf_len = 0;
+ int32 cert_buf_len = 0;
- if (key_len == 1024) {
- _psTrace("Using 1024 bit RSA private key\n");
- rc = matrixSslLoadRsaKeysMem(keys, RSA1024, sizeof(RSA1024),
- RSA1024KEY, sizeof(RSA1024KEY), CAstream, CAstreamLen);
- } else if (key_len == 2048) {
- _psTrace("Using 2048 bit RSA private key\n");
- rc = matrixSslLoadRsaKeysMem(keys, RSA2048, sizeof(RSA2048),
- RSA2048KEY, sizeof(RSA2048KEY), CAstream, CAstreamLen);
- } else if (key_len == 4096) {
- _psTrace("Using 4096 bit RSA private key\n");
- rc = matrixSslLoadRsaKeysMem(keys, RSA4096, sizeof(RSA4096),
- RSA4096KEY, sizeof(RSA4096KEY), CAstream, CAstreamLen);
- } else {
- rc = -1;
- psAssert((key_len == 1024) || (key_len == 2048) || (key_len == 4096));
- }
+ if (key_len == 1024)
+ {
+ _psTrace("Using 1024 bit RSA private key\n");
+ cert_buf = RSA1024;
+ cert_buf_len = sizeof(RSA1024);
+ key_buf = RSA1024KEY;
+ key_buf_len = sizeof(RSA1024KEY);
+ }
+ else if (key_len == 2048)
+ {
+ _psTrace("Using 2048 bit RSA private key\n");
+ cert_buf = RSA2048;
+ cert_buf_len = sizeof(RSA2048);
+ key_buf = RSA2048KEY;
+ key_buf_len = sizeof(RSA2048KEY);
+ }
+ else if (key_len == 3072)
+ {
+ _psTrace("Using 3072 bit RSA private key\n");
+ cert_buf = RSA3072;
+ cert_buf_len = sizeof(RSA3072);
+ key_buf = RSA3072KEY;
+ key_buf_len = sizeof(RSA3072KEY);
+ }
+ else if (key_len == 4096)
+ {
+ _psTrace("Using 4096 bit RSA private key\n");
+ cert_buf = RSA4096;
+ cert_buf_len = sizeof(RSA4096);
+ key_buf = RSA4096KEY;
+ key_buf_len = sizeof(RSA4096KEY);
+ }
+ else
+ {
+ _psTraceInt("Unsupported RSA private key size: %u\n", key_len);
+ return PS_FAILURE;
+ }
- if (rc < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- if (CAstream) {
- psFree(CAstream, NULL);
- }
- matrixSslDeleteKeys(keys);
- matrixSslClose();
- }
+ if (g_enable_ext_cv_sig_op)
+ {
+ key_buf = NULL;
+ key_buf_len = 0;
+ }
- return rc;
+ rc = matrixSslLoadRsaKeysMem(keys, cert_buf, cert_buf_len,
+ key_buf, key_buf_len, CAstream, CAstreamLen);
+
+ if (rc < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ if (CAstream)
+ {
+ psFree(CAstream, NULL);
+ }
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ }
+
+ return rc;
}
-#endif
-#endif
+# endif /* USE_HEADER_KEYS */
+# endif /* ID_RSA */
static void usage(void)
{
- printf(
- "\nusage: client { options }\n"
- "\n"
- "Options can be one or more of the following:\n"
- "\n"
- "-a - Disable sending closure alerts\n"
- "-b - Client request size\n"
- " Generates an HTTPS request after TLS negotiation\n"
- " Uses URL path of '/bytes?'\n"
- " Mutually exclusive with '-u' flag\n"
- "-c - Comma separated list of ciphers numbers\n"
- " - Example cipher numbers:\n"
- " - '53' TLS_RSA_WITH_AES_256_CBC_SHA\n"
- " - '47' TLS_RSA_WITH_AES_128_CBC_SHA\n"
- " - '10' SSL_RSA_WITH_3DES_EDE_CBC_SHA\n"
- " - '5' SSL_RSA_WITH_RC4_128_SHA\n"
- " - '4' SSL_RSA_WITH_RC4_128_MD5\n"
- "-d - Disable server certicate name/addr chk\n"
- "-h - Help, print usage and exit\n"
- "-k - RSA keyLen\n"
- " - Must be one of 1024, 2048 or 4096\n"
- "-K - Keepalive (Re-use socket after TLS session close)\n"
- "-n - Num of new (full handshake) sessions\n"
- " - Default 1\n"
- "-p - Port number for SSL/TLS server\n"
- " - Default 4433 (HTTPS is 443)\n"
- "-r - Num of resumed SSL/TLS sesssions\n"
- " - Default 0\n"
- "-s - IP address of server machine/interface\n"
- " - Default 127.0.0.1 (localhost)\n"
- "-u - URL path, eg. '/index.html'\n"
- " Generates an HTTPS request after TLS negotiation\n"
- " Mutually exclusive with '-b' flag\n"
- "-V - SSL/TLS version to use\n"
- " - '0' SSL 3.0\n"
- " - '1' TLS 1.0\n"
- " - '2' TLS 1.1\n"
- " - '3' TLS 1.2 (default)\n"
- "\n");
+ printf(
+ "\nusage: client { options }\n"
+ "\n"
+ "Options can be one or more of the following:\n"
+ "\n"
+ "-a - Disable sending closure alerts\n"
+ "-b - Client request size\n"
+ " Generates an HTTPS request after TLS negotiation\n"
+ " Uses URL path of '/bytes?'\n"
+ " Mutually exclusive with '-u' flag\n"
+ "-c - Comma separated list of ciphers numbers\n"
+ " - Example cipher numbers:\n"
+ " - '53' TLS_RSA_WITH_AES_256_CBC_SHA\n"
+ " - '47' TLS_RSA_WITH_AES_128_CBC_SHA\n"
+ " - '10' SSL_RSA_WITH_3DES_EDE_CBC_SHA\n"
+ " - '5' SSL_RSA_WITH_RC4_128_SHA\n"
+ " - '4' SSL_RSA_WITH_RC4_128_MD5\n"
+ "-d - Disable server certicate name/addr chk\n"
+ "-h - Help, print usage and exit\n"
+ "-k - RSA keyLen\n"
+ " - Must be one of 1024, 2048 or 4096\n"
+ "-K - Keepalive (Re-use socket after TLS session close)\n"
+ "-n - Num of new (full handshake) sessions\n"
+ " - Default 1\n"
+ "-p - Port number for SSL/TLS server\n"
+ " - Default 4433 (HTTPS is 443)\n"
+ "-r - Num of resumed SSL/TLS sesssions\n"
+ " - Default 0\n"
+ "-s - IP address of server machine/interface\n"
+ " - Default 127.0.0.1 (localhost)\n"
+ "-u - URL path, eg. '/index.html'\n"
+ " Generates an HTTPS request after TLS negotiation\n"
+ " Mutually exclusive with '-b' flag\n"
+ "-V - SSL/TLS version to use\n"
+ " - '0' SSL 3.0\n"
+ " - '1' TLS 1.0\n"
+ " - '2' TLS 1.1\n"
+ " - '3' TLS 1.2 (default)\n"
+ "\n");
}
/* Returns number of cipher numbers found, or -1 if an error. */
-#include
-static int32_t parse_cipher_list(char *cipherListString,
- uint16_t cipher_array[], uint8_t size_of_cipher_array)
+# include
+static int32_t parse_cipher_list(char *cipherListString,
+ psCipher16_t cipher_array[], uint8_t size_of_cipher_array)
{
- uint32 numCiphers, cipher;
- char *endPtr;
+ uint32 numCiphers, cipher;
+ char *endPtr;
- /* Convert the cipherListString into an array of cipher numbers. */
- numCiphers = 0;
- while (cipherListString != NULL) {
- cipher = strtol(cipherListString, &endPtr, 10);
- if (endPtr == cipherListString) {
- printf("The remaining cipherList has no cipher numbers - '%s'\n",
- cipherListString);
- return -1;
- } else if (size_of_cipher_array <= numCiphers) {
- printf("Too many cipher numbers supplied. limit is %d\n",
- size_of_cipher_array);
- return -1;
- }
- cipher_array[numCiphers++] = cipher;
- while (*endPtr != '\0' && !isdigit(*endPtr)) {
- endPtr++;
- }
- cipherListString = endPtr;
- if (*endPtr == '\0') {
- break;
- }
- }
+ /* Convert the cipherListString into an array of cipher numbers. */
+ numCiphers = 0;
+ while (cipherListString != NULL)
+ {
+ cipher = strtol(cipherListString, &endPtr, 10);
+ if (endPtr == cipherListString)
+ {
+ printf("The remaining cipherList has no cipher numbers - '%s'\n",
+ cipherListString);
+ return -1;
+ }
+ else if (size_of_cipher_array <= numCiphers)
+ {
+ printf("Too many cipher numbers supplied. limit is %d\n",
+ size_of_cipher_array);
+ return -1;
+ }
+ cipher_array[numCiphers++] = cipher;
+ while (*endPtr != '\0' && !isdigit(*endPtr))
+ {
+ endPtr++;
+ }
+ cipherListString = endPtr;
+ if (*endPtr == '\0')
+ {
+ break;
+ }
+ }
- return numCiphers;
+ return numCiphers;
}
/* Return 0 on good set of cmd options, return -1 if a bad cmd option is
encountered OR a request for help is seen (i.e. '-h' option). */
static int32 process_cmd_options(int32 argc, char **argv)
{
- int optionChar, key_len, version, numCiphers;
- char *cipherListString;
+ int optionChar, key_len, version, numCiphers;
+ char *cipherListString;
- // Set some default options:
- memset(g_cipher, 0, sizeof(g_cipher));
- memset(g_ip, 0, sizeof(g_ip));
- memset(g_path, 0, sizeof(g_path));
+ /* Set some default options: */
+ memset(g_cipher, 0, sizeof(g_cipher));
+ memset(g_ip, 0, sizeof(g_ip));
+ memset(g_path, 0, sizeof(g_path));
- strcpy(g_ip, "127.0.0.1");
- g_bytes_requested = 0;
- g_send_closure_alert = 1;
- g_ciphers = 0;
- g_cipher[0] = 0;
- g_disableCertNameChk = 0;
- g_key_len = 1024;
- g_new = 1;
- g_port = 4433;
- g_resumed = 0;
- g_version = 3;
- g_keepalive = 0;
+ strcpy(g_ip, "127.0.0.1");
+ g_bytes_requested = 0;
+ g_send_closure_alert = 1;
+ g_ciphers = 0;
+ g_cipher[0] = 0;
+ g_disableCertNameChk = 0;
+ g_key_len = 1024;
+ g_new = 1;
+ g_port = 4433;
+ g_resumed = 0;
+ g_version = 3;
+ g_keepalive = 0;
- opterr = 0;
- while ((optionChar = getopt(argc, argv, "ab:c:dhk:Kn:p:r:s:u:V:")) != -1)
- {
- switch (optionChar)
- {
- case 'h':
- return -1;
+ opterr = 0;
+ while ((optionChar = getopt(argc, argv, "ab:c:dhk:Km:n:p:r:s:u:V:e:")) != -1)
+ {
+ switch (optionChar)
+ {
+ case 'h':
+ return -1;
- case 'a':
- g_send_closure_alert = 0;
- break;
+ case 'a':
+ g_send_closure_alert = 0;
+ break;
- case 'b':
- if (*g_path) {
- printf("-b and -u options cannot both be provided\n");
- return -1;
- }
- g_bytes_requested = atoi(optarg);
- snprintf(g_path, sizeof(g_path), "/bytes?%u", g_bytes_requested);
- break;
+ case 'b':
+ if (*g_path)
+ {
+ printf("-b and -u options cannot both be provided\n");
+ return -1;
+ }
+ g_bytes_requested = atoi(optarg);
+ snprintf(g_path, sizeof(g_path), "/bytes?%u", g_bytes_requested);
+ break;
- case 'c':
- // Convert the cipherListString into an array of cipher numbers.
- cipherListString = optarg;
- numCiphers = parse_cipher_list(cipherListString, g_cipher, 16);
- if (numCiphers <= 0) {
- return -1;
- }
- g_ciphers = numCiphers;
- break;
+ case 'c':
+ /* Convert the cipherListString into an array of cipher numbers. */
+ cipherListString = optarg;
+ numCiphers = parse_cipher_list(cipherListString, g_cipher, 16);
+ if (numCiphers <= 0)
+ {
+ return -1;
+ }
+ g_ciphers = numCiphers;
+ break;
- case 'd':
- g_disableCertNameChk = 1;
- break;
+ case 'd':
+ g_disableCertNameChk = 1;
+ break;
- case 'k':
- key_len = atoi(optarg);
- if ((key_len != 1024) && (key_len != 2048) && (key_len != 4096)) {
- printf("-k option must be followed by a key_len whose value "
- " must be 1024, 2048 or 4096\n");
- return -1;
- }
- g_key_len = key_len;
- break;
+ case 'e':
+ printf("-e option only supported when USE_EXT_CERTIFICATE_VERIFY_SIGNING " \
+ "and USE_EXT_EXAMPLE_MODULE are defined\n");
+ return -1;
+ break;
- case 'K':
- g_keepalive = 1;
- break;
+ case 'k':
+ key_len = atoi(optarg);
+ if ((key_len != 1024) && (key_len != 2048)
+ && (key_len != 3072) && (key_len != 4096))
+ {
+ printf("-k option must be followed by a key_len whose value "
+ " must be 1024, 2048, 3072 or 4096\n");
+ return -1;
+ }
+ g_key_len = key_len;
+ break;
- case 'n':
- g_new = atoi(optarg);
- break;
+ case 'K':
+ g_keepalive = 1;
+ break;
- case 'p':
- g_port = atoi(optarg);
- break;
+ case 'm':
+ g_max_verify_depth = atoi(optarg);
+ break;
- case 'r':
- g_resumed = atoi(optarg);
- break;
+ case 'n':
+ g_new = atoi(optarg);
+ break;
- case 's':
- strncpy(g_ip, optarg, 15);
- break;
+ case 'p':
+ g_port = atoi(optarg);
+ break;
- case 'u':
- if (*g_path) {
- printf("-b and -u options cannot both be provided\n");
- return -1;
- }
- strncpy(g_path, optarg, sizeof(g_path) - 1);
- g_bytes_requested = 0;
- break;
+ case 'r':
+ g_resumed = atoi(optarg);
+ break;
- case 'V':
- version = atoi(optarg);
- if (version < 0 || version > 3) {
- printf("Invalid version: %d\n", version);
- return -1;
- }
- g_version = version;
- break;
- }
- }
+ case 's':
+ strncpy(g_ip, optarg, 15);
+ break;
- return 0;
+ case 'u':
+ if (*g_path)
+ {
+ printf("-b and -u options cannot both be provided\n");
+ return -1;
+ }
+ strncpy(g_path, optarg, sizeof(g_path) - 1);
+ g_bytes_requested = 0;
+ break;
+
+ case 'V':
+ version = atoi(optarg);
+ if (version < 0 || version > 3)
+ {
+ printf("Invalid version: %d\n", version);
+ return -1;
+ }
+ g_version = version;
+ break;
+ }
+ }
+
+ return 0;
}
/******************************************************************************/
/*
- Main routine. Initialize SSL keys and structures, and make two SSL
- connections, the first with a blank session Id, and the second with
- a session ID populated during the first connection to do a much faster
- session resumption connection the second time.
+ Main routine. Initialize SSL keys and structures, and make two SSL
+ connections, the first with a blank session Id, and the second with
+ a session ID populated during the first connection to do a much faster
+ session resumption connection the second time.
*/
int32 main(int32 argc, char **argv)
{
- int32 rc, CAstreamLen, i, exit_code;
- sslKeys_t *keys;
- sslSessionId_t *sid = NULL;
- struct g_sslstats stats;
- unsigned char *CAstream;
-#ifdef WIN32
- WSADATA wsaData;
- WSAStartup(MAKEWORD(1, 1), &wsaData);
-#endif
+ int32 rc, CAstreamLen, i, exit_code;
+ sslKeys_t *keys;
+ sslSessionId_t *sid = NULL;
+ struct g_sslstats stats;
+ unsigned char *CAstream;
- exit_code = 0;
+# if defined(USE_HEADER_KEYS) && !defined(ID_RSA)
+ const unsigned char *key_buf;
+ int32 key_buf_len;
+# endif /* USE_HEADER_KEYS && !ID_RSA */
+# ifndef USE_HEADER_KEYS
+ unsigned char *tmp_buf;
+ int32 tmp_buf_len;
+# endif /* USE_HEADER_KEYS */
+# ifdef WIN32
+ WSADATA wsaData;
+ WSAStartup(MAKEWORD(1, 1), &wsaData);
+# endif
- if ((rc = matrixSslOpen()) < 0) {
- _psTrace("MatrixSSL library init failure. Exiting\n");
- return EXIT_FAILURE;
- }
-
- if (matrixSslNewKeys(&keys, NULL) < 0) {
- _psTrace("MatrixSSL library key init failure. Exiting\n");
- return EXIT_FAILURE;
- }
-
- if (0 != process_cmd_options(argc, argv)) {
- usage();
- return 0;
- }
+ exit_code = 0;
- if (g_new <= 1 && g_resumed <= 1) {
- g_trace = 1;
- } else {
- g_trace = 0;
- }
+ if ((rc = matrixSslOpen()) < 0)
+ {
+ _psTrace("MatrixSSL library init failure. Exiting\n");
+ return EXIT_FAILURE;
+ }
- if (g_bytes_requested == 0 && *g_path == '\0') {
- printf("client %s:%d "
- "new:%d resumed:%d keylen:%d nciphers:%d version:%s\n",
- g_ip, g_port, g_new, g_resumed, g_key_len,
- g_ciphers, g_strver[g_version]);
- } else {
- printf("client https://%s:%d%s "
- "new:%d resumed:%d keylen:%d nciphers:%d version:%s\n",
- g_ip, g_port, g_path, g_new, g_resumed, g_key_len,
- g_ciphers, g_strver[g_version]);
- }
+ if (matrixSslNewKeys(&keys, NULL) < 0)
+ {
+ _psTrace("MatrixSSL library key init failure. Exiting\n");
+ return EXIT_FAILURE;
+ }
-#ifndef USE_ONLY_PSK_CIPHER_SUITE
-#ifdef USE_HEADER_KEYS
+ if (0 != process_cmd_options(argc, argv))
+ {
+ usage();
+ return 0;
+ }
+
+ if (g_new <= 1 && g_resumed <= 1)
+ {
+ g_trace = 1;
+ }
+ else
+ {
+ g_trace = 0;
+ }
+
+ if (g_bytes_requested == 0 && *g_path == '\0')
+ {
+ printf("client %s:%d "
+ "new:%d resumed:%d keylen:%d nciphers:%d version:%s\n",
+ g_ip, g_port, g_new, g_resumed, g_key_len,
+ g_ciphers, g_strver[g_version]);
+ }
+ else
+ {
+ printf("client https://%s:%d%s "
+ "new:%d resumed:%d keylen:%d nciphers:%d version:%s\n",
+ g_ip, g_port, g_path, g_new, g_resumed, g_key_len,
+ g_ciphers, g_strver[g_version]);
+ }
+
+# ifndef USE_ONLY_PSK_CIPHER_SUITE
+# ifdef USE_HEADER_KEYS
/*
- In-memory based keys
- Build the CA list first for potential client auth usage
-*/
- CAstreamLen = 0;
-#ifdef USE_RSA_CIPHER_SUITE
- CAstreamLen += sizeof(RSACAS);
-#ifdef USE_ECC_CIPHER_SUITE
- CAstreamLen += sizeof(ECDHRSACAS);
-#endif
-#endif
-#ifdef USE_ECC_CIPHER_SUITE
- CAstreamLen += sizeof(ECCAS);
-#endif
-#if defined(USE_RSA_CIPHER_SUITE) || defined(USE_ECC_CIPHER_SUITE)
- CAstream = psMalloc(NULL, CAstreamLen);
-#else
- CAstream = NULL;
-#endif
+ In-memory based keys
+ Build the CA list first for potential client auth usage
+ */
+ CAstreamLen = 0;
+# ifdef USE_RSA_CIPHER_SUITE
+ CAstreamLen += sizeof(RSACAS);
+# ifdef USE_ECC_CIPHER_SUITE
+ CAstreamLen += sizeof(ECDHRSACAS);
+# endif
+# endif
+# ifdef USE_ECC_CIPHER_SUITE
+ CAstreamLen += sizeof(ECCAS);
+# endif
+# if defined(USE_RSA_CIPHER_SUITE) || defined(USE_ECC_CIPHER_SUITE)
+ CAstream = psMalloc(NULL, CAstreamLen);
+# else
+ CAstream = NULL;
+# endif
- CAstreamLen = 0;
-#ifdef USE_RSA_CIPHER_SUITE
- memcpy(CAstream, RSACAS, sizeof(RSACAS));
- CAstreamLen += sizeof(RSACAS);
-#ifdef USE_ECC_CIPHER_SUITE
- memcpy(CAstream + CAstreamLen, ECDHRSACAS, sizeof(ECDHRSACAS));
- CAstreamLen += sizeof(ECDHRSACAS);
-#endif
-#endif
-#ifdef USE_ECC_CIPHER_SUITE
- memcpy(CAstream + CAstreamLen, ECCAS, sizeof(ECCAS));
- CAstreamLen += sizeof(ECCAS);
-#endif
+ CAstreamLen = 0;
+# ifdef USE_RSA_CIPHER_SUITE
+ memcpy(CAstream, RSACAS, sizeof(RSACAS));
+ CAstreamLen += sizeof(RSACAS);
+# ifdef USE_ECC_CIPHER_SUITE
+ memcpy(CAstream + CAstreamLen, ECDHRSACAS, sizeof(ECDHRSACAS));
+ CAstreamLen += sizeof(ECDHRSACAS);
+# endif
+# endif
+# ifdef USE_ECC_CIPHER_SUITE
+ memcpy(CAstream + CAstreamLen, ECCAS, sizeof(ECCAS));
+ CAstreamLen += sizeof(ECCAS);
+# endif
-#ifdef ID_RSA
- rc = loadRsaKeys(g_key_len, keys, CAstream, CAstreamLen);
- if (rc < 0) {
- return EXIT_FAILURE;
- }
-#endif
+# ifdef ID_RSA
+ rc = loadRsaKeys(g_key_len, keys, CAstream, CAstreamLen);
+ if (rc < 0)
+ {
+ return EXIT_FAILURE;
+ }
+# endif
-#ifdef ID_ECDH_RSA
- if ((rc = matrixSslLoadEcKeysMem(keys, ECDHRSA521, sizeof(ECDHRSA521),
- ECDHRSA521KEY, sizeof(ECDHRSA521KEY), (unsigned char*)CAstream,
- CAstreamLen)) < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- if (CAstream) psFree(CAstream, NULL);
- matrixSslDeleteKeys(keys);
- matrixSslClose();
- return EXIT_FAILURE;
- }
-#endif
+# ifdef ID_ECDH_RSA
+ if (g_enable_ext_cv_sig_op)
+ {
+ key_buf = NULL;
+ key_buf_len = 0;
+ }
+ else
+ {
+ key_buf = ECDHRSA521KEY;
+ key_buf_len = sizeof(ECDHRSA521KEY);
+ }
-#ifdef ID_ECDH_ECDSA
- if ((rc = matrixSslLoadEcKeysMem(keys, EC384, sizeof(EC384),
- EC384KEY, sizeof(EC384KEY), (unsigned char*)CAstream,
- CAstreamLen)) < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- if (CAstream) psFree(CAstream, NULL);
- matrixSslDeleteKeys(keys);
- matrixSslClose();
- return EXIT_FAILURE;
- }
-#endif
+ if ((rc = matrixSslLoadEcKeysMem(keys, ECDHRSA521, sizeof(ECDHRSA521),
+ key_buf, key_buf_len, (unsigned char *) CAstream,
+ CAstreamLen)) < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ if (CAstream)
+ {
+ psFree(CAstream, NULL);
+ }
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ return EXIT_FAILURE;
+ }
+# endif
- if (CAstream) psFree(CAstream, NULL);
+# ifdef ID_ECDH_ECDSA
+ if (g_enable_ext_cv_sig_op)
+ {
+ key_buf = NULL;
+ key_buf_len = 0;
+ }
+ else
+ {
+ key_buf = EC384KEY;
+ key_buf_len = sizeof(EC384KEY);
+ }
-#else
+ if ((rc = matrixSslLoadEcKeysMem(keys, EC384, sizeof(EC384),
+ key_buf, key_buf_len, (unsigned char *) CAstream,
+ CAstreamLen)) < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ if (CAstream)
+ {
+ psFree(CAstream, NULL);
+ }
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ return EXIT_FAILURE;
+ }
+# endif
+
+ if (CAstream)
+ {
+ psFree(CAstream, NULL);
+ }
+
+# else
/*
- File based keys
-*/
- CAstreamLen = 0;
-#ifdef USE_RSA_CIPHER_SUITE
- CAstreamLen += (int32)strlen(rsaCAFile) + 1;
-#ifdef USE_ECC_CIPHER_SUITE
- CAstreamLen += (int32)strlen(ecdhRsaCAFile) + 1;
-#endif
-#endif
-#ifdef USE_ECC_CIPHER_SUITE
- CAstreamLen += (int32)strlen(ecCAFile) + 1;
-#endif
- if (CAstreamLen > 0) {
- CAstream = psMalloc(NULL, CAstreamLen);
- memset(CAstream, 0x0, CAstreamLen);
- } else {
- CAstream = NULL;
- }
+ File based keys
+ */
+ rc = psGetFileBuf(NULL, "testkeys/RSA/2048_RSA.pem", &tmp_buf, &tmp_buf_len);
+ if (rc >= 0)
+ {
+ g_at_matrixssl_root = 1;
+ }
+ else
+ {
+ g_at_matrixssl_root = 0;
+ }
+ psFree(tmp_buf, NULL);
- CAstreamLen = 0;
-#ifdef USE_RSA_CIPHER_SUITE
- memcpy(CAstream, rsaCAFile, strlen(rsaCAFile));
- CAstreamLen += strlen(rsaCAFile);
-#ifdef USE_ECC_CIPHER_SUITE
- memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
- memcpy(CAstream + CAstreamLen, ecdhRsaCAFile, strlen(ecdhRsaCAFile));
- CAstreamLen += strlen(ecdhRsaCAFile);
-#endif
-#endif
-#ifdef USE_ECC_CIPHER_SUITE
- if (CAstreamLen > 0) {
- memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
- }
- memcpy(CAstream + CAstreamLen, ecCAFile, strlen(ecCAFile));
-#endif
+ CAstreamLen = 0;
+# ifdef USE_RSA_CIPHER_SUITE
+ if (g_at_matrixssl_root)
+ {
+ pRsaCAFile += 6;
+ }
+ CAstreamLen += (int32) strlen(pRsaCAFile) + 1;
+# ifdef USE_ECC_CIPHER_SUITE
+ if (g_at_matrixssl_root)
+ {
+ pEcdhRsaCAFile += 6;
+ }
+ CAstreamLen += (int32) strlen(pEcdhRsaCAFile) + 1;
+# endif
+# endif
+# ifdef USE_ECC_CIPHER_SUITE
+ if (g_at_matrixssl_root)
+ {
+ pEcCAFile += 6;
+ }
+ CAstreamLen += (int32) strlen(pEcCAFile) + 1;
+# endif
+ if (CAstreamLen > 0)
+ {
+ CAstream = psMalloc(NULL, CAstreamLen);
+ memset(CAstream, 0x0, CAstreamLen);
+ }
+ else
+ {
+ CAstream = NULL;
+ }
-/* Load Identiy */
-#ifdef EXAMPLE_RSA_KEYS
- if ((rc = matrixSslLoadRsaKeys(keys, rsaCertFile, rsaPrivkeyFile, NULL,
- (char*)CAstream)) < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- if (CAstream) psFree(CAstream, NULL);
- matrixSslDeleteKeys(keys);
- matrixSslClose();
- return EXIT_FAILURE;
- }
-#endif
+ CAstreamLen = 0;
+# ifdef USE_RSA_CIPHER_SUITE
+ memcpy(CAstream, pRsaCAFile, strlen(pRsaCAFile));
+ CAstreamLen += strlen(pRsaCAFile);
+# ifdef USE_ECC_CIPHER_SUITE
+ memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
+ memcpy(CAstream + CAstreamLen, pEcdhRsaCAFile, strlen(pEcdhRsaCAFile));
+ CAstreamLen += strlen(pEcdhRsaCAFile);
+# endif
+# endif
+# ifdef USE_ECC_CIPHER_SUITE
+ if (CAstreamLen > 0)
+ {
+ memcpy(CAstream + CAstreamLen, ";", 1); CAstreamLen++;
+ }
+ memcpy(CAstream + CAstreamLen, pEcCAFile, strlen(pEcCAFile));
+# endif
-#ifdef EXAMPLE_ECDH_RSA_KEYS
- if ((rc = matrixSslLoadEcKeys(keys, ecdhRsaCertFile, ecdhRsaPrivkeyFile,
- NULL, (char*)CAstream)) < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- if (CAstream) psFree(CAstream, NULL);
- matrixSslDeleteKeys(keys);
- matrixSslClose();
- return EXIT_FAILURE;
- }
-#endif
+/* Load Identity */
+# ifdef EXAMPLE_RSA_KEYS
+ if (g_at_matrixssl_root)
+ {
+ pRsaCertFile += 6;
+ pRsaPrivkeyFile += 6;
+ }
+ if (g_enable_ext_cv_sig_op)
+ {
+ pRsaPrivkeyFile = NULL;
+ }
-#ifdef EXAMPLE_EC_KEYS
- if ((rc = matrixSslLoadEcKeys(keys, ecCertFile, ecPrivkeyFile, NULL,
- (char*)CAstream)) < 0) {
- _psTrace("No certificate material loaded. Exiting\n");
- if (CAstream) psFree(CAstream, NULL);
- matrixSslDeleteKeys(keys);
- matrixSslClose();
- return EXIT_FAILURE;
- }
-#endif
+ if ((rc = matrixSslLoadRsaKeys(keys, pRsaCertFile, pRsaPrivkeyFile, NULL,
+ (char *) CAstream)) < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ if (CAstream)
+ {
+ psFree(CAstream, NULL);
+ }
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ return EXIT_FAILURE;
+ }
+# endif /* EXAMPLE_RSA_KEYS */
- if (CAstream) psFree(CAstream, NULL);
-#endif /* USE_HEADER_KEYS */
-#endif /* USE_ONLY_PSK_CIPHER_SUITE */
+# ifdef EXAMPLE_ECDH_RSA_KEYS
+ if (g_at_matrixssl_root)
+ {
+ pEcdhRsaCertFile += 6;
+ pEcdhRsaPrivkeyFile += 6;
+ }
-#ifdef USE_PSK_CIPHER_SUITE
- for (rc = 0; rc < PSK_HEADER_TABLE_COUNT; rc++) {
+ if (g_enable_ext_cv_sig_op)
+ {
+ pEcdhRsaPrivkeyFile = NULL;
+ }
+
+ if ((rc = matrixSslLoadEcKeys(keys, pEcdhRsaCertFile, pEcdhRsaPrivkeyFile,
+ NULL, (char *) CAstream)) < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ if (CAstream)
+ {
+ psFree(CAstream, NULL);
+ }
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ return EXIT_FAILURE;
+ }
+# endif /* EXAMPLE_ECDH_RSA_KEYS */
+
+# ifdef EXAMPLE_EC_KEYS
+ if (g_at_matrixssl_root)
+ {
+ pEcCertFile += 6;
+ pEcPrivkeyFile += 6;
+ }
+
+ if (g_enable_ext_cv_sig_op)
+ {
+ pEcPrivkeyFile = NULL;
+ }
+
+ if ((rc = matrixSslLoadEcKeys(keys, pEcCertFile, pEcPrivkeyFile, NULL,
+ (char *) CAstream)) < 0)
+ {
+ _psTrace("No certificate material loaded. Exiting\n");
+ if (CAstream)
+ {
+ psFree(CAstream, NULL);
+ }
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ return EXIT_FAILURE;
+ }
+# endif /* EXAMPLE_EC_KEYS */
+
+ if (CAstream)
+ {
+ psFree(CAstream, NULL);
+ }
+# endif /* USE_HEADER_KEYS */
+# endif /* USE_ONLY_PSK_CIPHER_SUITE */
+
+# ifdef USE_PSK_CIPHER_SUITE
+ for (rc = 0; rc < PSK_HEADER_TABLE_COUNT; rc++)
+ {
matrixSslLoadPsk(keys,
PSK_HEADER_TABLE[rc].key, sizeof(PSK_HEADER_TABLE[rc].key),
PSK_HEADER_TABLE[rc].id, sizeof(PSK_HEADER_TABLE[rc].id));
}
-#endif /* USE_PSK_CIPHER_SUITE */
+# endif /* USE_PSK_CIPHER_SUITE */
-#ifdef USE_CRL
- /* One initialization step that can be taken is to run through the CA
- files and see if any CRL URL distribution points are present.
- Fetch the CRL and load into the cache if found */
- fetchParseAndAuthCRLfromCert(NULL, keys->CAcerts, keys->CAcerts);
-#endif
+# ifdef USE_CRL
+ /* One initialization step that can be taken is to run through the CA
+ files and see if any CRL URL distribution points are present.
+ Fetch the CRL and load into the cache if found */
+ fetchParseAndAuthCRLfromCert(NULL, keys->CAcerts, keys->CAcerts);
+# endif
- memset(&stats, 0x0, sizeof(struct g_sslstats));
- printf("=== %d new connections ===\n", g_new);
+ memset(&stats, 0x0, sizeof(struct g_sslstats));
+ printf("=== %d new connections ===\n", g_new);
- if (g_new == 0) {
- /* Special case where client is being used to remotely shut down
- the server for automated tests */
- g_closeServer = 1;
- g_bytes_requested = 0; /* Disable data exchange in this case */
- g_new = 1;
- }
+ if (g_new == 0)
+ {
+ /* Special case where client is being used to remotely shut down
+ the server for automated tests */
+ g_closeServer = 1;
+ g_bytes_requested = 0; /* Disable data exchange in this case */
+ g_new = 1;
+ }
- for (i = 0; i < g_new; i++) {
- matrixSslNewSessionId(&sid, NULL);
-#ifdef USE_CRL
-#ifndef MIDHANDSHAKE_CRL_FETCH
- /* This is part of the example for an application that has chosen to
- fail a handshake if the CRL was not available during the first
- attempted connection. In this case, the CRL URL distribution points
- have been saved aside in g_crlDistURLs and now we will go out and
- fetch those CRLs and load them into the library cache so they
- will be available on this next connection attempt. */
- if (g_crlDistURLs[0][0] == 'h') { /* assumption is "http" */
- fetchSavedCRL(keys->CAcerts);
- }
-#endif
-#endif
- rc = httpsClientConnection(keys, sid, &stats);
- if (rc < 0) {
- printf("F %d/%d\n", i, g_new);
- exit_code = EXIT_FAILURE;
- goto out;
- } else {
- printf("N"); fflush(stdout);
- }
- /* Leave the final sessionID for resumed connections */
- if (i + 1 < g_new) matrixSslDeleteSessionId(sid);
- }
- printf("\n");
- if (g_bytes_requested > 0) {
- psAssert(g_bytes_requested * g_new == stats.rbytes);
- }
- printf("%d bytes received\n", stats.rbytes);
-#ifdef USE_HIGHRES_TIME
- printf("%d usec (%d avg usec/conn SSL handshake overhead)\n",
- (int)stats.hstime, (int)(stats.hstime/ g_new));
- printf("%d usec (%d avg usec/conn SSL data overhead)\n",
- (int)stats.datatime, (int)(stats.datatime/ g_new));
-#else
- printf("%d msec (%d avg msec/conn SSL handshake overhead)\n",
- (int)stats.hstime, (int)(stats.hstime/ g_new));
- printf("%d msec (%d avg msec/conn SSL data overhead)\n",
- (int)stats.datatime, (int)(stats.datatime/ g_new));
-#endif
+ for (i = 0; i < g_new; i++)
+ {
+ matrixSslNewSessionId(&sid, NULL);
+# ifdef USE_CRL
+# ifndef MIDHANDSHAKE_CRL_FETCH
+ /* This is part of the example for an application that has chosen to
+ fail a handshake if the CRL was not available during the first
+ attempted connection. In this case, the CRL URL distribution points
+ have been saved aside in g_crlDistURLs and now we will go out and
+ fetch those CRLs and load them into the library cache so they
+ will be available on this next connection attempt. */
+ if (g_crlDistURLs[0][0] == 'h') /* assumption is "http" */
+ {
+ fetchSavedCRL(keys->CAcerts);
+ }
+# endif
+# endif
+ rc = httpsClientConnection(keys, sid, &stats);
+ if (rc < 0)
+ {
+ printf("F %d/%d\n", i, g_new);
+ exit_code = EXIT_FAILURE;
+ goto out;
+ }
+ else
+ {
+ printf("N"); fflush(stdout);
+ }
+ /* Leave the final sessionID for resumed connections */
+ if (i + 1 < g_new)
+ {
+ matrixSslDeleteSessionId(sid);
+ }
+ }
+ printf("\n");
+ if (g_bytes_requested > 0)
+ {
+ psAssert(g_bytes_requested * g_new == stats.rbytes);
+ }
+ printf("%d bytes received\n", stats.rbytes);
+# ifdef USE_HIGHRES_TIME
+ printf("%d usec (%d avg usec/conn SSL handshake overhead)\n",
+ (int) stats.hstime, (int) (stats.hstime / g_new));
+ printf("%d usec (%d avg usec/conn SSL data overhead)\n",
+ (int) stats.datatime, (int) (stats.datatime / g_new));
+# else
+ printf("%d msec (%d avg msec/conn SSL handshake overhead)\n",
+ (int) stats.hstime, (int) (stats.hstime / g_new));
+ printf("%d msec (%d avg msec/conn SSL data overhead)\n",
+ (int) stats.datatime, (int) (stats.datatime / g_new));
+# endif
- memset(&stats, 0x0, sizeof(struct g_sslstats));
- printf("=== %d resumed connections ===\n", g_resumed);
- for (i = 0; i < g_resumed; i++) {
- rc = httpsClientConnection(keys, sid, &stats);
- if (rc < 0) {
- printf("f %d/%d\n", i, g_resumed);
- exit_code = EXIT_FAILURE;
- goto out;
- } else {
- printf("R"); fflush(stdout);
- }
- }
- if (g_keepalive) {
- printf("Closing socket\n");
- close(g_keepalive);
- g_keepalive = 0;
- }
- if (g_resumed) {
- if (g_bytes_requested > 0) {
- psAssert(g_bytes_requested * g_resumed == stats.rbytes);
- }
- printf("\n%d bytes received\n", stats.rbytes);
-#ifdef USE_HIGHRES_TIME
- printf("%d usec (%d avg usec/conn SSL handshake overhead)\n",
- (int)stats.hstime, (int)(stats.hstime/ g_resumed));
- printf("%d usec (%d avg usec/conn SSL data overhead)\n",
- (int)stats.datatime, (int)(stats.datatime/ g_resumed));
-#else
- printf("%d msec (%d avg msec/conn SSL handshake overhead)\n",
- (int)stats.hstime, (int)(stats.hstime/ g_resumed));
- printf("%d msec (%d avg msec/conn SSL data overhead)\n",
- (int)stats.datatime, (int)(stats.datatime/ g_resumed));
-#endif
- }
+ memset(&stats, 0x0, sizeof(struct g_sslstats));
+ printf("=== %d resumed connections ===\n", g_resumed);
+ for (i = 0; i < g_resumed; i++)
+ {
+ rc = httpsClientConnection(keys, sid, &stats);
+ if (rc < 0)
+ {
+ printf("f %d/%d\n", i, g_resumed);
+ exit_code = EXIT_FAILURE;
+ goto out;
+ }
+ else
+ {
+ printf("R"); fflush(stdout);
+ }
+ }
+ if (g_keepalive)
+ {
+ printf("Closing socket\n");
+ close(g_keepalive);
+ g_keepalive = 0;
+ }
+ if (g_resumed)
+ {
+ if (g_bytes_requested > 0)
+ {
+ psAssert(g_bytes_requested * g_resumed == stats.rbytes);
+ }
+ printf("\n%d bytes received\n", stats.rbytes);
+# ifdef USE_HIGHRES_TIME
+ printf("%d usec (%d avg usec/conn SSL handshake overhead)\n",
+ (int) stats.hstime, (int) (stats.hstime / g_resumed));
+ printf("%d usec (%d avg usec/conn SSL data overhead)\n",
+ (int) stats.datatime, (int) (stats.datatime / g_resumed));
+# else
+ printf("%d msec (%d avg msec/conn SSL handshake overhead)\n",
+ (int) stats.hstime, (int) (stats.hstime / g_resumed));
+ printf("%d msec (%d avg msec/conn SSL data overhead)\n",
+ (int) stats.datatime, (int) (stats.datatime / g_resumed));
+# endif
+ }
out:
- matrixSslDeleteSessionId(sid);
+ matrixSslDeleteSessionId(sid);
- matrixSslDeleteKeys(keys);
- matrixSslClose();
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
- if (rc == MATRIXSSL_SUCCESS)
- printf("TLS handshake complete.\n");
+ if (rc == MATRIXSSL_SUCCESS)
+ {
+ printf("TLS handshake complete.\n");
+ }
-#ifdef WIN32
- _psTrace("Press any key to close");
- getchar();
-#endif
- return exit_code;
+# ifdef WIN32
+ _psTrace("Press any key to close");
+ getchar();
+# endif
+ return exit_code;
}
/******************************************************************************/
/*
- Close a socket and free associated SSL context and buffers
- An attempt is made to send a closure alert
+ Close a socket and free associated SSL context and buffers
+ An attempt is made to send a closure alert
*/
static void closeConn(ssl_t *ssl, SOCKET fd)
{
- unsigned char *buf;
- int32 len, rc;
+ unsigned char *buf;
+ int32 len, rc;
- if (g_send_closure_alert) {
-#if 1
- /* Set the socket to non-blocking to flush remaining data */
-#ifdef POSIX
- rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
- psAssert(rc >= 0);
-#endif
-#ifdef WIN32
- len = 1; /* 1 for non-block, 0 for block */
- rc = ioctlsocket(fd, FIONBIO, &len);
- psAssert(rc);
-#endif
- /* Quick attempt to send a closure alert, don't worry about failure */
- if (matrixSslEncodeClosureAlert(ssl) >= 0) {
- if ((len = matrixSslGetOutdata(ssl, &buf)) > 0) {
- if ((len = send(fd, buf, len, MSG_DONTWAIT)) > 0) {
- matrixSslSentData(ssl, len);
- }
- }
- }
-#endif
- }
- matrixSslDeleteSession(ssl);
+ if (g_send_closure_alert)
+ {
+# if 1
+ /* Set the socket to non-blocking to flush remaining data */
+# ifdef POSIX
+ rc = fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
+ psAssert(rc >= 0);
+# endif
+# ifdef WIN32
+ len = 1; /* 1 for non-block, 0 for block */
+ rc = ioctlsocket(fd, FIONBIO, &len);
+ psAssert(rc);
+# endif
+ /* Quick attempt to send a closure alert, don't worry about failure */
+ if (matrixSslEncodeClosureAlert(ssl) >= 0)
+ {
+ if ((len = matrixSslGetOutdata(ssl, &buf)) > 0)
+ {
+ if ((len = send(fd, buf, len, MSG_DONTWAIT)) > 0)
+ {
+ matrixSslSentData(ssl, len);
+ }
+ }
+ }
+# endif
+ }
+ matrixSslDeleteSession(ssl);
- if (fd != INVALID_SOCKET && g_keepalive == 0) {
- //printf("Closing socket from closeConn\n");
- close(fd);
- }
+ if (fd != INVALID_SOCKET && g_keepalive == 0)
+ {
+ /* printf("Closing socket from closeConn\n"); */
+ close(fd);
+ }
}
static int32_t extensionCb(ssl_t *ssl,
- uint16_t extType, uint8_t extLen, void *e)
+ uint16_t extType, uint8_t extLen, void *e)
{
- unsigned char *c;
- short len;
- char proto[128];
+ unsigned char *c;
+ short len;
+ char proto[128];
- c = (unsigned char*)e;
+ c = (unsigned char *) e;
- if (extType == EXT_ALPN) {
- memset(proto, 0x0, 128);
- /* two byte proto list len, one byte proto len, then proto */
- c += 2; /* Skip proto list len */
- len = *c; c++;
- memcpy(proto, c, len);
- printf("Server agreed to use %s\n", proto);
- }
- return PS_SUCCESS;
+ if (extType == EXT_ALPN)
+ {
+ memset(proto, 0x0, 128);
+ /* two byte proto list len, one byte proto len, then proto */
+ c += 2; /* Skip proto list len */
+ len = *c; c++;
+ memcpy(proto, c, len);
+ printf("Server agreed to use %s\n", proto);
+ }
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- Example callback to show possiblie outcomes of certificate validation.
- If this callback is not registered in matrixSslNewClientSession
- the connection will be accepted or closed based on the alert value.
+ Example callback to show possiblie outcomes of certificate validation.
+ If this callback is not registered in matrixSslNewClientSession
+ the connection will be accepted or closed based on the alert value.
*/
static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert)
{
-#ifndef USE_ONLY_PSK_CIPHER_SUITE
- psX509Cert_t *next;
+# ifndef USE_ONLY_PSK_CIPHER_SUITE
+ psX509Cert_t *next;
- /* An immediate SSL_ALERT_UNKNOWN_CA alert means we could not find the
- CA to authenticate the server's certificate */
- if (alert == SSL_ALERT_UNKNOWN_CA) {
- /* Example to allow anonymous connections based on a define */
- if (ALLOW_ANON_CONNECTIONS) {
- if (g_trace) {
- _psTraceStr("Allowing anonymous connection for: %s.\n",
- cert->subject.commonName);
- }
- return SSL_ALLOW_ANON_CONNECTION;
- }
- _psTrace("ERROR: No matching CA found. Terminating connection\n");
- }
-
- /* Check for "major" authentication problems within the server certificate
- chain.
-
- The "alert" is the translation of the very first authentication problem
- found. So if we are dealing with a certificate chain we should walk to
- the parent-most cert to confirm there are no authentication problems
- that indicate the chain itself did not validate or this client did
- not find a CA to authenticate the server.
-
- Some certificate callback implemenations might choose to ignore some
- alerts that are considered minor to the use case, so this is an example
- of how to make sure a minor alert (such as expired date) is not
- overriding a more serious authentication problem
- */
- for (next = cert; next != NULL; next = next->next) {
- if (next->authStatus == PS_CERT_AUTH_FAIL_SIG) {
- _psTrace("Public key signature failure in server cert chain\n");
- /* This should result in a BAD_CERTIFICATE alert */
- alert = SSL_ALERT_BAD_CERTIFICATE;
- break;
- }
- if (next->authStatus == PS_CERT_AUTH_FAIL_DN) {
- /* A CA file was never located to support this chain */
- _psTrace("No CA file was found to support server's certificate\n");
- /* This should result in a SSL_ALERT_UNKNOWN_CA alert */
- alert = SSL_ALERT_UNKNOWN_CA;
- break;
- }
- if (next->authStatus == PS_CERT_AUTH_FAIL_AUTHKEY) {
- /* Subject and Issuer Key Id extension */
- _psTrace("Subject and Issuer Key Id mismatch error\n");
- /* This should be a BAD_CERTIFICATE alert */
- alert = SSL_ALERT_BAD_CERTIFICATE;
- break;
- }
- }
-
- /*
- If the expectedName passed to matrixSslNewClientSession does not
- match any of the server subject name or subjAltNames, we will have
- the alert below.
- For security, the expected name (typically a domain name) _must_
- match one of the certificate subject names, or the connection
- should not continue.
- The default MatrixSSL certificates use localhost and 127.0.0.1 as
- the subjects, so unless the server IP matches one of those, this
- alert will happen.
- To temporarily disable the subjet name validation, NULL can be passed
- as expectedName to matrixNewClientSession.
- */
- if (alert == SSL_ALERT_CERTIFICATE_UNKNOWN) {
- _psTraceStr("ERROR: %s not found in cert subject names\n",
- ssl->expectedName);
- }
+ /* An immediate SSL_ALERT_UNKNOWN_CA alert means we could not find the
+ CA to authenticate the server's certificate */
+ if (alert == SSL_ALERT_UNKNOWN_CA)
+ {
+ /*
+ SSL_ALERT_UNKNOWN_CA can also result from breach of the
+ max_verify_depth limit we specified in the session options.
+ */
+ if (g_max_verify_depth > 0) {
+ for (next = cert; next != NULL; next = next->next)
+ {
+ if ((next->authStatus & PS_CERT_AUTH_FAIL_PATH_LEN) &&
+ (next->authFailFlags &
+ PS_CERT_AUTH_FAIL_VERIFY_DEPTH_FLAG))
+ {
+ _psTrace("Maximum cert chain verify depth exceeded\n");
+ return SSL_ALERT_UNKNOWN_CA;
+ }
+ }
+ }
+ /* Example to allow anonymous connections based on a define */
+ else if (ALLOW_ANON_CONNECTIONS)
+ {
+ if (g_trace)
+ {
+ _psTraceStr("Allowing anonymous connection for: %s.\n",
+ cert->subject.commonName);
+ }
+ return SSL_ALLOW_ANON_CONNECTION;
+ }
+ _psTrace("ERROR: No matching CA found. Terminating connection\n");
+ }
- if (alert == SSL_ALERT_CERTIFICATE_EXPIRED) {
-#ifdef POSIX
- _psTrace("ERROR: A cert did not fall within the notBefore/notAfter window\n");
-#else
- _psTrace("WARNING: Certificate date window validation not implemented\n");
- alert = 0;
-#endif
- }
+ /* Check for "major" authentication problems within the server certificate
+ chain.
- if (alert == SSL_ALERT_ILLEGAL_PARAMETER) {
- _psTrace("ERROR: Found correct CA but X.509 extension details are wrong\n");
- }
+ The "alert" is the translation of the very first authentication problem
+ found. So if we are dealing with a certificate chain we should walk to
+ the parent-most cert to confirm there are no authentication problems
+ that indicate the chain itself did not validate or this client did
+ not find a CA to authenticate the server.
- /* Key usage related problems on chain */
- for (next = cert; next != NULL; next = next->next) {
- if (next->authStatus == PS_CERT_AUTH_FAIL_EXTENSION) {
- if (next->authFailFlags & PS_CERT_AUTH_FAIL_KEY_USAGE_FLAG) {
- _psTrace("CA keyUsage extension doesn't allow cert signing\n");
- }
- if (next->authFailFlags & PS_CERT_AUTH_FAIL_EKU_FLAG) {
- _psTrace("Cert extendedKeyUsage extension doesn't allow TLS\n");
- }
- }
- }
+ Some certificate callback implemenations might choose to ignore some
+ alerts that are considered minor to the use case, so this is an example
+ of how to make sure a minor alert (such as expired date) is not
+ overriding a more serious authentication problem
+ */
+ for (next = cert; next != NULL; next = next->next)
+ {
+ if (next->authStatus == PS_CERT_AUTH_FAIL_SIG)
+ {
+ _psTrace("Public key signature failure in server cert chain\n");
+ /* This should result in a BAD_CERTIFICATE alert */
+ alert = SSL_ALERT_BAD_CERTIFICATE;
+ break;
+ }
+ if (next->authStatus == PS_CERT_AUTH_FAIL_DN)
+ {
+ /* A CA file was never located to support this chain */
+ _psTrace("No CA file was found to support server's certificate\n");
+ /* This should result in a SSL_ALERT_UNKNOWN_CA alert */
+ alert = SSL_ALERT_UNKNOWN_CA;
+ break;
+ }
+ if (next->authStatus == PS_CERT_AUTH_FAIL_AUTHKEY)
+ {
+ /* Subject and Issuer Key Id extension */
+ _psTrace("Subject and Issuer Key Id mismatch error\n");
+ /* This should be a BAD_CERTIFICATE alert */
+ alert = SSL_ALERT_BAD_CERTIFICATE;
+ break;
+ }
+ }
- if (alert == SSL_ALERT_BAD_CERTIFICATE) {
- /* Should never let a connection happen if this is set. There was
- either a problem in the presented chain or in the final CA test */
- _psTrace("ERROR: Problem in certificate validation. Exiting.\n");
- }
+ /*
+ If the expectedName passed to matrixSslNewClientSession does not
+ match any of the server subject name or subjAltNames, we will have
+ the alert below.
+ For security, the expected name (typically a domain name) _must_
+ match one of the certificate subject names, or the connection
+ should not continue.
+ The default MatrixSSL certificates use localhost and 127.0.0.1 as
+ the subjects, so unless the server IP matches one of those, this
+ alert will happen.
+ To temporarily disable the subject name validation, NULL can be passed
+ as expectedName to matrixNewClientSession.
+ */
+ if (alert == SSL_ALERT_CERTIFICATE_UNKNOWN)
+ {
+ _psTraceStr("ERROR: %s not found in cert subject names\n",
+ ssl->expectedName);
+ }
+
+ if (alert == SSL_ALERT_CERTIFICATE_EXPIRED)
+ {
+# ifdef POSIX
+ _psTrace("ERROR: A cert did not fall within the notBefore/notAfter window\n");
+# else
+ _psTrace("WARNING: Certificate date window validation not implemented\n");
+ alert = 0;
+# endif
+ }
+
+ if (alert == SSL_ALERT_ILLEGAL_PARAMETER)
+ {
+ _psTrace("ERROR: Found correct CA but X.509 extension details are wrong\n");
+ }
+
+ /* Key usage related problems on chain */
+ for (next = cert; next != NULL; next = next->next)
+ {
+ if (next->authStatus == PS_CERT_AUTH_FAIL_EXTENSION)
+ {
+ if (next->authFailFlags & PS_CERT_AUTH_FAIL_KEY_USAGE_FLAG)
+ {
+ _psTrace("CA keyUsage extension doesn't allow cert signing\n");
+ }
+ if (next->authFailFlags & PS_CERT_AUTH_FAIL_EKU_FLAG)
+ {
+ _psTrace("Cert extendedKeyUsage extension doesn't allow TLS\n");
+ }
+ }
+ }
+
+ if (alert == SSL_ALERT_BAD_CERTIFICATE)
+ {
+ /* Should never let a connection happen if this is set. There was
+ either a problem in the presented chain or in the final CA test */
+ _psTrace("ERROR: Problem in certificate validation. Exiting.\n");
+ }
-#ifdef USE_CRL
- /* Examples on how to look at the CRL status for the cert chain and fetch
- CRLs if they have not been loaded */
- {
- psX509Crl_t *expired;
-#ifdef MIDHANDSHAKE_CRL_FETCH
- /* Will pause this handshake to go out and fetch a CRL via HTTP GET,
- re-check for revocation and continue on if it all checks out */
- int retryOnce = 0;
+# ifdef USE_CRL
+ /* Examples on how to look at the CRL status for the cert chain and fetch
+ CRLs if they have not been loaded */
+ {
+ psX509Crl_t *expired;
+# ifdef MIDHANDSHAKE_CRL_FETCH
+ /* Will pause this handshake to go out and fetch a CRL via HTTP GET,
+ re-check for revocation and continue on if it all checks out */
+ int retryOnce = 0;
RETRY_CRL_TEST_ONCE:
-#else
- /* Perhaps the more standard way is to stop the handshake if the CRLs have
- not been fetched. Go fetch them and retry the SSL connection from
- scratch. The connection reattempt will only occur if the -n command
- line option has been set to something greater than 1 */
- int count = 0;
- uint32_t urlLen;
- unsigned char *url;
-#endif
+# else
+ /* Perhaps the more standard way is to stop the handshake if the CRLs have
+ not been fetched. Go fetch them and retry the SSL connection from
+ scratch. The connection reattempt will only occur if the -n command
+ line option has been set to something greater than 1 */
+ int count = 0;
+ uint32_t urlLen;
+ unsigned char *url;
+# endif
- /* Loop to look at the CRL status of each cert in the chain */
- for (next = cert; next != NULL; next = next->next) {
- switch (next->revokedStatus) {
- case CRL_CHECK_CRL_EXPIRED:
- _psTrace("Have CRL but it is expired. Fetching new one\n");
- /* Remove the CRL from the table */
- expired = psCRL_GetCRLForCert(next);
- if (expired) {
- psAssert(expired->expired);
- psCRL_Delete(expired);
- } else {
- _psTrace("Unexpected combo of expired but no CRL found\n");
- }
- /* MOVING INTO CRL_CHECK_EXPECTED ON PURPOSE TO REFETCH */
- case CRL_CHECK_EXPECTED:
- /* There was a CRL distribution point in this cert but we didn't
- have the CRL to test against */
-#ifdef MIDHANDSHAKE_CRL_FETCH
- /* It is an application choice to go out and fetch CRLs in the
- middle of the handshake like this. It's probably not advised
- to do this but here is an example if you'd like to do so */
- /* Only attempt this once so we don't get stuck in a loop */
- if (retryOnce) {
- _psTrace("Cert was not able to be tested against a CRL\n");
- alert = SSL_ALERT_CERTIFICATE_UNKNOWN;
- break;
- }
- _psTrace("Cert expects CRL. Mid-handshake attempt being made\n");
- /* This fetchParseAndAuthCRLfromCert will work on "next" as a chain
- so it is correct that the server cert will look for the first
- instance of CHECK_EXPECTED and pass that as the start of
- chain to work upon */
- fetchParseAndAuthCRLfromCert(NULL, next, ssl->keys->CAcerts);
- /* If all went well, every cert in the server chain will have an
- updated status */
- retryOnce++;
- goto RETRY_CRL_TEST_ONCE;
-#else /* MIDHANSHAKE_CRL_FETCH */
+ /* Loop to look at the CRL status of each cert in the chain */
+ for (next = cert; next != NULL; next = next->next)
+ {
+ switch (next->revokedStatus)
+ {
+ case CRL_CHECK_CRL_EXPIRED:
+ _psTrace("Have CRL but it is expired. Fetching new one\n");
+ /* Remove the CRL from the table */
+ expired = psCRL_GetCRLForCert(next);
+ if (expired)
+ {
+ psAssert(expired->expired);
+ psCRL_Delete(expired);
+ }
+ else
+ {
+ _psTrace("Unexpected combo of expired but no CRL found\n");
+ }
+ /* MOVING INTO CRL_CHECK_EXPECTED ON PURPOSE TO REFETCH */
+ case CRL_CHECK_EXPECTED:
+ /* There was a CRL distribution point in this cert but we didn't
+ have the CRL to test against */
+# ifdef MIDHANDSHAKE_CRL_FETCH
+ /* It is an application choice to go out and fetch CRLs in the
+ middle of the handshake like this. It's probably not advised
+ to do this but here is an example if you'd like to do so */
+ /* Only attempt this once so we don't get stuck in a loop */
+ if (retryOnce)
+ {
+ _psTrace("Cert was not able to be tested against a CRL\n");
+ alert = SSL_ALERT_CERTIFICATE_UNKNOWN;
+ break;
+ }
+ _psTrace("Cert expects CRL. Mid-handshake attempt being made\n");
+ /* This fetchParseAndAuthCRLfromCert will work on "next" as a chain
+ so it is correct that the server cert will look for the first
+ instance of CHECK_EXPECTED and pass that as the start of
+ chain to work upon */
+ fetchParseAndAuthCRLfromCert(NULL, next, ssl->keys->CAcerts);
+ /* If all went well, every cert in the server chain will have an
+ updated status */
+ retryOnce++;
+ goto RETRY_CRL_TEST_ONCE;
+# else /* MIDHANSHAKE_CRL_FETCH */
- //if (next->extensions.ak.keyId) {
- // psTraceBytes("cert ak", next->extensions.ak.keyId, 20);
- //}
- _psTrace("Cert expects CRL. Failing handshake to go fetch it\n");
- /* A more typical case if CRL testing is expected to be done is
- to halt the handshake now, go out and fetch the CRLs and
- try the connection again */
- /* Not clear which alert should be associated with this
- application level decision. Let's call it UNKNOWN */
- alert = SSL_ALERT_CERTIFICATE_UNKNOWN;
-
- /* Save aside the CRL URL distribution points to fetch after
- control is given back when this handshake is done. Correct
- to pick up from the current cert and work up as far as
- possible */
- if (count < CRL_MAX_SERVER_CERT_CHAIN) {
- memset(g_crlDistURLs[count], 0, CRL_MAX_URL_LEN);
- psX509GetCRLdistURL(next, (char**)&url, &urlLen);
- if (urlLen > CRL_MAX_URL_LEN) {
- _psTraceInt("CLR URL distribution point longer than %d\n",
- CRL_MAX_URL_LEN);
- } else {
- memcpy(g_crlDistURLs[count], url, urlLen);
- count++;
- }
- } else {
- _psTraceInt("Server cert chain was longer than %d\n",
- CRL_MAX_SERVER_CERT_CHAIN);
- }
-
- break;
-
-#endif /* MIDHANDSHAKE_CRL_FETCH */
- break;
+ /* if (next->extensions.ak.keyId) { */
+ /* psTraceBytes("cert ak", next->extensions.ak.keyId, 20); */
+ /* } */
+ _psTrace("Cert expects CRL. Failing handshake to go fetch it\n");
+ /* A more typical case if CRL testing is expected to be done is
+ to halt the handshake now, go out and fetch the CRLs and
+ try the connection again */
+ /* Not clear which alert should be associated with this
+ application level decision. Let's call it UNKNOWN */
+ alert = SSL_ALERT_CERTIFICATE_UNKNOWN;
- case CRL_CHECK_NOT_EXPECTED:
- _psTrace("Cert didn't specify a CRL distribution point\n");
- break;
- case CRL_CHECK_PASSED_AND_AUTHENTICATED:
- _psTrace("Cert passed CRL test and CRL was authenticated\n");
- break;
- case CRL_CHECK_PASSED_BUT_NOT_AUTHENTICATED:
- _psTrace("Cert passed CRL test but CRL was not authenticated\n");
- break;
- case CRL_CHECK_REVOKED_AND_AUTHENTICATED:
- _psTrace("Cert was revoked by an authenticated CRL\n");
- alert = SSL_ALERT_CERTIFICATE_REVOKED;
- break;
- case CRL_CHECK_REVOKED_BUT_NOT_AUTHENTICATED:
- _psTrace("Cert was revoked but the CRL wasn't authenticated\n");
- alert = SSL_ALERT_CERTIFICATE_REVOKED;
- break;
- default:
- break;
- }
- }
- } /* End CRL local code block */
-#endif
+ /* Save aside the CRL URL distribution points to fetch after
+ control is given back when this handshake is done. Correct
+ to pick up from the current cert and work up as far as
+ possible */
+ if (count < CRL_MAX_SERVER_CERT_CHAIN)
+ {
+ memset(g_crlDistURLs[count], 0, CRL_MAX_URL_LEN);
+ psX509GetCRLdistURL(next, (char **) &url, &urlLen);
+ if (urlLen > CRL_MAX_URL_LEN)
+ {
+ _psTraceInt("CLR URL distribution point longer than %d\n",
+ CRL_MAX_URL_LEN);
+ }
+ else
+ {
+ memcpy(g_crlDistURLs[count], url, urlLen);
+ count++;
+ }
+ }
+ else
+ {
+ _psTraceInt("Server cert chain was longer than %d\n",
+ CRL_MAX_SERVER_CERT_CHAIN);
+ }
- if (g_trace && alert == 0 && cert) {
- _psTraceStr("SUCCESS: Validated cert for: %s.\n", cert->subject.commonName);
- }
+ break;
-#endif /* !USE_ONLY_PSK_CIPHER_SUITE */
- return alert;
+# endif /* MIDHANDSHAKE_CRL_FETCH */
+ break;
+
+ case CRL_CHECK_NOT_EXPECTED:
+ _psTrace("Cert didn't specify a CRL distribution point\n");
+ break;
+ case CRL_CHECK_PASSED_AND_AUTHENTICATED:
+ _psTrace("Cert passed CRL test and CRL was authenticated\n");
+ break;
+ case CRL_CHECK_PASSED_BUT_NOT_AUTHENTICATED:
+ _psTrace("Cert passed CRL test but CRL was not authenticated\n");
+ break;
+ case CRL_CHECK_REVOKED_AND_AUTHENTICATED:
+ _psTrace("Cert was revoked by an authenticated CRL\n");
+ alert = SSL_ALERT_CERTIFICATE_REVOKED;
+ break;
+ case CRL_CHECK_REVOKED_BUT_NOT_AUTHENTICATED:
+ _psTrace("Cert was revoked but the CRL wasn't authenticated\n");
+ alert = SSL_ALERT_CERTIFICATE_REVOKED;
+ break;
+ default:
+ break;
+ }
+ }
+ } /* End CRL local code block */
+# endif
+
+ if (g_trace && alert == 0 && cert)
+ {
+ _psTraceStr("SUCCESS: Validated cert for: %s.\n", cert->subject.commonName);
+ }
+
+# endif /* !USE_ONLY_PSK_CIPHER_SUITE */
+ return alert;
} /* end certificate callback */
/******************************************************************************/
-#ifdef USE_CRL
+# ifdef USE_CRL
-#ifndef MIDHANDSHAKE_CRL_FETCH
+# ifndef MIDHANDSHAKE_CRL_FETCH
/* Part of example for halting handshake because no CRL was available. Now
- we have closed that handshake and are fetching the CRLs that were set
- aside during the certificate callback. We use our list of CA files as
- potential issuers here so we can attempt a round of CRL authentications.
- This authentication round will save time during the next handshake */
+ we have closed that handshake and are fetching the CRLs that were set
+ aside during the certificate callback. We use our list of CA files as
+ potential issuers here so we can attempt a round of CRL authentications.
+ This authentication round will save time during the next handshake */
static void fetchSavedCRL(psX509Cert_t *potentialIssuers)
{
- int i;
-
- /* Test for 'h' is assuming URL to begin with "http" */
- for (i = 0; i < CRL_MAX_SERVER_CERT_CHAIN && g_crlDistURLs[i][0] == 'h';
- i++) {
- fetchParseAndAuthCRLfromUrl(NULL, g_crlDistURLs[i],
- strlen((char*)g_crlDistURLs[i]), potentialIssuers);
- memset(g_crlDistURLs[i], 0, CRL_MAX_URL_LEN);
- }
+ int i;
+
+ /* Test for 'h' is assuming URL to begin with "http" */
+ for (i = 0; i < CRL_MAX_SERVER_CERT_CHAIN && g_crlDistURLs[i][0] == 'h';
+ i++)
+ {
+ fetchParseAndAuthCRLfromUrl(NULL, g_crlDistURLs[i],
+ strlen((char *) g_crlDistURLs[i]), potentialIssuers);
+ memset(g_crlDistURLs[i], 0, CRL_MAX_URL_LEN);
+ }
}
/* Fetch a CRL give an URL. Once you have it, check to see if it can be
- authenticated by any of the "potentialIssuers"
-
- Regardless of authentication status, add any CRL that is found
- to the global cache for access inside the library during internal
- authentications */
+ authenticated by any of the "potentialIssuers"
+
+ Regardless of authentication status, add any CRL that is found
+ to the global cache for access inside the library during internal
+ authentications */
static int32_t fetchParseAndAuthCRLfromUrl(psPool_t *pool, unsigned char *url,
- uint32_t urlLen, psX509Cert_t *potentialIssuers)
+ uint32_t urlLen, psX509Cert_t *potentialIssuers)
{
- unsigned char *crlBuf;
- uint32_t crlBufLen;
- psX509Crl_t *crl;
- psX509Cert_t *ic;
-
- /* url need not be freed. It points into cert structure */
- if (fetchCRL(NULL, (char*)url, urlLen, &crlBuf, &crlBufLen) < 0){
- _psTrace("Unable to fetch CRL\n");
- return -1;
- }
- /* Convert the CRL stream into our structure */
- if (psX509ParseCRL(pool, &crl, crlBuf, crlBufLen) < 0) {
- _psTrace("Unable to parse CRL\n");
- psFree(crlBuf, pool);
- return -1;
- }
- psFree(crlBuf, pool);
-
- /* Adding the CRL to the global cache. This local crl is now the
- same memory as the entry in the global cache and is managed
- there. Freeing will now be done with psCRL_DeleteAll at
- application closure */
- psCRL_Update(crl, 1); /* The 1 will delete old CRLs */
-
- /* Important to separate the concept of the CRL authentication
- from the cert authentication. Here, we run through the
- list of potential issuers the caller thinks could work */
- for (ic = potentialIssuers; ic != NULL; ic = ic->next) {
- if (psX509AuthenticateCRL(ic, crl, NULL) >= 0) {
- _psTrace("NOTE: Able to authenticate CRL\n");
- break; /* Stop looking */
- }
- }
- return PS_SUCCESS;
+ unsigned char *crlBuf;
+ uint32_t crlBufLen;
+ psX509Crl_t *crl;
+ psX509Cert_t *ic;
+
+ /* url need not be freed. It points into cert structure */
+ if (fetchCRL(NULL, (char *) url, urlLen, &crlBuf, &crlBufLen) < 0)
+ {
+ _psTrace("Unable to fetch CRL\n");
+ return -1;
+ }
+ /* Convert the CRL stream into our structure */
+ if (psX509ParseCRL(pool, &crl, crlBuf, crlBufLen) < 0)
+ {
+ _psTrace("Unable to parse CRL\n");
+ psFree(crlBuf, pool);
+ return -1;
+ }
+ psFree(crlBuf, pool);
+
+ /* Adding the CRL to the global cache. This local crl is now the
+ same memory as the entry in the global cache and is managed
+ there. Freeing will now be done with psCRL_DeleteAll at
+ application closure */
+ psCRL_Update(crl, 1); /* The 1 will delete old CRLs */
+
+ /* Important to separate the concept of the CRL authentication
+ from the cert authentication. Here, we run through the
+ list of potential issuers the caller thinks could work */
+ for (ic = potentialIssuers; ic != NULL; ic = ic->next)
+ {
+ if (psX509AuthenticateCRL(ic, crl, NULL) >= 0)
+ {
+ _psTrace("NOTE: Able to authenticate CRL\n");
+ break; /* Stop looking */
+ }
+ }
+ return PS_SUCCESS;
}
-#endif /* ifndef MIDHANDSHAKE_CRL_FETCH */
+# endif /* ifndef MIDHANDSHAKE_CRL_FETCH */
/* Take the CRL Distribution URL from the "cert" (may be a chain) and go fetch
- the CRL. Once you have it, check to see if it can be authenticated by any
- of the "potentialIssuers" OR by the "cert" chain itself.
-
- Regardless of authentication status, add any CRL that is found
- to the global cache for access inside the library during internal
- authentications */
+ the CRL. Once you have it, check to see if it can be authenticated by any
+ of the "potentialIssuers" OR by the "cert" chain itself.
+
+ Regardless of authentication status, add any CRL that is found
+ to the global cache for access inside the library during internal
+ authentications */
static int32_t fetchParseAndAuthCRLfromCert(psPool_t *pool, psX509Cert_t *cert,
- psX509Cert_t *potentialIssuers)
+ psX509Cert_t *potentialIssuers)
{
- char *url;
- unsigned char *crlBuf;
- uint32_t urlLen, crlBufLen;
- psX509Crl_t *crl;
- psX509Cert_t *sc, *ic;
- int32 numLoaded = 0;
-
- sc = cert;
- while(sc) {
- if (psX509GetCRLdistURL(sc, &url, &urlLen) > 0) {
- /* url need not be freed. It points into cert structure */
- if (fetchCRL(NULL, url, urlLen, &crlBuf, &crlBufLen) < 0){
- _psTrace("Unable to fetch CRL\n");
- sc = sc->next;
- continue;
- }
- /* Convert the CRL stream into our structure */
- if (psX509ParseCRL(pool, &crl, crlBuf, crlBufLen) < 0) {
- _psTrace("Unable to parse CRL\n");
- psFree(crlBuf, pool);
- sc = sc->next;
- continue;
- }
- psFree(crlBuf, pool);
-
- /* Adding the CRL to the global cache. This local crl is now the
- same memory as the entry in the global cache and is managed
- there. Freeing will now be done with psCRL_DeleteAll at
- application closure */
- psCRL_Update(crl, 1); /* The 1 will delete old CRLs */
- ++numLoaded;
-
- /* Important to separate the concept of the CRL authentication
- from the cert authentication. Here, we run through the
- list of potential issuers the caller thinks could work */
- for (ic = potentialIssuers; ic != NULL; ic = ic->next) {
- if (psX509AuthenticateCRL(ic, crl, NULL) >= 0) {
- _psTrace("NOTE: Able to authenticate CRL\n");
- break; /* Stop looking */
- }
- }
- if (crl->authenticated == 0) {
- /* If none of our potential issuers were able to authenticate,
- let's just run through our own "cert" chain as well.
- The reason we are doing this is to allow this function
- to handle cases where the "cert" is part of a server
- cert chain where the issuer is included as part of that
- CERTIFICATE message. That is what we are testing here.
- The potentialIssuers will typically be the loaded CA
- files and that will catch the cases where the parent-most
- certificate of the server chain will need to be
- authenticated */
- for (ic = cert; ic != NULL; ic = ic->next) {
- if (psX509AuthenticateCRL(ic, crl, NULL) >= 0) {
- _psTrace("NOTE: Able to authenticate CRL\n");
- break; /* Stop looking */
- }
- }
- }
-
- /* Regardless of whether or not we could authenticate the CRL,
- run the function that recalculates the revokedStatus of
- the certificate itself. REQUIRES g_CRL */
- psCRL_determineRevokedStatus(sc);
- }
- sc = sc->next;
- }
- _psTraceInt("CRLs loaded: %d\n", numLoaded);
- return PS_SUCCESS;
+ char *url;
+ unsigned char *crlBuf;
+ uint32_t urlLen, crlBufLen;
+ psX509Crl_t *crl;
+ psX509Cert_t *sc, *ic;
+ int32 numLoaded = 0;
+
+ sc = cert;
+ while (sc)
+ {
+ if (psX509GetCRLdistURL(sc, &url, &urlLen) > 0)
+ {
+ /* url need not be freed. It points into cert structure */
+ if (fetchCRL(NULL, url, urlLen, &crlBuf, &crlBufLen) < 0)
+ {
+ _psTrace("Unable to fetch CRL\n");
+ sc = sc->next;
+ continue;
+ }
+ /* Convert the CRL stream into our structure */
+ if (psX509ParseCRL(pool, &crl, crlBuf, crlBufLen) < 0)
+ {
+ _psTrace("Unable to parse CRL\n");
+ psFree(crlBuf, pool);
+ sc = sc->next;
+ continue;
+ }
+ psFree(crlBuf, pool);
+
+ /* Adding the CRL to the global cache. This local crl is now the
+ same memory as the entry in the global cache and is managed
+ there. Freeing will now be done with psCRL_DeleteAll at
+ application closure */
+ psCRL_Update(crl, 1); /* The 1 will delete old CRLs */
+ ++numLoaded;
+
+ /* Important to separate the concept of the CRL authentication
+ from the cert authentication. Here, we run through the
+ list of potential issuers the caller thinks could work */
+ for (ic = potentialIssuers; ic != NULL; ic = ic->next)
+ {
+ if (psX509AuthenticateCRL(ic, crl, NULL) >= 0)
+ {
+ _psTrace("NOTE: Able to authenticate CRL\n");
+ break; /* Stop looking */
+ }
+ }
+ if (crl->authenticated == 0)
+ {
+ /* If none of our potential issuers were able to authenticate,
+ let's just run through our own "cert" chain as well.
+ The reason we are doing this is to allow this function
+ to handle cases where the "cert" is part of a server
+ cert chain where the issuer is included as part of that
+ CERTIFICATE message. That is what we are testing here.
+ The potentialIssuers will typically be the loaded CA
+ files and that will catch the cases where the parent-most
+ certificate of the server chain will need to be
+ authenticated */
+ for (ic = cert; ic != NULL; ic = ic->next)
+ {
+ if (psX509AuthenticateCRL(ic, crl, NULL) >= 0)
+ {
+ _psTrace("NOTE: Able to authenticate CRL\n");
+ break; /* Stop looking */
+ }
+ }
+ }
+
+ /* Regardless of whether or not we could authenticate the CRL,
+ run the function that recalculates the revokedStatus of
+ the certificate itself. REQUIRES g_CRL */
+ psCRL_determineRevokedStatus(sc);
+ }
+ sc = sc->next;
+ }
+ _psTraceInt("CRLs loaded: %d\n", numLoaded);
+ return PS_SUCCESS;
}
/**
- Return the number of bytes difference between 'end' and 'start'.
- @param[in] end A pointer to valid memory, greater or equal to 'start'
- @param[in] start A pointer to valid memory, less than or equal to 'start'
- @param sanity The maximum expected difference in bytes
- @return Number of bytes that 'end' is greater than 'start'. Range is 0 <= return <= sanity.
- If end < start, 0 is returned. If 'end' - 'start' > 'sanity', 'sanity' is returned.
-*/
+ Return the number of bytes difference between 'end' and 'start'.
+ @param[in] end A pointer to valid memory, greater or equal to 'start'
+ @param[in] start A pointer to valid memory, less than or equal to 'start'
+ @param sanity The maximum expected difference in bytes
+ @return Number of bytes that 'end' is greater than 'start'. Range is 0 <= return <= sanity.
+ If end < start, 0 is returned. If 'end' - 'start' > 'sanity', 'sanity' is returned.
+ */
__inline static size_t ptrdiff_safe(const void *end, const void *start, size_t sanity)
{
- ptrdiff_t d;
- if (end < start) {
- return 0;
- }
- d = end - start;
- if (d > sanity) {
- return sanity;
- }
- return (size_t)d;
+ ptrdiff_t d;
+
+ if (end < start)
+ {
+ return 0;
+ }
+ d = end - start;
+ if (d > sanity)
+ {
+ return sanity;
+ }
+ return (size_t) d;
}
/**
- Example function to retrieve a CRL using HTTP GET over POSIX sockets.
- @security This API does not fully validate all input. It should only be used to fetch
- a CRL froa trusted source with validly generated CRL data. The HTTP response of the
- trusted server should also be tested, as the HTTP parsing in this API is not flexible.
- @param [out] crlBuf is allocated by this routine and must be freed via psFree
- @return < 0 Error loading CRL. 0 on Success
-*/
+ Example function to retrieve a CRL using HTTP GET over POSIX sockets.
+ @security This API does not fully validate all input. It should only be used to fetch
+ a CRL froa trusted source with validly generated CRL data. The HTTP response of the
+ trusted server should also be tested, as the HTTP parsing in this API is not flexible.
+ @param [out] crlBuf is allocated by this routine and must be freed via psFree
+ @return < 0 Error loading CRL. 0 on Success
+ */
int32 fetchCRL(psPool_t *pool, char *url, uint32_t urlLen,
- unsigned char **crlBuf, uint32_t *crlBufLen)
+ unsigned char **crlBuf, uint32_t *crlBufLen)
{
- static unsigned char crl_getHdr[] = "GET ";
- #define GET_OH_LEN 4
- static unsigned char crl_httpHdr[] = " HTTP/1.0\r\n";
- #define HTTP_OH_LEN 11
- static unsigned char crl_hostHdr[] = "Host: ";
- #define HOST_OH_LEN 6
- static unsigned char crl_acceptHdr[] = "\r\nAccept: */*\r\n\r\n";
- #define ACCEPT_OH_LEN 17
- #define HOST_ADDR_LEN 64 /* max to hold 'www.something.com' */
- #define GET_REQ_LEN 128 /* max to hold http GET request */
- #define HTTP_REPLY_CHUNK_SIZE 2048
+ static unsigned char crl_getHdr[] = "GET ";
- SOCKET fd;
- struct hostent *ip;
- struct in_addr intaddr;
- char *pageStart, *replyPtr, *ipAddr;
- char hostAddr[HOST_ADDR_LEN], getReq[GET_REQ_LEN];
- int hostAddrLen, getReqLen, pageLen;
- ssize_t transferred;
- int32_t grown = 0;
- int32_t sawOK, sawContentLength, err, httpUriLen, port, offset;
- unsigned char crlChunk[HTTP_REPLY_CHUNK_SIZE + 1];
- unsigned char *crlBin; /* allocated */
- uint32_t crlBinLen;
+# define GET_OH_LEN 4
+ static unsigned char crl_httpHdr[] = " HTTP/1.0\r\n";
+# define HTTP_OH_LEN 11
+ static unsigned char crl_hostHdr[] = "Host: ";
+# define HOST_OH_LEN 6
+ static unsigned char crl_acceptHdr[] = "\r\nAccept: */*\r\n\r\n";
+# define ACCEPT_OH_LEN 17
+# define HOST_ADDR_LEN 64 /* max to hold 'www.something.com' */
+# define GET_REQ_LEN 128 /* max to hold http GET request */
+# define HTTP_REPLY_CHUNK_SIZE 2048
- /* Is URI in expected URL form? */
- if (strstr(url, "http://") == NULL) {
- if (strstr(url, "https://") == NULL) {
- _psTraceStr("fetchCRL: Unsupported CRL URI: %s\n", url);
- return -1;
- }
- httpUriLen = 8;
- port = 80; /* No example yet of using SSL to fetch CRL */
- } else {
- httpUriLen = 7;
- port = 80;
- }
+ SOCKET fd;
+ struct hostent *ip;
+ struct in_addr intaddr;
+ char *pageStart, *replyPtr, *ipAddr;
+ char hostAddr[HOST_ADDR_LEN], getReq[GET_REQ_LEN];
+ int hostAddrLen, getReqLen, pageLen;
+ ssize_t transferred;
+ int32_t grown = 0;
+ int32_t sawOK, sawContentLength, err, httpUriLen, port, offset;
+ unsigned char crlChunk[HTTP_REPLY_CHUNK_SIZE + 1];
+ unsigned char *crlBin; /* allocated */
+ uint32_t crlBinLen;
- /* Parsing host and page and setting up IP address and GET request */
- if ((pageStart = strchr(url + httpUriLen, '/')) == NULL) {
- _psTrace("fetchCRL: No host/page divider found\n");
- return -1;
- }
- if ((hostAddrLen = (int)(pageStart - url) - httpUriLen) > HOST_ADDR_LEN) {
- _psTrace("fetchCRL: HOST_ADDR_LEN needs to be increased\n");
- return -1; /* ipAddr too small to hold */
- }
+ /* Is URI in expected URL form? */
+ if (strstr(url, "http://") == NULL)
+ {
+ if (strstr(url, "https://") == NULL)
+ {
+ _psTraceStr("fetchCRL: Unsupported CRL URI: %s\n", url);
+ return -1;
+ }
+ httpUriLen = 8;
+ port = 80; /* No example yet of using SSL to fetch CRL */
+ }
+ else
+ {
+ httpUriLen = 7;
+ port = 80;
+ }
- memset(hostAddr, 0, HOST_ADDR_LEN);
- memcpy(hostAddr, url + httpUriLen, hostAddrLen);
- if ((ip = gethostbyname(hostAddr)) == NULL) {
- _psTrace("fetchCRL: gethostbyname failed\n");
- return -1;
- }
+ /* Parsing host and page and setting up IP address and GET request */
+ if ((pageStart = strchr(url + httpUriLen, '/')) == NULL)
+ {
+ _psTrace("fetchCRL: No host/page divider found\n");
+ return -1;
+ }
+ if ((hostAddrLen = (int) (pageStart - url) - httpUriLen) > HOST_ADDR_LEN)
+ {
+ _psTrace("fetchCRL: HOST_ADDR_LEN needs to be increased\n");
+ return -1; /* ipAddr too small to hold */
+ }
- memcpy((char *) &intaddr, (char *) ip->h_addr_list[0],
- (size_t) ip->h_length);
- if ((ipAddr = inet_ntoa(intaddr)) == NULL) {
- _psTrace("fetchCRL: inet_ntoa failed\n");
- return -1;
- }
+ memset(hostAddr, 0, HOST_ADDR_LEN);
+ memcpy(hostAddr, url + httpUriLen, hostAddrLen);
+ if ((ip = gethostbyname(hostAddr)) == NULL)
+ {
+ _psTrace("fetchCRL: gethostbyname failed\n");
+ return -1;
+ }
- pageLen = (urlLen - hostAddrLen - httpUriLen);
- getReqLen = pageLen + hostAddrLen + GET_OH_LEN + HTTP_OH_LEN +
- HOST_OH_LEN + ACCEPT_OH_LEN;
- if (getReqLen > GET_REQ_LEN) {
- _psTrace("fetchCRL: GET_REQ_LEN needs to be increased\n");
- return -1;
- }
+ memcpy((char *) &intaddr, (char *) ip->h_addr_list[0],
+ (size_t) ip->h_length);
+ if ((ipAddr = inet_ntoa(intaddr)) == NULL)
+ {
+ _psTrace("fetchCRL: inet_ntoa failed\n");
+ return -1;
+ }
- // Build the request:
- //
- // GET /page.crl HTTP/1.0
- // Host: www.host.com
- // Accept: */*
- //
- memset(getReq, 0, GET_REQ_LEN);
- memcpy(getReq, crl_getHdr, GET_OH_LEN);
- offset = GET_OH_LEN;
- memcpy(getReq + offset, pageStart, pageLen);
- offset += pageLen;
- memcpy(getReq + offset, crl_httpHdr, HTTP_OH_LEN);
- offset += HTTP_OH_LEN;
- memcpy(getReq + offset, crl_hostHdr, HOST_OH_LEN);
- offset += HOST_OH_LEN;
- memcpy(getReq + offset, hostAddr, hostAddrLen);
- offset += hostAddrLen;
- memcpy(getReq + offset, crl_acceptHdr, ACCEPT_OH_LEN);
+ pageLen = (urlLen - hostAddrLen - httpUriLen);
+ getReqLen = pageLen + hostAddrLen + GET_OH_LEN + HTTP_OH_LEN +
+ HOST_OH_LEN + ACCEPT_OH_LEN;
+ if (getReqLen > GET_REQ_LEN)
+ {
+ _psTrace("fetchCRL: GET_REQ_LEN needs to be increased\n");
+ return -1;
+ }
- /* Connect and send */
- fd = lsocketConnect(ipAddr, port, &err);
- if (fd == INVALID_SOCKET || err != PS_SUCCESS) {
- _psTraceInt("fetchCRL: socketConnect failed: %d\n", err);
- return PS_PLATFORM_FAIL;
- }
+ /* Build the request: */
+ /* */
+ /* GET /page.crl HTTP/1.0 */
+ /* Host: www.host.com */
+ /* Accept: * / * */
+ /* */
+ memset(getReq, 0, GET_REQ_LEN);
+ memcpy(getReq, crl_getHdr, GET_OH_LEN);
+ offset = GET_OH_LEN;
+ memcpy(getReq + offset, pageStart, pageLen);
+ offset += pageLen;
+ memcpy(getReq + offset, crl_httpHdr, HTTP_OH_LEN);
+ offset += HTTP_OH_LEN;
+ memcpy(getReq + offset, crl_hostHdr, HOST_OH_LEN);
+ offset += HOST_OH_LEN;
+ memcpy(getReq + offset, hostAddr, hostAddrLen);
+ offset += hostAddrLen;
+ memcpy(getReq + offset, crl_acceptHdr, ACCEPT_OH_LEN);
- /* Send request and receive response */
- offset = 0;
- while (getReqLen) {
- if ((transferred = send(fd, getReq + offset, getReqLen, 0)) < 0) {
- _psTraceInt("fetchCRL: socket send failed: %d\n", errno);
- close(fd);
- return PS_PLATFORM_FAIL;
- }
- getReqLen -= transferred;
- offset += transferred;
- }
+ /* Connect and send */
+ fd = lsocketConnect(ipAddr, port, &err);
+ if (fd == INVALID_SOCKET || err != PS_SUCCESS)
+ {
+ _psTraceInt("fetchCRL: socketConnect failed: %d\n", err);
+ return PS_PLATFORM_FAIL;
+ }
- /* Get a chunk at a time so we can peek at the size on the first chunk
- and allocate the correct CRL size */
- crlBin = NULL;
- crlBinLen = 0;
- *crlBuf = NULL;
- *crlBufLen = 0;
- sawOK = sawContentLength = 0;
-
- /* This recv loop is not 100%. The parse is looking for a few specific
- strings in the HTTP header to get initial status, content length,
- and \r\n\r\n for beginning of CRL data. If a recv happens to fall right
- on the boundary of any of these patterns, the behavior is undefined.
- There are some asserts sprinked around to notify if this happens.
- It SHOULD be sufficient to keep a decent size HTTP_REPLY_CHUNK_SIZE
- that you can be pretty sure will hold the entire HTTP header but
- the "recv" call itself is also a factor in how many bytes will be
- recevied in the first call */
- while ((transferred = recv(fd, crlChunk, HTTP_REPLY_CHUNK_SIZE, 0)) > 0) {
- crlChunk[transferred] = 0; /* Ensure zero termination for strstr(). */
- if (crlBin == NULL) {
- /* Still getting the details of the HTTP response */
- /* Did we get an OK response? */
- if (sawOK == 0) {
- if (strstr((const char *)crlChunk, "200 OK") == NULL) {
- /* First chunk. Should be plenty large enough to hold */
- _psTrace("fetchCRL: server reply was not '200 OK'\n");
- close(fd);
- return -1;
- }
- sawOK++;
- }
- /* Length parse */
- if (sawContentLength == 0) {
- if ((replyPtr = strstr((const char *)crlChunk,
- "Content-Length: ")) == NULL) {
-
- /* Apparently Content-Length is not always going to be
- there. See if we have the end of the header instead */
- if ((replyPtr = strstr((const char *)crlChunk, "\r\n\r\n"))
- == NULL) {
- continue; /* saw neither. keep trying */
- }
- /* Saw \r\n\r\n but no Content-Length: can't allocate full
- CRL buffer at once so work in chunks */
- crlBinLen = HTTP_REPLY_CHUNK_SIZE;
- } else {
- /* Got the Content-Length: as expected */
- sawContentLength++;
-
- /* Possible cut off right at Content-Length here which
- would be a pain. This assert is seeing if there are
- at least 8 more bytes in the chunk to read the
- integer out of. If you hit this, some partial
- parsing will need to be instrumented... or change
- the chunk size if this is truly a chunk boundary */
- psAssert((replyPtr + 16) <
- (char*)&(crlChunk[HTTP_REPLY_CHUNK_SIZE - 24]));
-
-
- /* Magic 16 is length of "Content-Length: " */
- crlBinLen = (int)atoi(replyPtr + 16);
- }
- }
-
-
- /* Data begins after CRLF CRLF */
- if ((replyPtr = strstr((const char *)crlChunk, "\r\n\r\n"))
- == NULL) {
- continue;
- }
- /* Possible cut off right at data start here which
- would be a pain. This assert is seeing if there are
- 4 more bytes in the chunk to advance past. If you hit this,
- some partial parsing will need to be instrumented... or change
- the chunk size if this is truly a chunk boundary */
- psAssert((replyPtr+4) < (char*)&(crlChunk[HTTP_REPLY_CHUNK_SIZE]));
- replyPtr += 4; /* Move past that "\r\n\r\n" to get to start */
+ /* Send request and receive response */
+ offset = 0;
+ while (getReqLen)
+ {
+ if ((transferred = send(fd, getReq + offset, getReqLen, 0)) < 0)
+ {
+ _psTraceInt("fetchCRL: socket send failed: %d\n", errno);
+ close(fd);
+ return PS_PLATFORM_FAIL;
+ }
+ getReqLen -= transferred;
+ offset += transferred;
+ }
- /* Check buffer length appears acceptable */
- if (crlBinLen < 1 || crlBinLen > CRL_MAX_LENGTH) {
- _psTrace("fetchCRL: Unacceptable size for CRL\n");
- /* Note: If this fails you may need to check CRL_MAX_LENGTH,
- as you possibly need to allow larger CRL. */
- close(fd);
- return -1;
- }
+ /* Get a chunk at a time so we can peek at the size on the first chunk
+ and allocate the correct CRL size */
+ crlBin = NULL;
+ crlBinLen = 0;
+ *crlBuf = NULL;
+ *crlBufLen = 0;
+ sawOK = sawContentLength = 0;
- /* Allocate the CRL buffer. Will be full size if sawContentLength */
- if ((crlBin = psMalloc(pool, crlBinLen)) == NULL) {
- _psTrace("fetchCRL: Memory allocation error for CRL buffer\n");
- close(fd);
- return -1;
- }
+ /* This recv loop is not 100%. The parse is looking for a few specific
+ strings in the HTTP header to get initial status, content length,
+ and \r\n\r\n for beginning of CRL data. If a recv happens to fall right
+ on the boundary of any of these patterns, the behavior is undefined.
+ There are some asserts sprinked around to notify if this happens.
+ It SHOULD be sufficient to keep a decent size HTTP_REPLY_CHUNK_SIZE
+ that you can be pretty sure will hold the entire HTTP header but
+ the "recv" call itself is also a factor in how many bytes will be
+ recevied in the first call */
+ while ((transferred = recv(fd, crlChunk, HTTP_REPLY_CHUNK_SIZE, 0)) > 0)
+ {
+ crlChunk[transferred] = 0; /* Ensure zero termination for strstr(). */
+ if (crlBin == NULL)
+ {
+ /* Still getting the details of the HTTP response */
+ /* Did we get an OK response? */
+ if (sawOK == 0)
+ {
+ if (strstr((const char *) crlChunk, "200 OK") == NULL)
+ {
+ /* First chunk. Should be plenty large enough to hold */
+ _psTrace("fetchCRL: server reply was not '200 OK'\n");
+ close(fd);
+ return -1;
+ }
+ sawOK++;
+ }
+ /* Length parse */
+ if (sawContentLength == 0)
+ {
+ if ((replyPtr = strstr((const char *) crlChunk,
+ "Content-Length: ")) == NULL)
+ {
- /* So how much do we actually have to copy our of first chunk? */
- transferred -= ptrdiff_safe(replyPtr, crlChunk, HTTP_REPLY_CHUNK_SIZE);
-
- if (sawContentLength) {
- /* Will march crlBin forward so just assign output crlBuf now */
- *crlBuf = crlBin;
- *crlBufLen = crlBinLen;
- memcpy(crlBin, replyPtr, transferred);
- crlBin += transferred;
- psAssert((crlBin - *crlBuf) <= crlBinLen);
- } else {
- grown = 1;
- /* Keep track of index to monitor size */
- crlBinLen = transferred;
- memcpy(crlBin, replyPtr, transferred);
- }
- } else {
- /* subsequent recv calls */
- if (sawContentLength) {
- memcpy(crlBin, crlChunk, transferred);
- crlBin += transferred;
- psAssert((crlBin - *crlBuf) <= crlBinLen);
- } else {
- if (transferred + crlBinLen > (HTTP_REPLY_CHUNK_SIZE * grown)) {
- /* not enough room. psRealloc */
- grown++;
- crlBin = psRealloc(crlBin, HTTP_REPLY_CHUNK_SIZE * grown,
- pool);
- }
- memcpy(crlBin + crlBinLen, crlChunk, transferred);
- crlBinLen += transferred;
- }
- }
- }
- close(fd);
- if (sawContentLength == 0) {
- /* These have been changing as we grow */
- *crlBuf = crlBin;
- *crlBufLen = crlBinLen;
- } else {
- psAssert(crlBinLen == (crlBin - *crlBuf));
- }
+ /* Apparently Content-Length is not always going to be
+ there. See if we have the end of the header instead */
+ if ((replyPtr = strstr((const char *) crlChunk, "\r\n\r\n"))
+ == NULL)
+ {
+ continue; /* saw neither. keep trying */
+ }
+ /* Saw \r\n\r\n but no Content-Length: can't allocate full
+ CRL buffer at once so work in chunks */
+ crlBinLen = HTTP_REPLY_CHUNK_SIZE;
+ }
+ else
+ {
+ /* Got the Content-Length: as expected */
+ sawContentLength++;
- return 0;
+ /* Possible cut off right at Content-Length here which
+ would be a pain. This assert is seeing if there are
+ at least 8 more bytes in the chunk to read the
+ integer out of. If you hit this, some partial
+ parsing will need to be instrumented... or change
+ the chunk size if this is truly a chunk boundary */
+ psAssert((replyPtr + 16) <
+ (char *) &(crlChunk[HTTP_REPLY_CHUNK_SIZE - 24]));
+
+
+ /* Magic 16 is length of "Content-Length: " */
+ crlBinLen = (int) atoi(replyPtr + 16);
+ }
+ }
+
+
+ /* Data begins after CRLF CRLF */
+ if ((replyPtr = strstr((const char *) crlChunk, "\r\n\r\n"))
+ == NULL)
+ {
+ continue;
+ }
+ /* Possible cut off right at data start here which
+ would be a pain. This assert is seeing if there are
+ 4 more bytes in the chunk to advance past. If you hit this,
+ some partial parsing will need to be instrumented... or change
+ the chunk size if this is truly a chunk boundary */
+ psAssert((replyPtr + 4) < (char *) &(crlChunk[HTTP_REPLY_CHUNK_SIZE]));
+ replyPtr += 4; /* Move past that "\r\n\r\n" to get to start */
+
+ /* Check buffer length appears acceptable */
+ if (crlBinLen < 1 || crlBinLen > CRL_MAX_LENGTH)
+ {
+ _psTrace("fetchCRL: Unacceptable size for CRL\n");
+ /* Note: If this fails you may need to check CRL_MAX_LENGTH,
+ as you possibly need to allow larger CRL. */
+ close(fd);
+ return -1;
+ }
+
+ /* Allocate the CRL buffer. Will be full size if sawContentLength */
+ if ((crlBin = psMalloc(pool, crlBinLen)) == NULL)
+ {
+ _psTrace("fetchCRL: Memory allocation error for CRL buffer\n");
+ close(fd);
+ return -1;
+ }
+
+ /* So how much do we actually have to copy our of first chunk? */
+ transferred -= ptrdiff_safe(replyPtr, crlChunk, HTTP_REPLY_CHUNK_SIZE);
+
+ if (sawContentLength)
+ {
+ /* Will march crlBin forward so just assign output crlBuf now */
+ *crlBuf = crlBin;
+ *crlBufLen = crlBinLen;
+ memcpy(crlBin, replyPtr, transferred);
+ crlBin += transferred;
+ psAssert((crlBin - *crlBuf) <= crlBinLen);
+ }
+ else
+ {
+ grown = 1;
+ /* Keep track of index to monitor size */
+ crlBinLen = transferred;
+ memcpy(crlBin, replyPtr, transferred);
+ }
+ }
+ else
+ {
+ /* subsequent recv calls */
+ if (sawContentLength)
+ {
+ memcpy(crlBin, crlChunk, transferred);
+ crlBin += transferred;
+ psAssert((crlBin - *crlBuf) <= crlBinLen);
+ }
+ else
+ {
+ if (transferred + crlBinLen > (HTTP_REPLY_CHUNK_SIZE * grown))
+ {
+ /* not enough room. psRealloc */
+ grown++;
+ crlBin = psRealloc(crlBin, HTTP_REPLY_CHUNK_SIZE * grown,
+ pool);
+ }
+ memcpy(crlBin + crlBinLen, crlChunk, transferred);
+ crlBinLen += transferred;
+ }
+ }
+ }
+ close(fd);
+ if (sawContentLength == 0)
+ {
+ /* These have been changing as we grow */
+ *crlBuf = crlBin;
+ *crlBufLen = crlBinLen;
+ }
+ else
+ {
+ psAssert(crlBinLen == (crlBin - *crlBuf));
+ }
+
+ return 0;
}
-#endif /* USE_CRL */
+# endif /* USE_CRL */
/******************************************************************************/
/*
- Open an outgoing blocking socket connection to a remote ip and port.
- Caller should always check *err value, even if a valid socket is returned
+ Open an outgoing blocking socket connection to a remote ip and port.
+ Caller should always check *err value, even if a valid socket is returned
*/
static SOCKET lsocketConnect(char *ip, int32 port, int32 *err)
{
- struct sockaddr_in addr;
- SOCKET fd;
- int32 rc;
+ struct sockaddr_in addr;
+ SOCKET fd;
+ int32 rc;
- /* By default, this will produce a blocking socket */
- if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
- perror("socket()");
- _psTrace("Error creating socket\n");
- *err = SOCKET_ERRNO;
- return INVALID_SOCKET;
- }
-#ifdef POSIX
- rc = fcntl(fd, F_SETFD, FD_CLOEXEC);
- psAssert(rc >= 0);
-#endif
-#if 0
- {
- struct linger lin;
- rc = 1;
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&rc, sizeof(rc));
- rc = 1;
- setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (char *)&rc, sizeof(rc));
- lin.l_onoff = 0;
- lin.l_linger = 0; // Seconds
- setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&lin, sizeof(struct linger));
- }
- {
- uint32 len;
- getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rc, &len);
- printf("SO_RCVBUF: %d\n", rc);
- }
-#endif
-#ifdef POSIX
-// rc = 1;
-// setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&rc, sizeof(rc));
-// fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
-#elif defined(WIN32)
-// rc = 1; /* 1 for non-block, 0 for block */
-// ioctlsocket(fd, FIONBIO, &rc);
-#endif
-#ifdef __APPLE__ /* MAC OS X */
- rc = 1;
- setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&rc, sizeof(rc));
-#endif
- memset((char *) &addr, 0x0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_port = htons((short)port);
- addr.sin_addr.s_addr = inet_addr(ip);
- rc = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
- if (rc < 0) {
- close(fd);
- perror("connect()");
- *err = SOCKET_ERRNO;
- } else {
- *err = 0;
- }
- return fd;
+ /* By default, this will produce a blocking socket */
+ if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
+ {
+ perror("socket()");
+ _psTrace("Error creating socket\n");
+ *err = SOCKET_ERRNO;
+ return INVALID_SOCKET;
+ }
+# ifdef POSIX
+ rc = fcntl(fd, F_SETFD, FD_CLOEXEC);
+ psAssert(rc >= 0);
+# endif
+# if 0
+ {
+ struct linger lin;
+ rc = 1;
+ setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &rc, sizeof(rc));
+ rc = 1;
+ setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (char *) &rc, sizeof(rc));
+ lin.l_onoff = 0;
+ lin.l_linger = 0; /* Seconds */
+ setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &lin, sizeof(struct linger));
+ }
+ {
+ uint32 len;
+ getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rc, &len);
+ printf("SO_RCVBUF: %d\n", rc);
+ }
+# endif
+# ifdef POSIX
+/* rc = 1; */
+/* setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&rc, sizeof(rc)); */
+/* fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); */
+# elif defined(WIN32)
+/* rc = 1; / * 1 for non-block, 0 for block * / */
+/* ioctlsocket(fd, FIONBIO, &rc); */
+# endif
+# ifdef __APPLE__ /* MAC OS X */
+ rc = 1;
+ setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *) &rc, sizeof(rc));
+# endif
+ memset((char *) &addr, 0x0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons((short) port);
+ addr.sin_addr.s_addr = inet_addr(ip);
+ rc = connect(fd, (struct sockaddr *) &addr, sizeof(addr));
+ if (rc < 0)
+ {
+ close(fd);
+ perror("connect()");
+ *err = SOCKET_ERRNO;
+ }
+ else
+ {
+ *err = 0;
+ }
+ return fd;
}
-
#else
/******************************************************************************/
/*
- Stub main for compiling without client enabled
-*/
+ Stub main for compiling without client enabled
+ */
int32 main(int32 argc, char **argv)
{
- printf("USE_CLIENT_SIDE_SSL must be enabled in matrixsslConfig.h at build" \
- " time to run this application\n");
- return EXIT_FAILURE;
+ printf("USE_CLIENT_SIDE_SSL must be enabled in matrixsslConfig.h at build" \
+ " time to run this application\n");
+ return EXIT_FAILURE;
}
#endif /* USE_CLIENT_SIDE_SSL */
diff --git a/apps/ssl/http.c b/apps/ssl/http.c
index 110d3d9..7823b93 100644
--- a/apps/ssl/http.c
+++ b/apps/ssl/http.c
@@ -1,136 +1,167 @@
/**
- * @file http.c
- * @version $Format:%h%d$
+ * @file http.c
+ * @version $Format:%h%d$
*
- * Simple INCOMPLETE HTTP parser for example applications.
+ * Simple INCOMPLETE HTTP parser for example applications.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#include "app.h"
-//#define TEST
+/* Currently this example uses _psTrace for tracing, so osdep.h is needed: */
+#include "core/osdep.h"
+#include "core/psUtil.h"
+
+/* #define TEST */
/******************************************************************************/
/*
- EXAMPLE ONLY - SHOULD NOT BE USED FOR PRODUCTION CODE
+ EXAMPLE ONLY - SHOULD NOT BE USED FOR PRODUCTION CODE
- Process an HTTP request from a client.
- Very simple - we just print it, and return success.
- No HTTP validation at all is done on the data.
+ Process an HTTP request from a client.
+ Very simple - we just print it, and return success.
+ No HTTP validation at all is done on the data.
*/
int32 httpBasicParse(httpConn_t *cp, unsigned char *buf, uint32 len,
- int32 trace)
+ int32 trace)
{
- unsigned char *c, *end, *tmp;
- int32 l;
+ unsigned char *c, *end, *tmp;
+ int32 l;
- /*
- SSL/TLS can provide zero length records, which we just ignore here
- because the code below assumes we have at least one byte
- */
- if (len == 0) {
- return HTTPS_PARTIAL;
- }
+ /*
+ SSL/TLS can provide zero length records, which we just ignore here
+ because the code below assumes we have at least one byte
+ */
+ if (len == 0)
+ {
+ return HTTPS_PARTIAL;
+ }
- c = buf;
- end = c + len;
+ c = buf;
+ end = c + len;
/*
- If we have an existing partial HTTP buffer, append to it the data in buf
- up to the first newline, or 'len' data, if no newline is in buf.
+ If we have an existing partial HTTP buffer, append to it the data in buf
+ up to the first newline, or 'len' data, if no newline is in buf.
*/
- if (cp->parsebuf != NULL) {
- for (tmp = c; c < end && *c != '\n'; c++);
- /* We want c to point to 'end' or to the byte after \r\n */
- if (*c == '\n') {
- c++;
- }
- l = (int32)(c - tmp);
- if (l > HTTPS_BUFFER_MAX) {
- return HTTPS_ERROR;
- }
- cp->parsebuf = realloc(cp->parsebuf, l + cp->parsebuflen);
- memcpy(cp->parsebuf + cp->parsebuflen, tmp, l);
- cp->parsebuflen += l;
- /* Parse the data out of the saved buffer first */
- c = cp->parsebuf;
- end = c + cp->parsebuflen;
- /* We've "moved" some data from buf into parsebuf, so account for it */
- buf += l;
- len -= l;
- }
+ if (cp->parsebuf != NULL)
+ {
+ for (tmp = c; c < end && *c != '\n'; c++)
+ {
+ ;
+ }
+ /* We want c to point to 'end' or to the byte after \r\n */
+ if (*c == '\n')
+ {
+ c++;
+ }
+ l = (int32) (c - tmp);
+ if (l > HTTPS_BUFFER_MAX)
+ {
+ return HTTPS_ERROR;
+ }
+ cp->parsebuf = realloc(cp->parsebuf, l + cp->parsebuflen);
+ memcpy(cp->parsebuf + cp->parsebuflen, tmp, l);
+ cp->parsebuflen += l;
+ /* Parse the data out of the saved buffer first */
+ c = cp->parsebuf;
+ end = c + cp->parsebuflen;
+ /* We've "moved" some data from buf into parsebuf, so account for it */
+ buf += l;
+ len -= l;
+ }
L_PARSE_LINE:
- for (tmp = c; c < end && *c != '\n'; c++);
- if (c < end) {
- if (*(c - 1) != '\r') {
- return HTTPS_ERROR;
- }
- /* If the \r\n started the line, we're done reading headers */
- if (*tmp == '\r' && (tmp + 1 == c)) {
+ for (tmp = c; c < end && *c != '\n'; c++)
+ {
+ ;
+ }
+ if (c < end)
+ {
+ if (*(c - 1) != '\r')
+ {
+ return HTTPS_ERROR;
+ }
+ /* If the \r\n started the line, we're done reading headers */
+ if (*tmp == '\r' && (tmp + 1 == c))
+ {
/*
- if ((c + 1) != end) {
- _psTrace("HTTP data parsing not supported, ignoring.\n");
- }
-*/
- if (cp->parsebuf != NULL) {
- free(cp->parsebuf); cp->parsebuf = NULL;
- cp->parsebuflen = 0;
- if (len != 0) {
- _psTrace("HTTP data parsing not supported, ignoring.\n");
- }
- }
- if (trace) _psTrace("RECV COMPLETE HTTP MESSAGE\n");
- return HTTPS_COMPLETE;
- }
- } else {
- /* If parsebuf is non-null, we have already saved it */
- if (cp->parsebuf == NULL && (l = (int32)(end -tmp)) > 0) {
- cp->parsebuflen = l;
- cp->parsebuf = malloc(cp->parsebuflen);
- psAssert(cp->parsebuf != NULL);
- memcpy(cp->parsebuf, tmp, cp->parsebuflen);
- }
- return HTTPS_PARTIAL;
- }
- *(c - 1) = '\0'; /* Replace \r with \0 just for printing */
- if (trace) _psTraceStr("RECV PARSED: [%s]\n", (char *)tmp);
- /* Finished parsing the saved buffer, now start parsing from incoming buf */
- if (cp->parsebuf != NULL) {
- free(cp->parsebuf); cp->parsebuf = NULL;
- cp->parsebuflen = 0;
- c = buf;
- end = c + len;
- } else {
- c++; /* point c to the next char after \r\n */
- }
- goto L_PARSE_LINE;
+ if ((c + 1) != end) {
+ _psTrace("HTTP data parsing not supported, ignoring.\n");
+ }
+ */
+ if (cp->parsebuf != NULL)
+ {
+ free(cp->parsebuf); cp->parsebuf = NULL;
+ cp->parsebuflen = 0;
+ if (len != 0)
+ {
+ _psTrace("HTTP data parsing not supported, ignoring.\n");
+ }
+ }
+ if (trace)
+ {
+ _psTrace("RECV COMPLETE HTTP MESSAGE\n");
+ }
+ return HTTPS_COMPLETE;
+ }
+ }
+ else
+ {
+ /* If parsebuf is non-null, we have already saved it */
+ if (cp->parsebuf == NULL && (l = (int32) (end - tmp)) > 0)
+ {
+ cp->parsebuflen = l;
+ cp->parsebuf = malloc(cp->parsebuflen);
+ psAssert(cp->parsebuf != NULL);
+ memcpy(cp->parsebuf, tmp, cp->parsebuflen);
+ }
+ return HTTPS_PARTIAL;
+ }
+ *(c - 1) = '\0'; /* Replace \r with \0 just for printing */
+ if (trace)
+ {
+ _psTraceStr("RECV PARSED: [%s]\n", (char *) tmp);
+ }
+ /* Finished parsing the saved buffer, now start parsing from incoming buf */
+ if (cp->parsebuf != NULL)
+ {
+ free(cp->parsebuf); cp->parsebuf = NULL;
+ cp->parsebuflen = 0;
+ c = buf;
+ end = c + len;
+ }
+ else
+ {
+ c++; /* point c to the next char after \r\n */
+ }
+ goto L_PARSE_LINE;
- return HTTPS_ERROR;
+ return HTTPS_ERROR;
}
/******************************************************************************/
diff --git a/apps/ssl/net.c b/apps/ssl/net.c
new file mode 100644
index 0000000..c4d32a5
--- /dev/null
+++ b/apps/ssl/net.c
@@ -0,0 +1,934 @@
+/* net.c
+ *
+ * Generic networking tool.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2017 INSIDE Secure Oy. All Rights Reserved.
+*
+* This confidential and proprietary software may be used only as authorized
+* by a licensing agreement from INSIDE Secure.
+*
+* The entire notice above must be reproduced on all authorized copies that
+* may only be made to the extent permitted by a licensing agreement from
+* INSIDE Secure.
+*****************************************************************************/
+
+#include
+#include
+#include
+#include
+#include "core/coreApi.h"
+#include "matrixssl/matrixsslApi.h"
+#include "matrixssl/matrixsslNet.h"
+#include "matrixssl/matrixsslSocket.h"
+/* Currently this example uses _psTrace for tracing, so osdep.h is needed: */
+#include "core/osdep.h"
+#include "core/psUtil.h"
+
+#define USE_MATRIX_NET_DEBUG
+#undef DEBUGF /* Protect against possible multiple definition. */
+#ifdef USE_MATRIX_NET_DEBUG
+# define DEBUGF(...) printf(__VA_ARGS__)
+#else
+# define DEBUGF(...) do {} while (0)
+#endif
+
+#if defined(USE_PS_NETWORKING) && !defined(USE_ONLY_PSK_CIPHER_SUITE)
+
+/* The flags used by this program for TLS versions. */
+# define FLAG_TLS_1_0 (1 << 10)
+# define FLAG_TLS_1_1 (1 << 11)
+# define FLAG_TLS_1_2 (1 << 12)
+
+/* Highlight text from peer. */
+static char start_remote_text[] = "\033[1m";
+static char end_remote_text[] = "\033[0m";
+
+static int g_ciphers = 1;
+static uint16_t g_cipher[] = { 47 };
+
+# define HTTP_BUFFER_SIZE (1024 * 1024)
+
+# define logMessage(l, t, ...) do { printf(#l " " #t ": " __VA_ARGS__); printf("\n"); } while (0) /* Log_Verbose, TAG, "Wrote %d bytes", transferred */
+
+static int usage(FILE *out, const char *program)
+{
+ fprintf(out, "usage: %s [options]\n", program);
+ fprintf(out, "Where options may include: ");
+ fprintf(out, "\t--help (-h) Get this usage\n");
+ fprintf(out, "\t--host hostname Specify host or address\n");
+ fprintf(out, "\t--port port Specify target port\n");
+ fprintf(out, "\t--get http://url/ Get URL (supports HTTP protocol)\n");
+ return 0;
+}
+
+/* Get the first argument from arguments. */
+static
+int option(int *argc_p, char ***argv_p, const char *opt, char **target)
+{
+ if (*argc_p == 1)
+ {
+ return 0; /* No arguments. */
+ }
+ if (*argc_p == 2 && target != NULL)
+ {
+ return 0; /* No space for argument with string. */
+
+ }
+ if (strcmp((*argv_p)[1], opt) == 0)
+ {
+ (*argc_p) -= 1;
+ (*argv_p)[1] = (*argv_p)[0];
+ (*argv_p) += 1;
+
+ if (target != NULL)
+ {
+ *target = (*argv_p)[1];
+ (*argc_p) -= 1;
+ (*argv_p)[1] = (*argv_p)[0];
+ (*argv_p) += 1;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+extern const char *capath_global;
+extern int tls_global;
+
+static int32 getHTTPResponse(const char *url,
+ unsigned char *httpResponseBuf,
+ size_t *httpResponseBufLen_p,
+ psSocketType_t type,
+ void *typespecific,
+ const psSocketFunctions_t *func)
+{
+ int32 err;
+ psUrlInteractState_t state = { type, typespecific, func };
+
+ /* HTTP headers for HTTP request/response. */
+ static const char *http_request_headers[] = {
+ "User-Agent"
+ };
+
+ static const char *http_request_header_values[] = {
+ "Basic-HTTP-Request/1.0"
+ };
+
+ err = psUrlInteract("GET", url,
+ http_request_headers,
+ http_request_header_values, 1,
+ NULL, 0,
+ NULL, NULL, NULL, 0,
+ httpResponseBuf, httpResponseBufLen_p, &state);
+
+ return err;
+}
+
+int do_get(const char *url, psSocketType_t type,
+ const char *capath, int tls_version)
+{
+ void *buf = malloc(HTTP_BUFFER_SIZE);
+ size_t bufsz = HTTP_BUFFER_SIZE;
+ int32 res;
+ struct psSocketTls tls = { capath, tls_version };
+ void *typespecific = &tls;
+ const psSocketFunctions_t *func = NULL;
+
+ if (type == PS_SOCKET_TLS)
+ {
+ func = psGetSocketFunctionsTLS();
+ }
+ else
+ {
+ typespecific = NULL;
+ }
+
+ if (!buf)
+ {
+ fprintf(stderr, "Unable to allocate buffer %d bytes\n",
+ HTTP_BUFFER_SIZE);
+ return 2;
+ }
+
+ res = getHTTPResponse(url, buf, &bufsz, type, typespecific, func);
+ if (res == PS_INSECURE_PROTOCOL)
+ {
+ fprintf(stderr, "Do not try to use capath or tls version with http protocol\n");
+ fprintf(stderr, "these are for https protocol.\n");
+ exit(1);
+ }
+ else if (res < 0)
+ {
+ /* Connection error. */
+ fprintf(stderr, "Connect error: %d\n", res);
+ }
+ else if (res != 0)
+ {
+ /* HTTP error. */
+ fprintf(stderr, "HTTP return code: %d\n", res);
+ }
+ else if (res == 0)
+ {
+ /* Write output (HTTP code 200 OK). */
+ fwrite(buf, bufsz, 1, stdout);
+ }
+ return res >= 0 ? 0 : 1;
+}
+
+# include
+
+int do_dialog(psSocket_t *sock)
+{
+ int32 rc;
+ unsigned char ch512[512];
+ unsigned char ch1024[1024];
+ psBuf_t buf;
+ psBuf_t buf2;
+
+ /* loop: send and receive. */
+ do
+ {
+ static int count = 0;
+ fd_set fds;
+ int sockfd = psSocketGetFd(sock);
+
+ FD_ZERO(&fds);
+ FD_SET(STDIN_FILENO, &fds);
+ FD_SET(sockfd, &fds);
+ select(sockfd + 1, &fds, NULL, NULL, NULL);
+ DEBUGF("an fd ready: stdin: %d sock_read: %d\n",
+ FD_ISSET(STDIN_FILENO, &fds),
+ FD_ISSET(sockfd, &fds));
+ if (count++ == 100000)
+ {
+ printf("Finished\n");
+ return 1;
+ }
+ buf.buf = buf.start = buf.end = ch1024;
+ buf.size = (uint32) sizeof(ch1024);
+ rc = psSocketReadAppendBuf(sock, &buf, PS_SOCKET_OPTION_NONBLOCK);
+ printf("Got SOCK bytes: %d\n", rc);
+ if (rc == 0)
+ {
+ printf("Peer disconnected\n");
+ return 0;
+ }
+ else if (rc > 0)
+ {
+ printf("%s%.*s%s",
+ start_remote_text,
+ (int) (buf.end - buf.start),
+ (const char *) buf.start,
+ end_remote_text);
+ }
+ psSocketSetOptions(sock, PS_SOCKET_OPTION_BLOCK);
+
+ buf2.buf = buf2.start = buf2.end = ch512;
+ buf2.size = (uint32) sizeof(ch512);
+ buf.buf = buf.start = buf.end = ch1024;
+ buf.size = (uint32) sizeof(ch1024);
+ rc = psSocketReadAppendBuf(STDIN_FILENO, &buf2,
+ PS_SOCKET_OPTION_NONBLOCK);
+ printf("Got STDIN bytes: %d\n", rc);
+ if (rc == 0)
+ {
+ printf("Quit from keyboard\n");
+ return 0;
+ }
+ /* Copy input to send buffer. */
+ if (rc > 0)
+ {
+ while (buf2.start != buf2.end)
+ {
+ unsigned char uch = *(buf2.start++);
+ if (uch == '\n')
+ {
+ *(buf.end++) = '\r';
+ }
+ *(buf.end++) = uch;
+ }
+
+ if (psSocketWriteShiftBuf(sock, &buf, 0) < 1)
+ {
+ fprintf(stderr, "Connection error\n");
+ return 1;
+ }
+ }
+ }
+ while (1);
+ return rc;
+}
+
+int do_dialog_matrixssl(matrixSslInteract_t *msi_p)
+{
+ int32 rc;
+ unsigned char ch512[512];
+ unsigned char ch1024[1024];
+ psBuf_t buf;
+ psBuf_t buf2;
+ psSocket_t *sock = msi_p->sock;
+
+ /* loop: send and receive. */
+ do
+ {
+ static int count = 0;
+ fd_set fds;
+ fd_set except_fds;
+ int sockfd = psSocketGetFd(sock);
+
+ FD_ZERO(&fds);
+ FD_ZERO(&except_fds);
+ FD_SET(STDIN_FILENO, &fds);
+ FD_SET(STDIN_FILENO, &except_fds);
+ FD_SET(sockfd, &fds);
+ select(sockfd + 1, &fds, NULL, NULL, NULL);
+ DEBUGF("an fd ready stdin: %d sock_read: %d\n",
+ FD_ISSET(STDIN_FILENO, &fds),
+ FD_ISSET(sockfd, &fds));
+
+ if (count++ == 2000000000)
+ {
+ printf("Finished\n");
+ return 1;
+ }
+ buf.buf = buf.start = buf.end = ch1024;
+ buf.size = (uint32) sizeof(ch1024);
+ rc = matrixSslInteract(msi_p, PS_FALSE, PS_TRUE);
+ if (rc == MATRIXSSL_RECEIVED_ALERT)
+ {
+alert_handler:
+ if (msi_p->ch2[0] == 1 && msi_p->ch2[1] == 0)
+ {
+ printf("Peer terminated connection.\n");
+ psSocketShutdown(sock, 0);
+ matrixSslInteractClose(msi_p);
+ return 0;
+ }
+
+ fprintf(stderr, "Got alert: level=%d desc=%d\n",
+ (int) msi_p->ch2[0], (int) msi_p->ch2[1]);
+ return 1;
+ }
+ if (rc == MATRIXSSL_NET_DISCONNECTED)
+ {
+ fprintf(stderr, "The peer has disconnected\n");
+ exit(0);
+ }
+ if (rc < 0)
+ {
+ fprintf(stderr, "matrixSslInteract error: %d\n",
+ (int) rc);
+ exit(1);
+ }
+again_read:
+ if (rc == MATRIXSSL_APP_DATA &&
+ matrixSslInteractReadLeft(msi_p))
+ {
+ rc = matrixSslInteractRead(
+ msi_p, buf.end,
+ buf.buf + buf.size - buf.end);
+ if (rc < 0)
+ {
+ fprintf(stderr, "Read error: rc=%d\n", rc);
+ return 1;
+ }
+ DEBUGF("Interact read gave %d\n", (int) rc);
+ printf("%s", start_remote_text);
+ printf("%.*s", (int) (rc), (const char *) buf.start);
+ printf("%s", end_remote_text);
+ fflush(stdout);
+ }
+ psSocketSetOptions(sock, PS_SOCKET_OPTION_BLOCK);
+
+ buf2.buf = buf2.start = buf2.end = ch512;
+ buf2.size = (uint32) sizeof(ch512);
+ buf.buf = buf.start = buf.end = ch1024;
+ buf.size = (uint32) sizeof(ch1024);
+ if (!FD_ISSET(STDIN_FILENO, &fds) &&
+ !FD_ISSET(STDIN_FILENO, &except_fds))
+ {
+ goto no_kbd_input;
+ }
+ rc = psSocketReadAppendBuf(STDIN_FILENO, &buf2,
+ PS_SOCKET_OPTION_NONBLOCK);
+ if (rc > 0)
+ {
+ DEBUGF("Got STDIN bytes: %d\n", rc);
+ }
+ else if (rc < 0 && rc != PS_EAGAIN)
+ {
+ DEBUGF("Got STDIN read error: %d\n", rc);
+ }
+ if (rc == 0)
+ {
+ printf("Quit from keyboard\n");
+ return 0;
+ }
+ /* Copy input to send buffer. */
+ if (rc > 0)
+ {
+ while (buf2.start != buf2.end)
+ {
+ unsigned char uch = *(buf2.start++);
+ if (uch == '\n')
+ {
+ *(buf.end++) = '\r';
+ }
+ *(buf.end++) = uch;
+ }
+
+ DEBUGF("Interact write %d bytes {%.*s}\n",
+ (int) (buf.end - buf.start),
+ (int) (buf.end - buf.start),
+ (const char *) buf.start);
+
+ if (matrixSslInteractWrite(msi_p,
+ buf.start,
+ buf.end - buf.start) < 0)
+ {
+ fprintf(stderr, "Connection error\n");
+ return 1;
+ }
+ /* Mark the buffer as handled. */
+ buf2.start = buf2.end;
+ }
+
+no_kbd_input:
+ /* Forward packets sent, if necessary. */
+ rc = matrixSslInteract(msi_p, PS_TRUE, PS_FALSE);
+ if (rc == MATRIXSSL_RECEIVED_ALERT)
+ {
+ goto alert_handler;
+ }
+ if (matrixSslInteractReadLeft(msi_p))
+ {
+ rc = MATRIXSSL_APP_DATA;
+ goto again_read;
+ }
+ if (rc == MATRIXSSL_NET_DISCONNECTED)
+ {
+ fprintf(stderr, "The peer has disconnected\n");
+ exit(0);
+ }
+ }
+ while (1);
+ return rc;
+}
+
+int do_dialog_client(const char *host, const char *port)
+{
+ int32 rc;
+ psSocket_t *sock;
+
+ rc = psSocketConnect(host, port, 0, PS_SOCKET_STREAM, NULL, NULL, &sock);
+ if (rc == PS_SUCCESS)
+ {
+ printf("Connected to %s:%s\n", host, port);
+ return do_dialog(sock);
+ }
+ printf("Unable to connect\n");
+ return 2;
+}
+
+/* The MatrixSSL certificate validation callback. */
+int32 ssl_cert_auth(ssl_t *ssl, psX509Cert_t *cert, int32 alert)
+{
+ return MATRIXSSL_SUCCESS;
+}
+
+# ifdef USE_CLIENT_SIDE_SSL
+static int32 extensionCb(ssl_t *ssl, uint16_t extType, uint8_t extLen, void *e)
+{
+
+ if (extType == EXT_SNI)
+ {
+ logMessage(Log_Info, TAG, "SNI extension callback called");
+ }
+ return PS_SUCCESS;
+}
+# endif /* USE_CLIENT_SIDE_SSL */
+
+
+int32 do_tls_handshake(matrixSslInteract_t *msi_p, int32 rc)
+{
+ fd_set fds;
+
+ if (rc < PS_SUCCESS)
+ {
+ return rc;
+ }
+
+
+ do
+ {
+ int sockfd = psSocketGetFd(msi_p->sock);
+ if (rc == MATRIXSSL_REQUEST_RECV)
+ {
+ DEBUGF("wait for data from peer\n");
+ FD_ZERO(&fds);
+ FD_SET(sockfd, &fds);
+ select(sockfd + 1, &fds, NULL, NULL, NULL);
+ }
+ else if (rc == MATRIXSSL_REQUEST_SEND ||
+ msi_p->send_len_left > 0)
+ {
+ DEBUGF("wait for sending data to peer\n");
+ FD_ZERO(&fds);
+ FD_SET(sockfd, &fds);
+ select(sockfd + 1, NULL, &fds, NULL, NULL);
+ }
+/* if (rc != 0) */
+ DEBUGF("hs rc code: %d\n", rc);
+ if (rc == MATRIXSSL_REQUEST_RECV)
+ {
+ rc = matrixSslInteractHandshake(msi_p, PS_FALSE, PS_TRUE);
+ }
+ else
+ {
+ rc = matrixSslInteractHandshake(msi_p, PS_TRUE, PS_TRUE);
+ }
+ DEBUGF("hs msi rc code: %d\n", rc);
+ }
+ while (rc > PS_SUCCESS && rc != MATRIXSSL_RECEIVED_ALERT);
+ return rc;
+}
+
+static void set_tls_options_version(sslSessOpts_t *options_p, int tls)
+{
+ if ((tls & FLAG_TLS_1_0) || tls == 0)
+ {
+ options_p->versionFlag |= SSL_FLAGS_TLS_1_0;
+ }
+ if ((tls & FLAG_TLS_1_1) || tls == 0)
+ {
+ options_p->versionFlag |= SSL_FLAGS_TLS_1_1;
+ }
+ if ((tls & FLAG_TLS_1_2) || tls == 0)
+ {
+ options_p->versionFlag |= SSL_FLAGS_TLS_1_2;
+ }
+}
+
+# ifdef USE_CLIENT_SIDE_SSL
+int do_dialog_client_tls(const char *host, const char *port,
+ const char *capath, int tls)
+{
+ int32 rc;
+ sslSessOpts_t options;
+ sslKeys_t *keys = NULL;
+ sslSessionId_t *sid = NULL;
+ matrixSslInteract_t msi;
+ tlsExtension_t *extension;
+ unsigned char *ext = NULL;
+ int32 extLen;
+
+ memset(&options, 0x0, sizeof(sslSessOpts_t));
+ set_tls_options_version(&options, tls);
+
+ if (matrixSslOpen() < 0)
+ {
+ fprintf(stderr, "Error initializing MatrixSSL\n");
+ return 3;
+ }
+
+ if (matrixSslNewKeys(&keys, NULL) < 0)
+ {
+ fprintf(stderr, "Error initializing MatrixSSL: "
+ "matrixSslNewKeys error\n");
+ return 3;
+ }
+ if (matrixSslNewSessionId(&sid, NULL) < 0)
+ {
+ fprintf(stderr, "Error initializing MatrixSSL: "
+ "matrixSslNewSessionId error\n");
+ return 3;
+ }
+
+ if (capath != NULL)
+ {
+# ifdef USE_RSA
+ rc = matrixSslLoadRsaKeys(keys, NULL, NULL, NULL, capath);
+# else
+# ifdef USE_ECC
+ rc = matrixSslLoadEcKeys(keys, NULL, NULL, NULL, capath);
+# else
+# error either USE_RSA or USE_ECC needed in net.c
+# endif
+# endif
+ if (rc != PS_SUCCESS)
+ {
+ fprintf(stderr, "No certificate material loaded.\n");
+ matrixSslDeleteSessionId(sid);
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ return rc;
+ }
+ }
+
+ matrixSslNewHelloExtension(&extension, NULL);
+ matrixSslCreateSNIext(NULL, (unsigned char *) host, (uint32) strlen(host),
+ &ext, &extLen);
+ if (ext)
+ {
+ matrixSslLoadHelloExtension(extension, ext, extLen, EXT_SNI);
+ psFree(ext, NULL);
+ }
+
+ rc = matrixSslInteractBeginConnected(&msi, host, port, 0, NULL,
+ keys, sid,
+ g_cipher, g_ciphers,
+ ssl_cert_auth, NULL,
+ extension,
+ extensionCb, &options);
+ matrixSslDeleteHelloExtension(extension);
+
+ if (rc >= PS_SUCCESS)
+ {
+ /* Interact until connected. */
+ printf("Connected to %s:%s (using TLS)\n", host, port);
+ rc = do_tls_handshake(&msi, rc);
+ if (rc == MATRIXSSL_REQUEST_CLOSE)
+ {
+ printf("Connection close requested.\n");
+ exit(1);
+ }
+ if (rc != PS_SUCCESS)
+ {
+ printf("Handshake failure: %d\n", rc);
+ exit(1);
+ }
+ printf("Successful handshake\n");
+
+ rc = do_dialog_matrixssl(&msi);
+
+ /* Free all allocated/opened resources. */
+ matrixSslDeleteSessionId(sid);
+
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ printf("Closed down\n");
+ return rc;
+ }
+ printf("Unable to connect\n");
+
+ /* Free all allocated/opened resources. */
+ matrixSslDeleteSessionId(sid);
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+
+ return 2;
+}
+# endif /* USE_CLIENT_SIDE_SSL */
+
+int do_dialog_server(const char *host, const char *port)
+{
+ int32 rc;
+ psSocket_t *sock;
+ psSocket_t *sock2;
+
+ rc = psSocketListen(host, port, 0, 0, PS_SOCKET_STREAM, NULL, NULL, &sock);
+ if (rc == PS_SUCCESS)
+ {
+ printf("Waiting for connection\n");
+ rc = psSocketAccept(sock, 0, &sock2);
+ printf("Connected.\n");
+ rc = do_dialog(sock2);
+ psSocketShutdown(sock, 0);
+ return rc;
+ }
+ printf("Cannot listen to specified address/port\n");
+ return 2;
+}
+
+# ifdef USE_STATELESS_SESSION_TICKETS
+static int32 sessTicketCb(void *keys, unsigned char name[16], short found);
+
+static unsigned char sessTicketSymKey[32] = { 0 };
+static unsigned char sessTicketMacKey[32] = { 0 };
+# endif
+
+# ifdef USE_STATELESS_SESSION_TICKETS
+int32 sessTicketCb(void *keys, unsigned char name[16], short found)
+{
+ if (found)
+ {
+ /* Was already cached */
+ return PS_SUCCESS;
+ }
+ /* Example. If name was located, the keys would be loaded this way */
+ return matrixSslLoadSessionTicketKeys((sslKeys_t *) keys, name,
+ sessTicketSymKey, 32, sessTicketMacKey, 32);
+}
+# endif
+
+# ifdef USE_SERVER_SIDE_SSL
+int do_dialog_server_tls(const char *host, const char *port,
+ const char *certpath, const char *keypath,
+ const char *capath, int tls)
+{
+ int32 rc;
+ psSocket_t *sock;
+ sslSessOpts_t options;
+ sslKeys_t *keys = NULL;
+ matrixSslInteract_t msi;
+
+# ifdef USE_STATELESS_SESSION_TICKETS
+ unsigned char sessTicketName[16];
+# endif
+
+ memset(&options, 0x0, sizeof(sslSessOpts_t));
+ set_tls_options_version(&options, tls);
+
+ if (matrixSslOpen() < 0)
+ {
+ fprintf(stderr, "Error initializing MatrixSSL\n");
+ return 3;
+ }
+
+ if (matrixSslNewKeys(&keys, NULL) < 0)
+ {
+ fprintf(stderr, "Error initializing MatrixSSL: "
+ "matrixSslNewKeys error\n");
+ return 3;
+ }
+
+ options.userPtr = keys;
+
+# ifdef USE_STATELESS_SESSION_TICKETS
+ matrixSslSetSessionTicketCallback(keys, sessTicketCb);
+ if (psGetPrngLocked(sessTicketSymKey,
+ sizeof(sessTicketSymKey), NULL) < 0 ||
+ psGetPrngLocked(sessTicketMacKey,
+ sizeof(sessTicketMacKey), NULL) < 0 ||
+ psGetPrngLocked(sessTicketName,
+ sizeof(sessTicketName), NULL) < 0)
+ {
+ _psTrace("Error generating session ticket encryption key\n");
+ return EXIT_FAILURE;
+ }
+
+ if (matrixSslLoadSessionTicketKeys(keys, sessTicketName,
+ sessTicketSymKey, 32,
+ sessTicketMacKey, 32) < 0)
+ {
+ _psTrace("Error loading session ticket encryption key\n");
+ }
+# endif
+
+# ifdef USE_RSA
+ rc = matrixSslLoadRsaKeys(keys, certpath, keypath, NULL, capath);
+# else
+# ifdef USE_ECC
+ rc = matrixSslLoadEcKeys(keys, certpath, keypath, NULL, capath);
+# else
+# error either USE_RSA or USE_ECC needed in net.c
+# endif
+# endif
+ if (rc < 0)
+ {
+ _psTrace("Unable to load static key material. Exiting\n");
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ return rc;
+ }
+
+ rc = psSocketListen(host, port, 0, 0, PS_SOCKET_STREAM, NULL, NULL, &sock);
+ if (rc == PS_SUCCESS)
+ {
+ printf("Waiting for connection\n");
+ rc = matrixSslInteractBeginAccept(&msi, sock, 0,
+ keys, NULL, &options);
+ if (rc < 0)
+ {
+ printf("Accept failed\n");
+ exit(1);
+ }
+
+ if (rc >= PS_SUCCESS)
+ {
+ /* Interact until connected. */
+ printf("Client connected\n");
+ /* TOOD: Fake read needed. */
+ rc = do_tls_handshake(&msi,
+ MATRIXSSL_REQUEST_RECV);
+ if (rc == MATRIXSSL_REQUEST_CLOSE)
+ {
+ printf("Connection close requested.\n");
+ exit(1);
+ }
+ if (rc != PS_SUCCESS)
+ {
+ printf("Handshake failure: %d\n", rc);
+ exit(1);
+ }
+ printf("Successful handshake\n");
+
+ rc = do_dialog_matrixssl(&msi);
+
+ /* Free all allocated/opened resources. */
+ matrixSslDeleteKeys(keys);
+ matrixSslClose();
+ printf("Closed down\n");
+ psSocketShutdown(sock, 0);
+ return rc;
+ }
+ }
+ printf("Cannot listen to specified address/port\n");
+ return 2;
+}
+# endif /* USE_SERVER_SIDE_SSL */
+
+int main(int argc, char **argv)
+{
+ int listen = 0;
+ int tls = 0;
+ int tls_version = 0;
+ char *host = NULL;
+ char *port = NULL;
+ char *get = NULL;
+ char *capath = NULL;
+ char *certpath = NULL;
+ char *keypath = NULL;
+
+ while (argc > 1)
+ {
+ if (option(&argc, &argv, "-h", NULL))
+ {
+ exit(usage(stdout, argv[0]));
+ }
+ else if (option(&argc, &argv, "--help", NULL))
+ {
+ exit(usage(stdout, argv[0]));
+ }
+ else if (option(&argc, &argv, "--host", &host))
+ {
+ ;
+ }
+ else if (option(&argc, &argv, "--port", &port))
+ {
+ ;
+ }
+ else if (option(&argc, &argv, "--get", &get))
+ {
+ ;
+ }
+ else if (option(&argc, &argv, "--tls", NULL))
+ {
+ tls = 1;
+ }
+ else if (option(&argc, &argv, "--tlsv10", NULL))
+ {
+ tls_version |= FLAG_TLS_1_0;
+ }
+ else if (option(&argc, &argv, "--tlsv11", NULL))
+ {
+ tls_version |= FLAG_TLS_1_1;
+ }
+ else if (option(&argc, &argv, "--tlsv12", NULL))
+ {
+ tls_version |= FLAG_TLS_1_2;
+ }
+ else if (option(&argc, &argv, "--capath", &capath))
+ {
+ tls = 1; /* CApath also enables tls. */
+ }
+ else if (option(&argc, &argv, "--cert", &certpath))
+ {
+ tls = 1; /* certpath also enables tls. */
+ }
+ else if (option(&argc, &argv, "--key", &keypath))
+ {
+ tls = 1; /* keypath also enables tls. */
+ }
+ else if (option(&argc, &argv, "--listen", NULL))
+ {
+ listen = 1;
+ }
+ else if (option(&argc, &argv, "--no-highlighting", NULL))
+ {
+ *start_remote_text = 0;
+ *end_remote_text = 0;
+ }
+ else
+ {
+ break;
+ }
+ }
+ if (argc > 1)
+ {
+ fprintf(stderr, "Invalid arguments: Unable to process %s\n",
+ argv[1]);
+ usage(stderr, argv[0]);
+ exit(1);
+ }
+ if (tls_version > 0)
+ {
+ tls = 1;
+ }
+
+ if (get != NULL && capath != NULL && tls)
+ {
+ exit(do_get(get, PS_SOCKET_TLS, capath, tls_version));
+ }
+ if (get != NULL)
+ {
+ exit(do_get(get, PS_SOCKET_STREAM, NULL, 0));
+ }
+ if (listen && port && certpath && keypath && tls)
+ {
+# ifdef USE_SERVER_SIDE_SSL
+ exit(do_dialog_server_tls(host, port,
+ certpath, keypath, capath,
+ tls_version));
+# else
+ fprintf(stderr, "USE_SERVER_SIDE_SSL required\n");
+ return EXIT_FAILURE;
+# endif
+ }
+ if (listen && port)
+ {
+ exit(do_dialog_server(host, port));
+ }
+ if (host && port && tls)
+ {
+# ifdef USE_CLIENT_SIDE_SSL
+ exit(do_dialog_client_tls(host, port, capath, tls_version));
+# else
+ fprintf(stderr, "USE_CLIENT_SIDE_SSL required\n");
+ return EXIT_FAILURE;
+# endif
+ }
+ if (host && port)
+ {
+ exit(do_dialog_client(host, port));
+ }
+
+ fprintf(stderr, "Invalid arguments\n");
+ usage(stderr, argv[0]);
+ exit(1);
+ return 0;
+}
+
+#else
+
+/******************************************************************************/
+/*
+ Stub main for compiling without proper options enabled
+ */
+int32 main(int32 argc, char **argv)
+{
+# ifndef USE_PS_NETWORKING
+ printf("USE_PS_NETWORKING must be enabled at build"
+ " time to run this application\n");
+# endif
+# ifdef USE_ONLY_PSK_CIPHER_SUITE
+ printf("This application is not compatible with"
+ " USE_ONLY_PSK_CIPHER_SUITE.\n");
+# endif
+ return 1;
+}
+#endif /* define USE_PS_NETWORKING */
+
+/* end of file net.c */
diff --git a/apps/ssl/net.sh b/apps/ssl/net.sh
new file mode 100755
index 0000000..02c7c95
--- /dev/null
+++ b/apps/ssl/net.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+set -e
+if [ -e apps/ssl ];then cd apps/ssl;fi
+
+set -x
+./matrixnet --help
+./matrixnet --get http://www.insidesecure.com/ || echo Failed expectedly.
+(./matrixnet --get http://essjira.insidesecure.com | fold -w 80 | head -10)
+(./matrixnet --get http://localhost/ | fold -w 80 | head -10)
+
+echo "Successful test for (matrix)net."
diff --git a/apps/ssl/server.c b/apps/ssl/server.c
index f1bb371..9b11b5a 100644
--- a/apps/ssl/server.c
+++ b/apps/ssl/server.c
@@ -1,113 +1,118 @@
/**
- * @file server.c
- * @version $Format:%h%d$
+ * @file server.c
+ * @version $Format:%h%d$
*
- * Simple non-blocking MatrixSSL server example for multiple connections.
- * Uses a single, hardcoded RSA identity. No client authentication.
+ * Simple non-blocking MatrixSSL server example for multiple connections.
+ * Uses a single, hardcoded RSA identity. No client authentication.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#include "app.h"
#include "matrixssl/matrixsslApi.h"
+/* Currently this example uses _psTrace for tracing, so osdep.h is needed: */
+#include "core/osdep.h"
+#include "core/psUtil.h"
#ifdef USE_SERVER_SIDE_SSL
-#ifdef MATRIX_USE_FILE_SYSTEM
+# ifdef MATRIX_USE_FILE_SYSTEM
-#include /* Defines SIGTERM, etc. */
+# include /* Defines SIGTERM, etc. */
-#ifdef WIN32
-#pragma message("DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS.")
-#else
-#warning "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
-#endif
+# ifndef MATRIX_TESTING_ENVIRONMENT /* Omit the message when testing. */
+# ifdef WIN32
+# pragma message("DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS.")
+# else
+# warning "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS."
+# endif
+# endif /* MATRIX_TESTING_ENVIRONMENT */
-#define ALLOW_ANON_CONNECTIONS 1
-#define SEND_CLOSURE_ALERT
+# define ALLOW_ANON_CONNECTIONS 1
+# define SEND_CLOSURE_ALERT
/* Default keys if nothing provided on command line */
-#define KEY_DIR "../../"
+# define KEY_DIR "../../"
const static char g_defaultCertFile[] = "testkeys/RSA/2048_RSA.pem";
const static char g_defaultPrivkeyFile[] = "testkeys/RSA/2048_RSA_KEY.pem";
const static char g_defaultCAFile[] = "testkeys/RSA/2048_RSA_CA.pem";
-#ifdef REQUIRE_DH_PARAMS
+# ifdef REQUIRE_DH_PARAMS
const static char g_defaultDHParamFile[] = "testkeys/DH/1024_DH_PARAMS.pem";
-#endif
+# endif
/********************************** Defines ***********************************/
-#define SSL_TIMEOUT 45000 /* In milliseconds */
-#define SELECT_TIME 1000 /* In milliseconds */
-#define RESPONSE_REC_LEN SSL_MAX_PLAINTEXT_LEN
+# define SSL_TIMEOUT 45000 /* In milliseconds */
+# define SELECT_TIME 1000 /* In milliseconds */
+# define RESPONSE_REC_LEN SSL_MAX_PLAINTEXT_LEN
-#define GOTO_SANITY 32 /* Must be <= 255 */
+# define GOTO_SANITY 32/* Must be <= 255 */
/*
- The ACCEPT_QUEUE is an optimization mechanism that allows the server to
- accept() up to this many connections before serving any of them. The
- reason is that the timeout waiting for the accept() is much shorter
- than the timeout for the actual processing.
-*/
-#define ACCEPT_QUEUE 16
+ The ACCEPT_QUEUE is an optimization mechanism that allows the server to
+ accept() up to this many connections before serving any of them. The
+ reason is that the timeout waiting for the accept() is much shorter
+ than the timeout for the actual processing.
+ */
+# define ACCEPT_QUEUE 16
/********************************** Globals ***********************************/
-static DLListEntry g_conns;
-static int32 g_exitFlag;
-static int g_port;
-static int g_version;
-static int g_disabledCiphers;
-static uint16_t g_disabledCipher[SSL_MAX_DISABLED_CIPHERS];
+static DLListEntry g_conns;
+static int32 g_exitFlag;
+static int g_port;
+static int g_version;
+static int g_disabledCiphers;
+static uint16_t g_disabledCipher[SSL_MAX_DISABLED_CIPHERS];
-#define MAX_KEYFILE_PATH 256
-#define MAX_PASSWORD_LEN MAX_KEYFILE_PATH
-static char g_keyfilePath[MAX_KEYFILE_PATH];
-static char g_privkeyFile[MAX_KEYFILE_PATH];
-static char g_identityCert[MAX_KEYFILE_PATH];
-static char g_dhParamFile[MAX_KEYFILE_PATH];
-static char g_caFile[MAX_KEYFILE_PATH];
-static char g_password[MAX_PASSWORD_LEN];
+# define MAX_KEYFILE_PATH 256
+# define MAX_PASSWORD_LEN MAX_KEYFILE_PATH
+static char g_keyfilePath[MAX_KEYFILE_PATH];
+static char g_privkeyFile[MAX_KEYFILE_PATH];
+static char g_identityCert[MAX_KEYFILE_PATH];
+static char g_dhParamFile[MAX_KEYFILE_PATH];
+static char g_caFile[MAX_KEYFILE_PATH];
+static char g_password[MAX_PASSWORD_LEN];
-static unsigned char g_httpResponseHdr[] = "HTTP/1.0 200 OK\r\n"
- "Server: MatrixSSL/" MATRIXSSL_VERSION "\r\n"
- "Pragma: no-cache\r\n"
- "Cache-Control: no-cache\r\n"
- "Content-type: text/plain\r\n"
- "Content-length: 9\r\n"
- "\r\n"
- "MatrixSSL";
+static unsigned char g_httpResponseHdr[] = "HTTP/1.0 200 OK\r\n"
+ "Server: MatrixSSL/" MATRIXSSL_VERSION "\r\n"
+ "Pragma: no-cache\r\n"
+ "Cache-Control: no-cache\r\n"
+ "Content-type: text/plain\r\n"
+ "Content-length: 9\r\n"
+ "\r\n"
+ "MatrixSSL";
-#ifdef USE_STATELESS_SESSION_TICKETS
+# ifdef USE_STATELESS_SESSION_TICKETS
static int32 sessTicketCb(void *keys, unsigned char name[16], short found);
static unsigned char sessTicketSymKey[32] = { 0 };
static unsigned char sessTicketMacKey[32] = { 0 };
-#endif
+# endif
/****************************** Local Functions *******************************/
@@ -117,1067 +122,1226 @@ static int setSocketOptions(SOCKET fd);
static SOCKET lsocketListen(short port, int32 *err);
static void closeConn(httpConn_t *cp, int32 reason);
-#ifdef POSIX
+# ifdef POSIX
static void sigsegv_handler(int i);
static void sigintterm_handler(int i);
static int32 sighandlers(void);
-#endif /* POSIX */
+# endif /* POSIX */
/************************ Handshake Callback Functions ************************/
/* A server will make use of a certificate callback if client authentication
- is being used. This callback will be invoked during the handshake to
- allow application level inspection of the client certificate and halt
- the connection if required. See the documentation for more information
- on the Certificte Callback function */
+ is being used. This callback will be invoked during the handshake to
+ allow application level inspection of the client certificate and halt
+ the connection if required. See the documentation for more information
+ on the Certificte Callback function */
int32_t certCb(ssl_t *ssl, psX509Cert_t *cert, int32_t alert)
{
- return alert;
+ return alert;
}
-#ifdef USE_STATELESS_SESSION_TICKETS
+# ifdef USE_STATELESS_SESSION_TICKETS
/* This callback will be invoked each time a client sends a session ticket and
- can be used as an opportunity for the application to locate and load the
- correct key or to void the ticket and revert to a full handshake. See
- the API documenation for matrixSslSetSessionTicketCallback for more info */
+ can be used as an opportunity for the application to locate and load the
+ correct key or to void the ticket and revert to a full handshake. See
+ the API documenation for matrixSslSetSessionTicketCallback for more info */
int32 sessTicketCb(void *keys, unsigned char name[16], short found)
{
- if (found) {
+ if (found)
+ {
/* Was already cached */
return PS_SUCCESS;
}
/* Example. If name was located, different keys would be loaded this way. Of course here
- we are loading the same keys already loaded. */
- return matrixSslLoadSessionTicketKeys((sslKeys_t*)keys, name,
- sessTicketSymKey, sizeof(sessTicketSymKey),
- sessTicketMacKey, sizeof(sessTicketMacKey));
+ we are loading the same keys already loaded. */
+ return matrixSslLoadSessionTicketKeys((sslKeys_t *) keys, name,
+ sessTicketSymKey, sizeof(sessTicketSymKey),
+ sessTicketMacKey, sizeof(sessTicketMacKey));
}
-#endif
+# endif
void SNIcallback(void *ssl, char *hostname, int32 hostnameLen,
- sslKeys_t **newKeys)
+ sslKeys_t **newKeys)
{
- ssl_t *lssl = ssl;
- *newKeys = lssl->keys;
+ ssl_t *lssl = ssl;
+
+ *newKeys = lssl->keys;
}
/******************************************************************************/
/**
- Display connections per second (if more than 0), at most once per second
-*/
-static uint64_t g_handshakes = 0;
+ Display connections per second (if more than 0), at most once per second
+ */
+static uint64_t g_handshakes = 0;
static void displayStats(void)
{
- static uint64_t s_handshakes = 0; /* last value displayed */
- static time_t s_t = (time_t)0; /* last time displayed */
- time_t t;
+ static uint64_t s_handshakes = 0; /* last value displayed */
+ static time_t s_t = (time_t) 0; /* last time displayed */
+ time_t t;
- if (g_handshakes > s_handshakes) {
- t = time(NULL);
- if (t > s_t) {
- printf("%u CPS\n",
- (uint32_t)(g_handshakes - s_handshakes) / (uint32_t)(t - s_t));
- s_handshakes = g_handshakes;
- s_t = t;
- }
- }
+ if (g_handshakes > s_handshakes)
+ {
+ t = time(NULL);
+ if (t > s_t)
+ {
+ printf("%u CPS\n",
+ (uint32_t) (g_handshakes - s_handshakes) / (uint32_t) (t - s_t));
+ s_handshakes = g_handshakes;
+ s_t = t;
+ }
+ }
}
/******************************************************************************/
/*
- Non-blocking socket event handler
- Wait one time in select for events on any socket
- This will accept new connections, read and write to sockets that are
- connected, and close sockets as required.
+ Non-blocking socket event handler
+ Wait one time in select for events on any socket
+ This will accept new connections, read and write to sockets that are
+ connected, and close sockets as required.
*/
static int32 selectLoop(sslKeys_t *keys, SOCKET lfd)
{
- httpConn_t *cp;
- psTime_t now;
- DLListEntry connsTmp;
- DLListEntry *pList;
+ httpConn_t *cp;
+ psTime_t now;
+ DLListEntry connsTmp;
+ DLListEntry *pList;
- fd_set readfd, writefd;
- struct timeval timeout;
- SOCKET fd, maxfd;
+ fd_set readfd, writefd;
+ struct timeval timeout;
+ SOCKET fd, maxfd;
- unsigned char *buf;
- int32 rc, len, transferred, val, specialAppData;
- unsigned char rSanity, wSanity, acceptSanity;
+ unsigned char *buf;
+ int32 rc, len, transferred, val, specialAppData;
+ unsigned char rSanity, wSanity, acceptSanity;
- sslSessOpts_t options;
+ sslSessOpts_t options;
- DLListInit(&connsTmp);
- rc = PS_SUCCESS;
- maxfd = INVALID_SOCKET;
- timeout.tv_sec = SELECT_TIME / 1000;
- timeout.tv_usec = (SELECT_TIME % 1000) * 1000;
- FD_ZERO(&readfd);
- FD_ZERO(&writefd);
+ DLListInit(&connsTmp);
+ rc = PS_SUCCESS;
+ maxfd = INVALID_SOCKET;
+ timeout.tv_sec = SELECT_TIME / 1000;
+ timeout.tv_usec = (SELECT_TIME % 1000) * 1000;
+ FD_ZERO(&readfd);
+ FD_ZERO(&writefd);
- /* Always set readfd for listening socket */
- FD_SET(lfd, &readfd);
- if (lfd > maxfd) {
- maxfd = lfd;
- }
+ /* Always set readfd for listening socket */
+ FD_SET(lfd, &readfd);
+ if (lfd > maxfd)
+ {
+ maxfd = lfd;
+ }
/*
- Check timeouts and set readfd and writefd for connections as required.
- We use connsTemp so that removal on error from the active iteration list
- doesn't interfere with list traversal
+ Check timeouts and set readfd and writefd for connections as required.
+ We use connsTemp so that removal on error from the active iteration list
+ doesn't interfere with list traversal
*/
- psGetTime(&now, NULL);
- while (!DLListIsEmpty(&g_conns)) {
- pList = DLListGetHead(&g_conns);
- cp = DLListGetContainer(pList, httpConn_t, List);
- DLListInsertTail(&connsTmp, &cp->List);
- /* If timeout != 0 msec ith no new data, close */
- if (cp->timeout && (psDiffMsecs(cp->time, now, NULL) >
- (int32)cp->timeout)) {
- closeConn(cp, PS_TIMEOUT_FAIL);
- continue; /* Next connection */
- }
- /* Always select for read */
- FD_SET(cp->fd, &readfd);
- /* Select for write if there's pending write data or connection */
- if (matrixSslGetOutdata(cp->ssl, NULL) > 0) {
- FD_SET(cp->fd, &writefd);
- }
- /* Housekeeping for maxsock in select call */
- if (cp->fd > maxfd) {
- maxfd = cp->fd;
- }
- }
+ psGetTime(&now, NULL);
+ while (!DLListIsEmpty(&g_conns))
+ {
+ pList = DLListGetHead(&g_conns);
+ cp = DLListGetContainer(pList, httpConn_t, List);
+ DLListInsertTail(&connsTmp, &cp->List);
+ /* If timeout != 0 msec ith no new data, close */
+ if (cp->timeout && (psDiffMsecs(cp->time, now, NULL) >
+ (int32) cp->timeout))
+ {
+ closeConn(cp, PS_TIMEOUT_FAIL);
+ continue; /* Next connection */
+ }
+ /* Always select for read */
+ FD_SET(cp->fd, &readfd);
+ /* Select for write if there's pending write data or connection */
+ if (matrixSslGetOutdata(cp->ssl, NULL) > 0)
+ {
+ FD_SET(cp->fd, &writefd);
+ }
+ /* Housekeeping for maxsock in select call */
+ if (cp->fd > maxfd)
+ {
+ maxfd = cp->fd;
+ }
+ }
- /* Use select to check for events on the sockets */
- if ((val = select(maxfd + 1, &readfd, &writefd, NULL, &timeout)) <= 0) {
- /* On error, restore global connections list */
- while (!DLListIsEmpty(&connsTmp)) {
- pList = DLListGetHead(&connsTmp);
- cp = DLListGetContainer(pList, httpConn_t, List);
- DLListInsertTail(&g_conns, &cp->List);
- }
- /* Select timeout */
- if (val == 0) {
- return PS_TIMEOUT_FAIL;
- }
- /* Woke due to interrupt */
- if (SOCKET_ERRNO == EINTR) {
- return PS_TIMEOUT_FAIL;
- }
- /* Should attempt to handle more errnos, such as EBADF */
- return PS_PLATFORM_FAIL;
- }
+ /* Use select to check for events on the sockets */
+ if ((val = select(maxfd + 1, &readfd, &writefd, NULL, &timeout)) <= 0)
+ {
+ /* On error, restore global connections list */
+ while (!DLListIsEmpty(&connsTmp))
+ {
+ pList = DLListGetHead(&connsTmp);
+ cp = DLListGetContainer(pList, httpConn_t, List);
+ DLListInsertTail(&g_conns, &cp->List);
+ }
+ /* Select timeout */
+ if (val == 0)
+ {
+ return PS_TIMEOUT_FAIL;
+ }
+ /* Woke due to interrupt */
+ if (SOCKET_ERRNO == EINTR)
+ {
+ return PS_TIMEOUT_FAIL;
+ }
+ /* Should attempt to handle more errnos, such as EBADF */
+ return PS_PLATFORM_FAIL;
+ }
- /* Check listener for new incoming socket connections */
- if (FD_ISSET(lfd, &readfd)) {
- for (acceptSanity = 0; acceptSanity < ACCEPT_QUEUE; acceptSanity++) {
- fd = accept(lfd, NULL, NULL);
- if (fd == INVALID_SOCKET) {
- break; /* Nothing more to accept; next listener */
- }
- if (setSocketOptions(fd) < 0) {
- close(fd);
- return PS_PLATFORM_FAIL;
- }
- cp = malloc(sizeof(httpConn_t));
- if (cp == NULL) {
- close(fd);
- return PS_MEM_FAIL;
- }
- memset(cp, 0x0, sizeof(httpConn_t));
+ /* Check listener for new incoming socket connections */
+ if (FD_ISSET(lfd, &readfd))
+ {
+ for (acceptSanity = 0; acceptSanity < ACCEPT_QUEUE; acceptSanity++)
+ {
+ fd = accept(lfd, NULL, NULL);
+ if (fd == INVALID_SOCKET)
+ {
+ break; /* Nothing more to accept; next listener */
+ }
+ if (setSocketOptions(fd) < 0)
+ {
+ close(fd);
+ return PS_PLATFORM_FAIL;
+ }
+ cp = malloc(sizeof(httpConn_t));
+ if (cp == NULL)
+ {
+ close(fd);
+ return PS_MEM_FAIL;
+ }
+ memset(cp, 0x0, sizeof(httpConn_t));
- memset(&options, 0x0, sizeof(sslSessOpts_t));
- options.userPtr = keys;
- //options.extendedMasterSecret = 1; /* Require */
+ memset(&options, 0x0, sizeof(sslSessOpts_t));
+ options.userPtr = keys;
+ /* options.extendedMasterSecret = 1; / * Require * / */
- if ((rc = matrixSslNewServerSession(&cp->ssl, keys, NULL,
- &options)) < 0) {
- close(fd);
- continue;
- }
- matrixSslRegisterSNICallback(cp->ssl, SNIcallback);
+ if ((rc = matrixSslNewServerSession(&cp->ssl, keys, NULL,
+ &options)) < 0)
+ {
+ close(fd);
+ continue;
+ }
+ matrixSslRegisterSNICallback(cp->ssl, SNIcallback);
- cp->fd = fd;
- cp->timeout = SSL_TIMEOUT;
- psGetTime(&cp->time, NULL);
- cp->parsebuf = NULL;
- cp->parsebuflen = 0;
- DLListInsertTail(&connsTmp, &cp->List);
- /* Fake that there is read data available, no harm if there isn't */
- FD_SET(cp->fd, &readfd);
-/* _psTraceInt("=== New Client %d ===\n", cp->fd); */
- }
- }
+ cp->fd = fd;
+ cp->timeout = SSL_TIMEOUT;
+ psGetTime(&cp->time, NULL);
+ cp->parsebuf = NULL;
+ cp->parsebuflen = 0;
+ DLListInsertTail(&connsTmp, &cp->List);
+ /* Fake that there is read data available, no harm if there isn't */
+ FD_SET(cp->fd, &readfd);
+/* _psTraceInt("=== New Client %d ===\n", cp->fd); */
+ }
+ }
- /* Check each connection for read/write activity */
- while (!DLListIsEmpty(&connsTmp)) {
- pList = DLListGetHead(&connsTmp);
- cp = DLListGetContainer(pList, httpConn_t, List);
- DLListInsertTail(&g_conns, &cp->List);
+ /* Check each connection for read/write activity */
+ while (!DLListIsEmpty(&connsTmp))
+ {
+ pList = DLListGetHead(&connsTmp);
+ cp = DLListGetContainer(pList, httpConn_t, List);
+ DLListInsertTail(&g_conns, &cp->List);
- rSanity = wSanity = 0;
+ rSanity = wSanity = 0;
/*
- See if there's pending data to send on this connection
- We could use FD_ISSET, but this is more reliable for the current
- state of data to send.
+ See if there's pending data to send on this connection
+ We could use FD_ISSET, but this is more reliable for the current
+ state of data to send.
*/
WRITE_MORE:
- if ((len = matrixSslGetOutdata(cp->ssl, &buf)) > 0) {
- /* Could get a EWOULDBLOCK since we don't check FD_ISSET */
- transferred = (int32)send(cp->fd, buf, len, MSG_DONTWAIT);
- if (transferred <= 0) {
-#ifdef WIN32
- if (SOCKET_ERRNO != EWOULDBLOCK &&
- SOCKET_ERRNO != WSAEWOULDBLOCK) {
+ if ((len = matrixSslGetOutdata(cp->ssl, &buf)) > 0)
+ {
+ /* Could get a EWOULDBLOCK since we don't check FD_ISSET */
+ transferred = (int32) send(cp->fd, buf, len, MSG_DONTWAIT);
+ if (transferred <= 0)
+ {
+# ifdef WIN32
+ if (SOCKET_ERRNO != EWOULDBLOCK &&
+ SOCKET_ERRNO != WSAEWOULDBLOCK)
+ {
-#else
- if (SOCKET_ERRNO != EWOULDBLOCK) {
-#endif
- closeConn(cp, PS_PLATFORM_FAIL);
- continue; /* Next connection */
- }
- } else {
- /* Indicate that we've written > 0 bytes of data */
- if ((rc = matrixSslSentData(cp->ssl, transferred)) < 0) {
- closeConn(cp, PS_ARG_FAIL);
- continue; /* Next connection */
- }
- if (rc == MATRIXSSL_REQUEST_CLOSE) {
- closeConn(cp, MATRIXSSL_REQUEST_CLOSE);
- continue; /* Next connection */
- } else if (rc == MATRIXSSL_HANDSHAKE_COMPLETE) {
- /* If the protocol is server initiated, send data here */
- g_handshakes++;
-#ifdef ENABLE_FALSE_START
- /* OR this could be a Chrome browser using
- FALSE_START and the application data is already
- waiting in our inbuf for processing */
- if ((rc = matrixSslReceivedData(cp->ssl, 0,
- &buf, (uint32*)&len)) < 0) {
- closeConn(cp, 0);
- continue; /* Next connection */
- }
- if (rc > 0) { /* There was leftover data */
- goto PROCESS_MORE;
- }
-#endif /* ENABLE_FALSE_START */
+# else
+ if (SOCKET_ERRNO != EWOULDBLOCK)
+ {
+# endif
+ closeConn(cp, PS_PLATFORM_FAIL);
+ continue; /* Next connection */
+ }
+ }
+ else
+ {
+ /* Indicate that we've written > 0 bytes of data */
+ if ((rc = matrixSslSentData(cp->ssl, transferred)) < 0)
+ {
+ closeConn(cp, PS_ARG_FAIL);
+ continue; /* Next connection */
+ }
+ if (rc == MATRIXSSL_REQUEST_CLOSE)
+ {
+ closeConn(cp, MATRIXSSL_REQUEST_CLOSE);
+ continue; /* Next connection */
+ }
+ else if (rc == MATRIXSSL_HANDSHAKE_COMPLETE)
+ {
+ /* If the protocol is server initiated, send data here */
+ g_handshakes++;
+# ifdef ENABLE_FALSE_START
+ /* OR this could be a Chrome browser using
+ FALSE_START and the application data is already
+ waiting in our inbuf for processing */
+ if ((rc = matrixSslReceivedData(cp->ssl, 0,
+ &buf, (uint32 *) &len)) < 0)
+ {
+ closeConn(cp, 0);
+ continue; /* Next connection */
+ }
+ if (rc > 0) /* There was leftover data */
+ {
+ goto PROCESS_MORE;
+ }
+# endif /* ENABLE_FALSE_START */
- }
- /* Update activity time */
- psGetTime(&cp->time, NULL);
- /* Try to send again if more data to send */
- if (rc == MATRIXSSL_REQUEST_SEND || transferred < len) {
- if (wSanity++ < GOTO_SANITY) goto WRITE_MORE;
- }
- }
- } else if (len < 0) {
- closeConn(cp, PS_ARG_FAIL);
- continue; /* Next connection */
- }
+ }
+ /* Update activity time */
+ psGetTime(&cp->time, NULL);
+ /* Try to send again if more data to send */
+ if (rc == MATRIXSSL_REQUEST_SEND || transferred < len)
+ {
+ if (wSanity++ < GOTO_SANITY)
+ {
+ goto WRITE_MORE;
+ }
+ }
+ }
+ }
+ else if (len < 0)
+ {
+ closeConn(cp, PS_ARG_FAIL);
+ continue; /* Next connection */
+ }
- /* If we are sending response data and it's all encoded and sent, close conn */
- if (cp->bytes_requested > 0 &&
- cp->bytes_requested == cp->bytes_sent &&
- matrixSslGetOutdata(cp->ssl, &buf) <= 0) {
- closeConn(cp, PS_SUCCESS);
- continue; /* Next connection */
- }
+ /* If we are sending response data and it's all encoded and sent, close conn */
+ if (cp->bytes_requested > 0 &&
+ cp->bytes_requested == cp->bytes_sent &&
+ matrixSslGetOutdata(cp->ssl, &buf) <= 0)
+ {
+ closeConn(cp, PS_SUCCESS);
+ continue; /* Next connection */
+ }
/*
- Check the file descriptor returned from select to see if the connection
- has data to be read
+ Check the file descriptor returned from select to see if the connection
+ has data to be read
*/
- if (FD_ISSET(cp->fd, &readfd)) {
+ if (FD_ISSET(cp->fd, &readfd))
+ {
READ_MORE:
- /* Get the ssl buffer and how much data it can accept */
- /* Note 0 is a return failure, unlike with matrixSslGetOutdata */
- if ((len = matrixSslGetReadbuf(cp->ssl, &buf)) <= 0) {
- closeConn(cp, PS_ARG_FAIL);
- continue; /* Next connection */
- }
- if ((transferred = (int32)recv(cp->fd, buf, len, MSG_DONTWAIT)) < 0) {
- /* We could get EWOULDBLOCK despite the FD_ISSET on goto */
-#ifdef WIN32
- if (SOCKET_ERRNO != EWOULDBLOCK &&
- SOCKET_ERRNO != WSAEWOULDBLOCK) {
+ /* Get the ssl buffer and how much data it can accept */
+ /* Note 0 is a return failure, unlike with matrixSslGetOutdata */
+ if ((len = matrixSslGetReadbuf(cp->ssl, &buf)) <= 0)
+ {
+ closeConn(cp, PS_ARG_FAIL);
+ continue; /* Next connection */
+ }
+ if ((transferred = (int32) recv(cp->fd, buf, len, MSG_DONTWAIT)) < 0)
+ {
+ /* We could get EWOULDBLOCK despite the FD_ISSET on goto */
+# ifdef WIN32
+ if (SOCKET_ERRNO != EWOULDBLOCK &&
+ SOCKET_ERRNO != WSAEWOULDBLOCK)
+ {
-#else
- if (SOCKET_ERRNO != EWOULDBLOCK) {
-#endif
- closeConn(cp, PS_PLATFORM_FAIL);
- }
- continue; /* Next connection */
- }
+# else
+ if (SOCKET_ERRNO != EWOULDBLOCK)
+ {
+# endif
+ closeConn(cp, PS_PLATFORM_FAIL);
+ }
+ continue; /* Next connection */
+ }
- /* If EOF, remote socket closed. This is semi-normal closure.
- Officially, we should close on closure alert. */
- if (transferred == 0) {
-/* psTraceIntInfo("Closing connection %d on EOF\n", cp->fd); */
- closeConn(cp, 0);
- continue; /* Next connection */
- }
+ /* If EOF, remote socket closed. This is semi-normal closure.
+ Officially, we should close on closure alert. */
+ if (transferred == 0)
+ {
+/* psTraceIntInfo("Closing connection %d on EOF\n", cp->fd); */
+ closeConn(cp, 0);
+ continue; /* Next connection */
+ }
/*
- Notify SSL state machine that we've received more data into the
- ssl buffer retreived with matrixSslGetReadbuf.
+ Notify SSL state machine that we've received more data into the
+ ssl buffer retreived with matrixSslGetReadbuf.
*/
- if ((rc = matrixSslReceivedData(cp->ssl, (int32)transferred, &buf,
- (uint32*)&len)) < 0) {
- closeConn(cp, 0);
- continue; /* Next connection */
- }
- /* Update activity time */
- psGetTime(&cp->time, NULL);
+ if ((rc = matrixSslReceivedData(cp->ssl, (int32) transferred, &buf,
+ (uint32 *) &len)) < 0)
+ {
+ closeConn(cp, 0);
+ continue; /* Next connection */
+ }
+ /* Update activity time */
+ psGetTime(&cp->time, NULL);
PROCESS_MORE:
- /* Process any incoming plaintext application data */
- switch (rc) {
- case MATRIXSSL_HANDSHAKE_COMPLETE:
- g_handshakes++;
- /* If the protocol is server initiated, send data here */
- goto READ_MORE;
- case MATRIXSSL_APP_DATA:
- case MATRIXSSL_APP_DATA_COMPRESSED:
- //psTraceBytes("DATA", buf, len);
-
- /* First test to see if this is one of the special data
- requests used for testing.
-
- First is a "GET /bytes?" format
- */
- specialAppData = 0;
- if (len > 11 &&
- strncmp((char *)buf, "GET /bytes?", 11) == 0) {
- cp->bytes_requested = atoi((char *)buf + 11);
- if (cp->bytes_requested <
- strlen((char *)g_httpResponseHdr) ||
- cp->bytes_requested > 1073741824) {
- cp->bytes_requested =
- (uint32)strlen((char *)g_httpResponseHdr);
- }
- cp->bytes_sent = 0;
- specialAppData = 1;
- }
- /* A special test for TLS 1.0 where BEAST workaround used */
- if (len > 10 &&
- strncmp((char *)buf, "ET /bytes?", 10) == 0) {
- cp->bytes_requested = atoi((char *)buf + 10);
- if (cp->bytes_requested <
- strlen((char *)g_httpResponseHdr) ||
- cp->bytes_requested > 1073741824) {
- cp->bytes_requested =
- (uint32)strlen((char *)g_httpResponseHdr);
- }
- cp->bytes_sent = 0;
- specialAppData = 1;
- }
- /* Shutdown the server */
- if (len >= 15 &&
- strncmp((char*)buf, "MATRIX_SHUTDOWN", 15) == 0) {
- g_exitFlag = 1;
- rc = matrixSslEncodeClosureAlert(cp->ssl);
- psAssert(rc >= 0);
- _psTrace("Got MATRIX_SHUTDOWN. Exiting\n");
- goto WRITE_MORE;
- }
+ /* Process any incoming plaintext application data */
+ switch (rc)
+ {
+ case MATRIXSSL_HANDSHAKE_COMPLETE:
+ g_handshakes++;
+ /* If the protocol is server initiated, send data here */
+ goto READ_MORE;
+ case MATRIXSSL_APP_DATA:
+ case MATRIXSSL_APP_DATA_COMPRESSED:
+ /* psTraceBytes("DATA", buf, len); */
- if (specialAppData == 0) {
- if ((rc = httpBasicParse(cp, buf, len, 0)) < 0) {
- _psTrace("Couldn't parse HTTP data. Closing...\n");
- closeConn(cp, PS_PROTOCOL_FAIL);
- continue; /* Next connection */
- }
- }
-
- if (rc == HTTPS_COMPLETE || specialAppData == 1) {
- if (httpWriteResponse(cp) < 0) {
- closeConn(cp, PS_PROTOCOL_FAIL);
- continue; /* Next connection */
- }
- /* For HTTP, we assume no pipelined requests, so we
- close after parsing a single HTTP request */
- /* Ignore return of closure alert, it's optional */
-#ifdef SEND_CLOSURE_ALERT
-// rc = matrixSslEncodeClosureAlert(cp->ssl);
-// psAssert(rc >= 0);
-#endif
- rc = matrixSslProcessedData(cp->ssl, &buf, (uint32*)&len);
- if (rc > 0) {
- /* Additional data is available, but we ignore it */
- _psTrace("HTTP data parsing not supported, ignoring.\n");
- closeConn(cp, PS_SUCCESS);
- continue; /* Next connection */
- } else if (rc < 0) {
- closeConn(cp, PS_PROTOCOL_FAIL);
- continue; /* Next connection */
- }
- /* rc == 0, write out our response and closure alert */
- goto WRITE_MORE;
- }
- /* We processed a partial HTTP message */
- if ((rc = matrixSslProcessedData(cp->ssl, &buf, (uint32*)&len)) == 0) {
- goto READ_MORE;
- }
- goto PROCESS_MORE;
- case MATRIXSSL_REQUEST_SEND:
- /* Prevent us from reading again after the write,
- although that wouldn't be the end of the world */
- FD_CLR(cp->fd, &readfd);
- if (wSanity++ < GOTO_SANITY) goto WRITE_MORE;
- break;
- case MATRIXSSL_REQUEST_RECV:
- if (rSanity++ < GOTO_SANITY) goto READ_MORE;
- break;
- case MATRIXSSL_RECEIVED_ALERT:
- /* The first byte of the buffer is the level */
- /* The second byte is the description */
- if (*buf == SSL_ALERT_LEVEL_FATAL) {
- psTraceIntInfo("Fatal alert: %d, closing connection.\n",
- *(buf + 1));
- closeConn(cp, PS_PROTOCOL_FAIL);
- continue; /* Next connection */
- }
- /* Closure alert is normal (and best) way to close */
- if (*(buf + 1) == SSL_ALERT_CLOSE_NOTIFY) {
- closeConn(cp, PS_SUCCESS);
- continue; /* Next connection */
- }
- psTraceIntInfo("Warning alert: %d\n", *(buf + 1));
- if ((rc = matrixSslProcessedData(cp->ssl, &buf, (uint32*)&len)) == 0) {
- /* No more data in buffer. Might as well read for more. */
- goto READ_MORE;
- }
- goto PROCESS_MORE;
+ /* First test to see if this is one of the special data
+ requests used for testing.
- default:
- /* If rc <= 0 we fall here */
- closeConn(cp, PS_PROTOCOL_FAIL);
- continue; /* Next connection */
- }
- /* Always try to read more if we processed some data */
- if (rSanity++ < GOTO_SANITY) goto READ_MORE;
- } /* readfd handling */
- } /* connection loop */
- return PS_SUCCESS;
+ First is a "GET /bytes?" format
+ */
+ specialAppData = 0;
+ if (len > 11 &&
+ strncmp((char *) buf, "GET /bytes?", 11) == 0)
+ {
+ cp->bytes_requested = atoi((char *) buf + 11);
+ if (cp->bytes_requested <
+ strlen((char *) g_httpResponseHdr) ||
+ cp->bytes_requested > 1073741824)
+ {
+ cp->bytes_requested =
+ (uint32) strlen((char *) g_httpResponseHdr);
+ }
+ cp->bytes_sent = 0;
+ specialAppData = 1;
+ }
+ /* A special test for TLS 1.0 where BEAST workaround used */
+ if (len > 10 &&
+ strncmp((char *) buf, "ET /bytes?", 10) == 0)
+ {
+ cp->bytes_requested = atoi((char *) buf + 10);
+ if (cp->bytes_requested <
+ strlen((char *) g_httpResponseHdr) ||
+ cp->bytes_requested > 1073741824)
+ {
+ cp->bytes_requested =
+ (uint32) strlen((char *) g_httpResponseHdr);
+ }
+ cp->bytes_sent = 0;
+ specialAppData = 1;
+ }
+ /* Shutdown the server */
+ if (len >= 15 &&
+ strncmp((char *) buf, "MATRIX_SHUTDOWN", 15) == 0)
+ {
+ g_exitFlag = 1;
+ rc = matrixSslEncodeClosureAlert(cp->ssl);
+ psAssert(rc >= 0);
+ _psTrace("Got MATRIX_SHUTDOWN. Exiting\n");
+ goto WRITE_MORE;
+ }
+
+ if (specialAppData == 0)
+ {
+ if ((rc = httpBasicParse(cp, buf, len, 0)) < 0)
+ {
+ _psTrace("Couldn't parse HTTP data. Closing...\n");
+ closeConn(cp, PS_PROTOCOL_FAIL);
+ continue; /* Next connection */
+ }
+ }
+
+ if (rc == HTTPS_COMPLETE || specialAppData == 1)
+ {
+ if (httpWriteResponse(cp) < 0)
+ {
+ closeConn(cp, PS_PROTOCOL_FAIL);
+ continue; /* Next connection */
+ }
+ /* For HTTP, we assume no pipelined requests, so we
+ close after parsing a single HTTP request */
+ /* Ignore return of closure alert, it's optional */
+# ifdef SEND_CLOSURE_ALERT
+/* rc = matrixSslEncodeClosureAlert(cp->ssl); */
+/* psAssert(rc >= 0); */
+# endif
+ rc = matrixSslProcessedData(cp->ssl, &buf, (uint32 *) &len);
+ if (rc > 0)
+ {
+ /* Additional data is available, but we ignore it */
+ _psTrace("HTTP data parsing not supported, ignoring.\n");
+ closeConn(cp, PS_SUCCESS);
+ continue; /* Next connection */
+ }
+ else if (rc < 0)
+ {
+ closeConn(cp, PS_PROTOCOL_FAIL);
+ continue; /* Next connection */
+ }
+ /* rc == 0, write out our response and closure alert */
+ goto WRITE_MORE;
+ }
+ /* We processed a partial HTTP message */
+ if ((rc = matrixSslProcessedData(cp->ssl, &buf, (uint32 *) &len)) == 0)
+ {
+ goto READ_MORE;
+ }
+ goto PROCESS_MORE;
+ case MATRIXSSL_REQUEST_SEND:
+ /* Prevent us from reading again after the write,
+ although that wouldn't be the end of the world */
+ FD_CLR(cp->fd, &readfd);
+ if (wSanity++ < GOTO_SANITY)
+ {
+ goto WRITE_MORE;
+ }
+ break;
+ case MATRIXSSL_REQUEST_RECV:
+ if (rSanity++ < GOTO_SANITY)
+ {
+ goto READ_MORE;
+ }
+ break;
+ case MATRIXSSL_RECEIVED_ALERT:
+ /* The first byte of the buffer is the level */
+ /* The second byte is the description */
+ if (*buf == SSL_ALERT_LEVEL_FATAL)
+ {
+ psTraceIntInfo("Fatal alert: %d, closing connection.\n",
+ *(buf + 1));
+ closeConn(cp, PS_PROTOCOL_FAIL);
+ continue; /* Next connection */
+ }
+ /* Closure alert is normal (and best) way to close */
+ if (*(buf + 1) == SSL_ALERT_CLOSE_NOTIFY)
+ {
+ closeConn(cp, PS_SUCCESS);
+ continue; /* Next connection */
+ }
+ psTraceIntInfo("Warning alert: %d\n", *(buf + 1));
+ if ((rc = matrixSslProcessedData(cp->ssl, &buf, (uint32 *) &len)) == 0)
+ {
+ /* No more data in buffer. Might as well read for more. */
+ goto READ_MORE;
+ }
+ goto PROCESS_MORE;
+
+ default:
+ /* If rc <= 0 we fall here */
+ closeConn(cp, PS_PROTOCOL_FAIL);
+ continue; /* Next connection */
+ }
+ /* Always try to read more if we processed some data */
+ if (rSanity++ < GOTO_SANITY)
+ {
+ goto READ_MORE;
+ }
+ } /* readfd handling */
+ } /* connection loop */
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- Create an HTTP response and encode it to the SSL buffer
+ Create an HTTP response and encode it to the SSL buffer
*/
-#define TEST_SIZE 16000
+# define TEST_SIZE 16000
static int32 httpWriteResponse(httpConn_t *cp)
{
- unsigned char *buf;
- ssl_t *ssl;
- int32 available, len, rc;
+ unsigned char *buf;
+ ssl_t *ssl;
+ int32 available, len, rc;
- ssl = cp->ssl;
- /* The /bytes? HTTP request assigns bytes_requested */
- if (cp->bytes_requested) {
- /*
- Generate TLS records for all the requested bytes.
- This can put a lot of data in ssl outbuf, so we attempt
- to flush it out at the bottom of the loop.
- Anything left over will be sent out in the main server loop.
- */
- while (cp->bytes_sent < cp->bytes_requested) {
- len = cp->bytes_requested - cp->bytes_sent;
- if (len < 0) {
- return PS_MEM_FAIL;
- }
- if (len > RESPONSE_REC_LEN) {
- len = RESPONSE_REC_LEN;
- }
- if ((rc = matrixSslGetWritebuf(ssl, &buf, len)) < 1) {
- return PS_MEM_FAIL;
- }
- if (rc < len) {
- len = rc; /* could have been shortened due to max_frag */
- }
- memset(buf, 'J', len);
- if (cp->bytes_sent == 0) {
- /* Overwrite first N bytes with HTTP header the first time */
- strncpy((char *)buf, (char *)g_httpResponseHdr,
- strlen((char*)g_httpResponseHdr));
- }
- if ((rc = matrixSslEncodeWritebuf(ssl, len)) < 0) {
- printf("couldn't encode data %d\n", rc);
- }
- cp->bytes_sent += len;
- /*
- Do a quick, non-blocking send here to start flushing the
- generated records. We could flush after each record encode,
- or only on a multiple of record encodes.
- */
- if (matrixSslGetOutdata(ssl, &buf) > (RESPONSE_REC_LEN * 4)) {
- if ((len = (int32)send(cp->fd, buf, len, MSG_DONTWAIT)) > 0) {
- rc = matrixSslSentData(ssl, len);
-// psAssert(rc != MATRIXSSL_REQUEST_SEND); /* Some data remains */
- }
- }
- }
- return MATRIXSSL_REQUEST_SEND;
- }
+ ssl = cp->ssl;
+ /* The /bytes? HTTP request assigns bytes_requested */
+ if (cp->bytes_requested)
+ {
+ /*
+ Generate TLS records for all the requested bytes.
+ This can put a lot of data in ssl outbuf, so we attempt
+ to flush it out at the bottom of the loop.
+ Anything left over will be sent out in the main server loop.
+ */
+ while (cp->bytes_sent < cp->bytes_requested)
+ {
+ len = cp->bytes_requested - cp->bytes_sent;
+ if (len < 0)
+ {
+ return PS_MEM_FAIL;
+ }
+ if (len > RESPONSE_REC_LEN)
+ {
+ len = RESPONSE_REC_LEN;
+ }
+ if ((rc = matrixSslGetWritebuf(ssl, &buf, len)) < 1)
+ {
+ return PS_MEM_FAIL;
+ }
+ if (rc < len)
+ {
+ len = rc; /* could have been shortened due to max_frag */
+ }
+ memset(buf, 'J', len);
+ if (cp->bytes_sent == 0)
+ {
+ /* Overwrite first N bytes with HTTP header the first time */
+ strncpy((char *) buf, (char *) g_httpResponseHdr,
+ strlen((char *) g_httpResponseHdr));
+ }
+ if ((rc = matrixSslEncodeWritebuf(ssl, len)) < 0)
+ {
+ printf("couldn't encode data %d\n", rc);
+ }
+ cp->bytes_sent += len;
+ /*
+ Do a quick, non-blocking send here to start flushing the
+ generated records. We could flush after each record encode,
+ or only on a multiple of record encodes.
+ */
+ if (matrixSslGetOutdata(ssl, &buf) > (RESPONSE_REC_LEN * 4))
+ {
+ if ((len = (int32) send(cp->fd, buf, len, MSG_DONTWAIT)) > 0)
+ {
+ rc = matrixSslSentData(ssl, len);
+/* psAssert(rc != MATRIXSSL_REQUEST_SEND); / * Some data remains * / */
+ }
+ }
+ }
+ return MATRIXSSL_REQUEST_SEND;
+ }
- /* Usual reply */
- if ((available = matrixSslGetWritebuf(ssl, &buf,
- (uint32)strlen((char *)g_httpResponseHdr) + 1)) < 0) {
- return PS_MEM_FAIL;
- }
- strncpy((char *)buf, (char *)g_httpResponseHdr, available);
- //psTraceBytes("Replying", buf, (uint32)strlen((char *)buf));
- if (matrixSslEncodeWritebuf(ssl, (uint32)strlen((char *)buf)) < 0) {
- return PS_MEM_FAIL;
- }
- return MATRIXSSL_REQUEST_SEND;
+ /* Usual reply */
+ if ((available = matrixSslGetWritebuf(ssl, &buf,
+ (uint32) strlen((char *) g_httpResponseHdr) + 1)) < 0)
+ {
+ return PS_MEM_FAIL;
+ }
+ strncpy((char *) buf, (char *) g_httpResponseHdr, available);
+ /* psTraceBytes("Replying", buf, (uint32)strlen((char *)buf)); */
+ if (matrixSslEncodeWritebuf(ssl, (uint32) strlen((char *) buf)) < 0)
+ {
+ return PS_MEM_FAIL;
+ }
+ return MATRIXSSL_REQUEST_SEND;
}
static void usage(void)
{
- printf(
- "\nusage: server { options }\n"
- "\n"
- "Options can be one or more of the following:\n"
- "\n"
- "-c - Server certificate file\n"
- "-k - Server private key file of certificate\n"
- "-a - CA certificate file\n"
- "-p - Private key password\n"
- "-d - Diffie-Hellman parameters file\n"
- "-D - Directory path to certificate, private key, \n"
- " and Diffie-Hellman parameter files\n"
- "-P - Port number\n"
- "-h - Help, print usage and exit\n"
- "-x - Cipher suites to disable\n"
- " Example cipher numbers:\n"
- " - '53' TLS_RSA_WITH_AES_256_CBC_SHA\n"
- " - '47' TLS_RSA_WITH_AES_128_CBC_SHA\n"
- " - '10' SSL_RSA_WITH_3DES_EDE_CBC_SHA\n"
- " - '5' SSL_RSA_WITH_RC4_128_SHA\n"
- " - '4' SSL_RSA_WITH_RC4_128_MD5\n"
- "-v - SSL/TLS version to use\n"
- " - '0' SSL 3.0\n"
- " - '1' TLS 1.0\n"
- " - '2' TLS 1.1\n"
- " - '3' TLS 1.2 (default)\n"
- "\n");
+ printf(
+ "\nusage: server { options }\n"
+ "\n"
+ "Options can be one or more of the following:\n"
+ "\n"
+ "-c - Server certificate file\n"
+ "-k - Server private key file of certificate\n"
+ "-a - CA certificate file\n"
+ "-p - Private key password\n"
+ "-d - Diffie-Hellman parameters file\n"
+ "-D - Directory path to certificate, private key, \n"
+ " and Diffie-Hellman parameter files\n"
+ "-P - Port number\n"
+ "-h - Help, print usage and exit\n"
+ "-x - Cipher suites to disable\n"
+ " Example cipher numbers:\n"
+ " - '53' TLS_RSA_WITH_AES_256_CBC_SHA\n"
+ " - '47' TLS_RSA_WITH_AES_128_CBC_SHA\n"
+ " - '10' SSL_RSA_WITH_3DES_EDE_CBC_SHA\n"
+ " - '5' SSL_RSA_WITH_RC4_128_SHA\n"
+ " - '4' SSL_RSA_WITH_RC4_128_MD5\n"
+ "-v - SSL/TLS version to use\n"
+ " - '0' SSL 3.0\n"
+ " - '1' TLS 1.0\n"
+ " - '2' TLS 1.1\n"
+ " - '3' TLS 1.2 (default)\n"
+ "\n");
}
/* Returns number of cipher numbers found, or -1 if an error. */
-#include
-static int32_t parse_cipher_list(char *cipherListString,
- uint16_t cipher_array[], uint8_t size_of_cipher_array)
+# include
+static int32_t parse_cipher_list(char *cipherListString,
+ psCipher16_t cipher_array[], uint8_t size_of_cipher_array)
{
- uint32 numCiphers, cipher;
- char *endPtr;
+ uint32 numCiphers, cipher;
+ char *endPtr;
- /* Convert the cipherListString into an array of cipher numbers. */
- numCiphers = 0;
- while (cipherListString != NULL) {
- cipher = strtol(cipherListString, &endPtr, 10);
- if (endPtr == cipherListString) {
- printf("The remaining cipherList has no cipher numbers - '%s'\n",
- cipherListString);
- return -1;
- } else if (size_of_cipher_array <= numCiphers) {
- printf("Too many cipher numbers supplied. limit is %d\n",
- size_of_cipher_array);
- return -1;
- }
- cipher_array[numCiphers++] = cipher;
- while (*endPtr != '\0' && !isdigit(*endPtr)) {
- endPtr++;
- }
- cipherListString = endPtr;
- if (*endPtr == '\0') {
- break;
- }
- }
+ /* Convert the cipherListString into an array of cipher numbers. */
+ numCiphers = 0;
+ while (cipherListString != NULL)
+ {
+ cipher = strtol(cipherListString, &endPtr, 10);
+ if (endPtr == cipherListString)
+ {
+ printf("The remaining cipherList has no cipher numbers - '%s'\n",
+ cipherListString);
+ return -1;
+ }
+ else if (size_of_cipher_array <= numCiphers)
+ {
+ printf("Too many cipher numbers supplied. limit is %d\n",
+ size_of_cipher_array);
+ return -1;
+ }
+ cipher_array[numCiphers++] = cipher;
+ while (*endPtr != '\0' && !isdigit(*endPtr))
+ {
+ endPtr++;
+ }
+ cipherListString = endPtr;
+ if (*endPtr == '\0')
+ {
+ break;
+ }
+ }
- return numCiphers;
+ return numCiphers;
}
/* Return 0 on good set of cmd options, return -1 if a bad cmd option is
encountered OR a request for help is seen (i.e. '-h' option). */
static int32 process_cmd_options(int32 argc, char **argv)
{
- int optionChar, str_len, version, numCiphers;
- char *cipherListString;
+ int optionChar, str_len, version, numCiphers;
+ char *cipherListString;
- /* Start with all options zeroized. */
- memset(g_keyfilePath, 0, MAX_KEYFILE_PATH);
- memset(g_privkeyFile, 0, MAX_KEYFILE_PATH);
- memset(g_identityCert, 0, MAX_KEYFILE_PATH);
- memset(g_dhParamFile, 0, MAX_KEYFILE_PATH);
- memset(g_caFile, 0, MAX_KEYFILE_PATH);
- memset(g_password, 0, MAX_PASSWORD_LEN);
-
- g_port = HTTPS_PORT;
- g_version = 3;
- g_disabledCiphers = 0;
+ /* Start with all options zeroized. */
+ memset(g_keyfilePath, 0, MAX_KEYFILE_PATH);
+ memset(g_privkeyFile, 0, MAX_KEYFILE_PATH);
+ memset(g_identityCert, 0, MAX_KEYFILE_PATH);
+ memset(g_dhParamFile, 0, MAX_KEYFILE_PATH);
+ memset(g_caFile, 0, MAX_KEYFILE_PATH);
+ memset(g_password, 0, MAX_PASSWORD_LEN);
- opterr = 0;
- while ((optionChar = getopt(argc, argv, "c:d:a:D:hk:p:P:v:x:")) != -1)
- {
- switch (optionChar)
- {
- case 'h':
- return -1;
+ g_port = HTTPS_PORT;
+ g_version = 3;
+ g_disabledCiphers = 0;
- case 'x':
- // Ciphers to DISABLE!
- // Convert the cipherListString into an array of cipher numbers.
- cipherListString = optarg;
- numCiphers = parse_cipher_list(cipherListString, g_disabledCipher,
- SSL_MAX_DISABLED_CIPHERS);
- if (numCiphers <= 0) {
- return -1;
- }
- g_disabledCiphers = numCiphers;
- break;
+ opterr = 0;
+ while ((optionChar = getopt(argc, argv, "c:d:a:D:hk:p:P:v:x:")) != -1)
+ {
+ switch (optionChar)
+ {
+ case 'h':
+ return -1;
- case 'D':
- // Directory for key and cert location
- str_len = strlen(optarg);
- if (str_len > MAX_KEYFILE_PATH - 1) {
- return -1;
- }
- strncpy(g_keyfilePath, optarg, str_len);
- break;
-
- case 'c':
- // Certfile
- str_len = strlen(optarg);
- if (str_len > MAX_KEYFILE_PATH - 1) {
- return -1;
- }
- strncpy(g_identityCert, optarg, str_len);
- break;
-
- case 'a':
- // Cert authority file
- str_len = strlen(optarg);
- if (str_len > MAX_KEYFILE_PATH - 1) {
- return -1;
- }
- strncpy(g_caFile, optarg, str_len);
- break;
-
- case 'd':
- // Diffie-Hellman parameters
- str_len = strlen(optarg);
- if (str_len > MAX_KEYFILE_PATH - 1) {
- return -1;
- }
- strncpy(g_dhParamFile, optarg, str_len);
- break;
-
-
- case 'k':
- // Keyfile
- str_len = strlen(optarg);
- if (str_len > MAX_KEYFILE_PATH - 1) {
- return -1;
- }
- strncpy(g_privkeyFile, optarg, str_len);
- break;
-
- case 'p':
- // password
- str_len = strlen(optarg);
- if (str_len > MAX_KEYFILE_PATH - 1) {
- return -1;
- }
- strncpy(g_password, optarg, str_len);
- break;
+ case 'x':
+ /* Ciphers to DISABLE! */
+ /* Convert the cipherListString into an array of cipher numbers. */
+ cipherListString = optarg;
+ numCiphers = parse_cipher_list(cipherListString, g_disabledCipher,
+ SSL_MAX_DISABLED_CIPHERS);
+ if (numCiphers <= 0)
+ {
+ return -1;
+ }
+ g_disabledCiphers = numCiphers;
+ break;
- case 'P':
- g_port = atoi(optarg);
- break;
+ case 'D':
+ /* Directory for key and cert location */
+ str_len = strlen(optarg);
+ if (str_len > MAX_KEYFILE_PATH - 1)
+ {
+ return -1;
+ }
+ strncpy(g_keyfilePath, optarg, str_len);
+ break;
- case 'v':
- version = atoi(optarg);
- if (version < 0 || version > 3) {
- printf("Invalid version: %d\n", version);
- return -1;
- }
- g_version = version;
- break;
- }
- }
+ case 'c':
+ /* Certfile */
+ str_len = strlen(optarg);
+ if (str_len > MAX_KEYFILE_PATH - 1)
+ {
+ return -1;
+ }
+ strncpy(g_identityCert, optarg, str_len);
+ break;
- return 0;
+ case 'a':
+ /* Cert authority file */
+ str_len = strlen(optarg);
+ if (str_len > MAX_KEYFILE_PATH - 1)
+ {
+ return -1;
+ }
+ strncpy(g_caFile, optarg, str_len);
+ break;
+
+ case 'd':
+ /* Diffie-Hellman parameters */
+ str_len = strlen(optarg);
+ if (str_len > MAX_KEYFILE_PATH - 1)
+ {
+ return -1;
+ }
+ strncpy(g_dhParamFile, optarg, str_len);
+ break;
+
+
+ case 'k':
+ /* Keyfile */
+ str_len = strlen(optarg);
+ if (str_len > MAX_KEYFILE_PATH - 1)
+ {
+ return -1;
+ }
+ strncpy(g_privkeyFile, optarg, str_len);
+ break;
+
+ case 'p':
+ /* password */
+ str_len = strlen(optarg);
+ if (str_len > MAX_KEYFILE_PATH - 1)
+ {
+ return -1;
+ }
+ strncpy(g_password, optarg, str_len);
+ break;
+
+ case 'P':
+ g_port = atoi(optarg);
+ break;
+
+ case 'v':
+ version = atoi(optarg);
+ if (version < 0 || version > 3)
+ {
+ printf("Invalid version: %d\n", version);
+ return -1;
+ }
+ g_version = version;
+ break;
+ }
+ }
+
+ return 0;
}
/******************************************************************************/
/*
- Main non-blocking SSL server
- Initialize MatrixSSL and sockets layer, and loop on select
+ Main non-blocking SSL server
+ Initialize MatrixSSL and sockets layer, and loop on select
*/
int32 main(int32 argc, char **argv)
{
- SOCKET lfd;
- int32 err, rc;
-#ifdef WIN32
- WSADATA wsaData;
-#endif
-#ifdef USE_STATELESS_SESSION_TICKETS
- unsigned char sessTicketName[16];
-#endif
- char certpath[FILENAME_MAX];
- char keypath[FILENAME_MAX];
- char capath[FILENAME_MAX];
- sslKeys_t *keys = NULL;
+ SOCKET lfd;
+ int32 err, rc;
-#ifdef WIN32
- WSAStartup(MAKEWORD(1, 1), &wsaData);
-#endif
+# ifdef WIN32
+ WSADATA wsaData;
+# endif
+# ifdef USE_STATELESS_SESSION_TICKETS
+ unsigned char sessTicketName[16];
+# endif
+ char certpath[FILENAME_MAX];
+ char keypath[FILENAME_MAX];
+ char capath[FILENAME_MAX];
+ sslKeys_t *keys = NULL;
- DLListInit(&g_conns);
- g_exitFlag = 0;
- lfd = INVALID_SOCKET;
+# ifdef WIN32
+ WSAStartup(MAKEWORD(1, 1), &wsaData);
+# endif
-#ifdef POSIX
- if (sighandlers() < 0) {
- return PS_PLATFORM_FAIL;
- }
-#endif /* POSIX */
+ DLListInit(&g_conns);
+ g_exitFlag = 0;
+ lfd = INVALID_SOCKET;
- if ((rc = matrixSslOpen()) < 0) {
- _psTrace("MatrixSSL library init failure. Exiting\n");
- return rc;
- }
+# ifdef POSIX
+ if (sighandlers() < 0)
+ {
+ return PS_PLATFORM_FAIL;
+ }
+# endif /* POSIX */
- if (matrixSslNewKeys(&keys, NULL) < 0) {
- return -1;
- }
+ if ((rc = matrixSslOpen()) < 0)
+ {
+ _psTrace("MatrixSSL library init failure. Exiting\n");
+ return rc;
+ }
- if (0 != process_cmd_options(argc, argv)) {
- usage();
- return 0;
- }
+ if (matrixSslNewKeys(&keys, NULL) < 0)
+ {
+ return -1;
+ }
-#ifdef USE_STATELESS_SESSION_TICKETS
- if (matrixCryptoGetPrngData(sessTicketSymKey, sizeof(sessTicketSymKey), NULL) < 0
- || matrixCryptoGetPrngData(sessTicketMacKey, sizeof(sessTicketMacKey), NULL) < 0
- || matrixCryptoGetPrngData(sessTicketName, sizeof(sessTicketName), NULL) < 0) {
- _psTrace("Error generating session ticket encryption key\n");
- return EXIT_FAILURE;
- }
- if (matrixSslLoadSessionTicketKeys(keys, sessTicketName,
- sessTicketSymKey, sizeof(sessTicketSymKey),
- sessTicketMacKey, sizeof(sessTicketMacKey)) < 0) {
- _psTrace("Error loading session ticket encryption key\n");
- return EXIT_FAILURE;
- }
- matrixSslSetSessionTicketCallback(keys, sessTicketCb);
- _psTrace("Session Ticket resumption enabled\n");
-#endif
+ if (0 != process_cmd_options(argc, argv))
+ {
+ usage();
+ return 0;
+ }
+
+# ifdef USE_STATELESS_SESSION_TICKETS
+ if (psGetPrngLocked(sessTicketSymKey, sizeof(sessTicketSymKey), NULL) < 0
+ || psGetPrngLocked(sessTicketMacKey, sizeof(sessTicketMacKey), NULL) < 0
+ || psGetPrngLocked(sessTicketName, sizeof(sessTicketName), NULL) < 0)
+ {
+ _psTrace("Error generating session ticket encryption key\n");
+ return EXIT_FAILURE;
+ }
+ if (matrixSslLoadSessionTicketKeys(keys, sessTicketName,
+ sessTicketSymKey, sizeof(sessTicketSymKey),
+ sessTicketMacKey, sizeof(sessTicketMacKey)) < 0)
+ {
+ _psTrace("Error loading session ticket encryption key\n");
+ return EXIT_FAILURE;
+ }
+ matrixSslSetSessionTicketCallback(keys, sessTicketCb);
+ _psTrace("Session Ticket resumption enabled\n");
+# endif
- /* Set the certpath and keypath as the defaults or the user provided */
- if (g_identityCert[0] != 0) {
- // User provided a cert
- if (g_keyfilePath[0] != 0) {
- snprintf(certpath, FILENAME_MAX - 1, "%s/%s",
- g_keyfilePath, g_identityCert);
- } else {
- snprintf(certpath, FILENAME_MAX - 1, "%s", g_identityCert);
- }
- } else {
- // Default cert
- _psTrace("WARNING: Do not use sample certificate file in production\n");
- snprintf(certpath, FILENAME_MAX - 1, "%s/%s",
- KEY_DIR, g_defaultCertFile);
- }
+ /* Set the certpath and keypath as the defaults or the user provided */
+ if (g_identityCert[0] != 0)
+ {
+ /* User provided a cert */
+ if (g_keyfilePath[0] != 0)
+ {
+ snprintf(certpath, FILENAME_MAX - 1, "%s/%s",
+ g_keyfilePath, g_identityCert);
+ }
+ else
+ {
+ snprintf(certpath, FILENAME_MAX - 1, "%s", g_identityCert);
+ }
+ }
+ else
+ {
+ /* Default cert */
+ _psTrace("WARNING: Do not use sample certificate file in production\n");
+ snprintf(certpath, FILENAME_MAX - 1, "%s/%s",
+ KEY_DIR, g_defaultCertFile);
+ }
- if (g_privkeyFile[0] != 0) {
- // User provided a key
- if (g_keyfilePath[0] != 0) {
- snprintf(keypath, FILENAME_MAX - 1, "%s/%s",
- g_keyfilePath, g_privkeyFile);
- } else {
- snprintf(keypath, FILENAME_MAX - 1, "%s", g_privkeyFile);
- }
- } else {
- // Default key
- _psTrace("WARNING: Do not use sample private key file in production\n");
- snprintf(keypath, FILENAME_MAX - 1, "%s/%s",
- KEY_DIR, g_defaultPrivkeyFile);
- }
+ if (g_privkeyFile[0] != 0)
+ {
+ /* User provided a key */
+ if (g_keyfilePath[0] != 0)
+ {
+ snprintf(keypath, FILENAME_MAX - 1, "%s/%s",
+ g_keyfilePath, g_privkeyFile);
+ }
+ else
+ {
+ snprintf(keypath, FILENAME_MAX - 1, "%s", g_privkeyFile);
+ }
+ }
+ else
+ {
+ /* Default key */
+ _psTrace("WARNING: Do not use sample private key file in production\n");
+ snprintf(keypath, FILENAME_MAX - 1, "%s/%s",
+ KEY_DIR, g_defaultPrivkeyFile);
+ }
- if (g_caFile[0] != 0) {
- // User provided a CA file
- if (g_keyfilePath[0] != 0) {
- snprintf(capath, FILENAME_MAX - 1, "%s/%s",
- g_keyfilePath, g_caFile);
- } else {
- snprintf(capath, FILENAME_MAX - 1, "%s", g_caFile);
- }
- } else {
- // Default key
- snprintf(capath, FILENAME_MAX - 1, "%s/%s",
- KEY_DIR, g_defaultCAFile);
- }
+ if (g_caFile[0] != 0)
+ {
+ /* User provided a CA file */
+ if (g_keyfilePath[0] != 0)
+ {
+ snprintf(capath, FILENAME_MAX - 1, "%s/%s",
+ g_keyfilePath, g_caFile);
+ }
+ else
+ {
+ snprintf(capath, FILENAME_MAX - 1, "%s", g_caFile);
+ }
+ }
+ else
+ {
+ /* Default key */
+ snprintf(capath, FILENAME_MAX - 1, "%s/%s",
+ KEY_DIR, g_defaultCAFile);
+ }
- /* Still don't have a generic key loading function. Try RSA first and
- then ECC if that doesn't load */
-#ifdef USE_RSA
- if ((rc = matrixSslLoadRsaKeys(keys, certpath, keypath, g_password, capath)) < 0) {
-#endif /* USE_RSA */
-#ifdef USE_ECC_CIPHER_SUITE
- if ((rc = matrixSslLoadEcKeys(keys, certpath, keypath, g_password, capath)) < 0) {
- _psTrace("Unable to load key material. Exiting\n");
- return rc;
- }
-#else
- _psTrace("Unable to load key material. Please enable RSA or ECC from config.\n");
- return rc;
-#endif /* USE_ECC_CIPHER_SUITE */
-#ifdef USE_RSA
- }
-#endif /* USE_RSA */
+ /* Still don't have a generic key loading function. Try RSA first and
+ then ECC if that doesn't load */
+# ifdef USE_RSA
+ if ((rc = matrixSslLoadRsaKeys(keys, certpath, keypath, g_password, capath)) < 0)
+ {
+# endif /* USE_RSA */
+# ifdef USE_ECC_CIPHER_SUITE
+ if ((rc = matrixSslLoadEcKeys(keys, certpath, keypath, g_password, capath)) < 0)
+ {
+ _psTrace("Unable to load key material. Exiting\n");
+ return rc;
+ }
+# else
+ _psTrace("Unable to load key material. Please enable RSA or ECC from config.\n");
+ return rc;
+# endif /* USE_ECC_CIPHER_SUITE */
+# ifdef USE_RSA
+}
+# endif /* USE_RSA */
-#ifdef REQUIRE_DH_PARAMS
- if (g_dhParamFile[0] != 0) {
- // User provided DH params
- if (g_keyfilePath[0] != 0) {
- snprintf(certpath, FILENAME_MAX - 1, "%s/%s",
- g_keyfilePath, g_dhParamFile);
- } else {
- snprintf(certpath, FILENAME_MAX - 1, "%s", g_dhParamFile);
- }
- } else {
- // Default DH params
- snprintf(certpath, FILENAME_MAX - 1, "%s/%s",
- KEY_DIR, g_defaultDHParamFile);
- }
- if ((rc = matrixSslLoadDhParams(keys, certpath)) < 0) {
- _psTrace("Unable to load static key material. Exiting\n");
- return rc;
- }
-#endif
+# ifdef REQUIRE_DH_PARAMS
+ if (g_dhParamFile[0] != 0)
+ {
+ /* User provided DH params */
+ if (g_keyfilePath[0] != 0)
+ {
+ snprintf(certpath, FILENAME_MAX - 1, "%s/%s",
+ g_keyfilePath, g_dhParamFile);
+ }
+ else
+ {
+ snprintf(certpath, FILENAME_MAX - 1, "%s", g_dhParamFile);
+ }
+ }
+ else
+ {
+ /* Default DH params */
+ snprintf(certpath, FILENAME_MAX - 1, "%s/%s",
+ KEY_DIR, g_defaultDHParamFile);
+ }
+ if ((rc = matrixSslLoadDhParams(keys, certpath)) < 0)
+ {
+ _psTrace("Unable to load static key material. Exiting\n");
+ return rc;
+ }
+# endif
- /* Were any cipher suites disabled? */
- if (g_disabledCiphers > 0) {
- for (rc = 0; rc < g_disabledCiphers; rc++) {
- /* Global disable. Per-session disables would be done immediately
- following matrixSslNewServerSession if desired */
- matrixSslSetCipherSuiteEnabledStatus(NULL, g_disabledCipher[rc],
- PS_FALSE);
- }
- }
-
- /* Create the listening socket that will accept incoming connections */
- if ((lfd = lsocketListen(g_port, &err)) == INVALID_SOCKET) {
- _psTraceInt("Can't listen on port %d\n", g_port);
- goto L_EXIT;
- }
+ /* Were any cipher suites disabled? */
+ if (g_disabledCiphers > 0)
+ {
+ for (rc = 0; rc < g_disabledCiphers; rc++)
+ {
+ /* Global disable. Per-session disables would be done immediately
+ following matrixSslNewServerSession if desired */
+ matrixSslSetCipherSuiteEnabledStatus(NULL, g_disabledCipher[rc],
+ PS_FALSE);
+ }
+ }
- /* Main select loop to handle sockets events */
- while (!g_exitFlag) {
- selectLoop(keys, lfd);
- displayStats();
- }
+ /* Create the listening socket that will accept incoming connections */
+ if ((lfd = lsocketListen(g_port, &err)) == INVALID_SOCKET)
+ {
+ _psTraceInt("Can't listen on port %d\n", g_port);
+ goto L_EXIT;
+ }
- /* Close any active connections */
- while (!DLListIsEmpty(&g_conns)) {
- httpConn_t *cp;
- DLListEntry *pList;
- pList = DLListGetHead(&g_conns);
- cp = DLListGetContainer(pList, httpConn_t, List);
- closeConn(cp, PS_SUCCESS);
- }
+ /* Main select loop to handle sockets events */
+ while (!g_exitFlag)
+ {
+ selectLoop(keys, lfd);
+ displayStats();
+ }
+
+ /* Close any active connections */
+ while (!DLListIsEmpty(&g_conns))
+ {
+ httpConn_t *cp;
+ DLListEntry *pList;
+ pList = DLListGetHead(&g_conns);
+ cp = DLListGetContainer(pList, httpConn_t, List);
+ closeConn(cp, PS_SUCCESS);
+ }
L_EXIT:
- if (lfd != INVALID_SOCKET) close(lfd);
- matrixSslClose();
+ if (lfd != INVALID_SOCKET)
+ {
+ close(lfd);
+ }
+ matrixSslClose();
- return 0;
+ return 0;
}
/******************************************************************************/
/*
- Close a socket and free associated SSL context and buffers
+ Close a socket and free associated SSL context and buffers
*/
static void closeConn(httpConn_t *cp, int32 reason)
{
-#ifdef SEND_CLOSURE_ALERT
- unsigned char *buf;
-#endif
- int32 len;
+# ifdef SEND_CLOSURE_ALERT
+ unsigned char *buf;
+# endif
+ int32 len;
- DLListRemove(&cp->List);
-#ifdef SEND_CLOSURE_ALERT
- /* Quick attempt to send a closure alert, don't worry about failure */
- if (matrixSslEncodeClosureAlert(cp->ssl) >= 0) {
- if ((len = matrixSslGetOutdata(cp->ssl, &buf)) > 0) {
- //psTraceBytes("closure alert", buf, len);
- if ((len = (int32)send(cp->fd, buf, len, MSG_DONTWAIT)) > 0) {
- matrixSslSentData(cp->ssl, len);
- }
- }
- }
-#endif
- if (cp->parsebuf != NULL) {
- psAssert(cp->parsebuflen > 0);
- free(cp->parsebuf);
- cp->parsebuflen = 0;
- }
+ DLListRemove(&cp->List);
+# ifdef SEND_CLOSURE_ALERT
+ /* Quick attempt to send a closure alert, don't worry about failure */
+ if (matrixSslEncodeClosureAlert(cp->ssl) >= 0)
+ {
+ if ((len = matrixSslGetOutdata(cp->ssl, &buf)) > 0)
+ {
+ /* psTraceBytes("closure alert", buf, len); */
+ if ((len = (int32) send(cp->fd, buf, len, MSG_DONTWAIT)) > 0)
+ {
+ matrixSslSentData(cp->ssl, len);
+ }
+ }
+ }
+# endif
+ if (cp->parsebuf != NULL)
+ {
+ psAssert(cp->parsebuflen > 0);
+ free(cp->parsebuf);
+ cp->parsebuflen = 0;
+ }
- matrixSslDeleteSession(cp->ssl);
+ matrixSslDeleteSession(cp->ssl);
- if (cp->fd != INVALID_SOCKET) {
- close(cp->fd);
- }
- if (reason >= 0) {
-/* _psTraceInt("=== Closing Client %d ===\n", cp->fd); */
- } else {
- _psTraceInt("=== Closing Client %d on Error ===\n", cp->fd);
- }
- free(cp);
+ if (cp->fd != INVALID_SOCKET)
+ {
+ close(cp->fd);
+ }
+ if (reason >= 0)
+ {
+/* _psTraceInt("=== Closing Client %d ===\n", cp->fd); */
+ }
+ else
+ {
+ _psTraceInt("=== Closing Client %d on Error ===\n", cp->fd);
+ }
+ free(cp);
}
/******************************************************************************/
/*
- Establish a listening socket for incomming connections
+ Establish a listening socket for incomming connections
*/
static SOCKET lsocketListen(short port, int32 *err)
{
- struct sockaddr_in addr = { 0 };
- SOCKET fd;
+ struct sockaddr_in addr = { 0 };
+ SOCKET fd;
- if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
- _psTrace("Error creating listen socket\n");
- *err = SOCKET_ERRNO;
- return INVALID_SOCKET;
- }
+ if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
+ {
+ _psTrace("Error creating listen socket\n");
+ *err = SOCKET_ERRNO;
+ return INVALID_SOCKET;
+ }
- if (setSocketOptions(fd) < 0) {
- close(fd);
- return INVALID_SOCKET;
- }
- addr.sin_family = AF_INET;
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = INADDR_ANY;
- if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- close(fd);
- _psTrace("Can't bind socket. Port in use or insufficient privilege\n");
- *err = SOCKET_ERRNO;
- return INVALID_SOCKET;
- }
- if (listen(fd, SOMAXCONN) < 0) {
- close(fd);
- _psTrace("Error listening on socket\n");
- *err = SOCKET_ERRNO;
- return INVALID_SOCKET;
- }
- _psTraceInt("Listening on port %d\n", port);
- return fd;
+ if (setSocketOptions(fd) < 0)
+ {
+ close(fd);
+ return INVALID_SOCKET;
+ }
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ addr.sin_addr.s_addr = INADDR_ANY;
+ if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
+ {
+ close(fd);
+ _psTrace("Can't bind socket. Port in use or insufficient privilege\n");
+ *err = SOCKET_ERRNO;
+ return INVALID_SOCKET;
+ }
+ if (listen(fd, SOMAXCONN) < 0)
+ {
+ close(fd);
+ _psTrace("Error listening on socket\n");
+ *err = SOCKET_ERRNO;
+ return INVALID_SOCKET;
+ }
+ _psTraceInt("Listening on port %d\n", port);
+ return fd;
}
/******************************************************************************/
/*
- Make sure the socket is not inherited by exec'd processes
- Set the REUSE flag to minimize the number of sockets in TIME_WAIT
- Then we set REUSEADDR, NODELAY and NONBLOCK on the socket
-*/
+ Make sure the socket is not inherited by exec'd processes
+ Set the REUSE flag to minimize the number of sockets in TIME_WAIT
+ Then we set REUSEADDR, NODELAY and NONBLOCK on the socket
+ */
static int setSocketOptions(SOCKET fd)
{
- int rc;
+ int rc;
-#ifdef POSIX
- if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
- return PS_PLATFORM_FAIL;
- }
-#endif
- rc = 1;
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&rc, sizeof(rc)) < 0) {
- return PS_PLATFORM_FAIL;
- }
-#ifdef POSIX
- rc = 1;
- if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&rc, sizeof(rc)) < 0) {
- return PS_PLATFORM_FAIL;
- }
- if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK) < 0) {
- return PS_PLATFORM_FAIL;
- }
-#elif defined(WIN32)
- rc = 1; /* 1 for non-block, 0 for block */
- if (ioctlsocket(fd, FIONBIO, &rc) < 0) {
- return PS_PLATFORM_FAIL;
- }
-#endif
-#ifdef __APPLE__ /* MAC OS X */
- rc = 1;
- if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&rc, sizeof(rc)) < 0) {
- return PS_PLATFORM_FAIL;
- }
-#endif
- return PS_SUCCESS;
+# ifdef POSIX
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
+ {
+ return PS_PLATFORM_FAIL;
+ }
+# endif
+ rc = 1;
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &rc, sizeof(rc)) < 0)
+ {
+ return PS_PLATFORM_FAIL;
+ }
+# ifdef POSIX
+ rc = 1;
+ if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &rc, sizeof(rc)) < 0)
+ {
+ return PS_PLATFORM_FAIL;
+ }
+ if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK) < 0)
+ {
+ return PS_PLATFORM_FAIL;
+ }
+# elif defined(WIN32)
+ rc = 1; /* 1 for non-block, 0 for block */
+ if (ioctlsocket(fd, FIONBIO, &rc) < 0)
+ {
+ return PS_PLATFORM_FAIL;
+ }
+# endif
+# ifdef __APPLE__ /* MAC OS X */
+ rc = 1;
+ if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *) &rc, sizeof(rc)) < 0)
+ {
+ return PS_PLATFORM_FAIL;
+ }
+# endif
+ return PS_SUCCESS;
}
-#ifdef POSIX
+# ifdef POSIX
/******************************************************************************/
/*
- Handle some signals on POSIX platforms
- Lets ctrl-c do a clean exit of the server.
+ Handle some signals on POSIX platforms
+ Lets ctrl-c do a clean exit of the server.
*/
static int32 sighandlers(void)
{
- if (signal(SIGINT, sigintterm_handler) == SIG_ERR ||
- signal(SIGTERM, sigintterm_handler) == SIG_ERR ||
- signal(SIGPIPE, SIG_IGN) == SIG_ERR ||
- signal(SIGSEGV, sigsegv_handler) == SIG_ERR) {
- return PS_PLATFORM_FAIL;
- }
- return 0;
+ if (signal(SIGINT, sigintterm_handler) == SIG_ERR ||
+ signal(SIGTERM, sigintterm_handler) == SIG_ERR ||
+ signal(SIGPIPE, SIG_IGN) == SIG_ERR ||
+ signal(SIGSEGV, sigsegv_handler) == SIG_ERR)
+ {
+ return PS_PLATFORM_FAIL;
+ }
+ return 0;
}
/* Warn on segmentation violation */
static void sigsegv_handler(int unused)
{
- printf("Segfault! Please report this as a bug to support@peersec.com\n");
- exit(EXIT_FAILURE);
+ printf("Segfault! Please report this as a bug to support@peersec.com\n");
+ exit(EXIT_FAILURE);
}
/* catch ctrl-c or sigterm */
static void sigintterm_handler(int unused)
{
- g_exitFlag = 1; /* Rudimentary exit flagging */
- printf("Exiting due to interrupt.\n");
+ g_exitFlag = 1; /* Rudimentary exit flagging */
+ printf("Exiting due to interrupt.\n");
}
-#endif /* POSIX */
+# endif /* POSIX */
-#else
+# else
/******************************************************************************/
/*
- Stub main for compiling without server enabled
-*/
+ Stub main for compiling without server enabled
+ */
int32 main(int32 argc, char **argv)
{
- printf("USE_SERVER_SIDE_SSL must be enabled in matrixsslConfig.h at build" \
- " time to run this application\n");
- return -1;
+ printf("USE_SERVER_SIDE_SSL must be enabled in matrixsslConfig.h at build" \
+ " time to run this application\n");
+ return -1;
}
-#endif /* USE_SERVER_SIDE_SSL */
+# endif /* USE_SERVER_SIDE_SSL */
/******************************************************************************/
#else
-#include
+# include
int main(int argc, char **argv)
{
- printf("You need to #define MATRIX_USE_FILE_SYSTEM for this test\n");
- return 1;
+ printf("You need to #define MATRIX_USE_FILE_SYSTEM for this test\n");
+ return 1;
}
#endif /* MATRIX_USE_FILE_SYSTEM */
diff --git a/common.mk b/common.mk
index 098607c..095d9c5 100644
--- a/common.mk
+++ b/common.mk
@@ -6,6 +6,11 @@
#-------------------------------------------------------------------------------
+# Allow extra CFLAGS, CPPFLAGS and LDFLAGS to be used.
+LDFLAGS += $(EXTRA_LDFLAGS)
+CFLAGS += $(CFLAGS_STANDARD) $(CFLAGS_PLATFORM) $(CFLAGS_ADDITIONAL) $(CFLAGS_WARNINGS) $(CFLAGS_CPU) $(CFLAGS_ASM) $(CFLAGS_PROFILE) $(DEBUGGABLE) $(EXTRA_CFLAGS)
+CPPFLAGS += $(CPPFLAGS_STANDARD) $(CPPFLAGS_PLATFORM) $(CPPFLAGS_ADDITIONAL) $(CPPFLAGS_WARNINGS) $(CPPFLAGS_CPPPU) $(CPPFLAGS_ASM) $(CPPFLAGS_PROFILE) $(DEBUGGABLE) $(EXTRA_CPPFLAGS)
+
#-------------------------------------------------------------------------------
## Makefile variables that must be defined in this file
# @param[out] $(BUILD) Set here for release or debug
@@ -227,12 +232,13 @@ ifneq (,$(findstring arm,$(CCARCH)))
endif
endif
+CFLAGS_GARBAGE_COLLECTION=-ffunction-sections -fdata-sections
ifdef MATRIX_DEBUG
-CFLAGS+=-ffunction-sections -fdata-sections
+CFLAGS+=$(CFLAGS_GARBAGE_COLLECTION)
endif
ifndef MATRIX_DEBUG
CFLAGS_OMIT_FRAMEPOINTER=-fomit-frame-pointer
-CFLAGS+=-ffunction-sections -fdata-sections $(CFLAGS_OMIT_FRAMEPOINTER)
+CFLAGS+=$(CFLAGS_GARBAGE_COLLECTION) $(CFLAGS_OMIT_FRAMEPOINTER)
endif
# If we are using clang (it may be invoked via 'cc' or 'gcc'),
diff --git a/configs/default/coreConfig.h b/configs/default/coreConfig.h
index 1dc1ecf..81fa819 100644
--- a/configs/default/coreConfig.h
+++ b/configs/default/coreConfig.h
@@ -1,83 +1,83 @@
/**
- * @file coreConfig.h
- * @version $Format:%h%d$
+ * @file coreConfig.h
+ * @version $Format:%h%d$
*
- * Configuration settings for Matrix core module.
+ * Configuration settings for Matrix core module.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_CORECONFIG
-#define _h_PS_CORECONFIG
+# define _h_PS_CORECONFIG
/******************************************************************************/
/* Configurable features */
/******************************************************************************/
/**
- Enable various levels of trace.
- When these option is turned off, messages are silently
- discarded and their text does not take space in the binary image.
-*/
-//#define USE_CORE_TRACE
-#ifndef NO_CORE_ERROR
- #define USE_CORE_ERROR
-#endif
-#ifndef NO_CORE_ASSERT
- #define USE_CORE_ASSERT
-#endif
-
-/**
- If enabled, calls to the psError set of APIs will perform a platform
- abort on the exeutable to aid in debugging.
-*/
-#ifdef DEBUG
-//#define HALT_ON_PS_ERROR /* NOT RECOMMENDED FOR PRODUCTION BUILDS */
-#endif
-
-/**
- Include the psCoreOsdepMutex family of APIs
-
- @note If intending to compile crypto-cl, then this flag should
- always be set.
-*/
-#ifndef NO_MULTITHREADING
-#define USE_MULTITHREADING
-#endif /* NO_MULTITHREADING */
-
-/**
- Include the psNetwork family of APIs
-
- These APIs allow simple high-level socket api.
+ Enable various levels of trace.
+ When these option is turned off, messages are silently
+ discarded and their text does not take space in the binary image.
*/
-#define USE_PS_NETWORKING
+/* #define USE_CORE_TRACE */
+# ifndef NO_CORE_ERROR
+# define USE_CORE_ERROR
+# endif
+# ifndef NO_CORE_ASSERT
+# define USE_CORE_ASSERT
+# endif
-#endif /* _h_PS_CORECONFIG */
+/**
+ If enabled, calls to the psError set of APIs will perform a platform
+ abort on the exeutable to aid in debugging.
+ */
+# ifdef DEBUG
+/* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */
+# endif
+
+/**
+ Include the psCoreOsdepMutex family of APIs
+
+ @note If intending to compile crypto-cl, then this flag should
+ always be set.
+*/
+# ifndef NO_MULTITHREADING
+# define USE_MULTITHREADING
+# endif /* NO_MULTITHREADING */
+
+/**
+ Include the psNetwork family of APIs
+
+ These APIs allow simple high-level socket api.
+ */
+# define USE_PS_NETWORKING
+
+#endif /* _h_PS_CORECONFIG */
/******************************************************************************/
diff --git a/configs/default/cryptoConfig.h b/configs/default/cryptoConfig.h
index ce4252b..3b35542 100644
--- a/configs/default/cryptoConfig.h
+++ b/configs/default/cryptoConfig.h
@@ -1,220 +1,242 @@
/**
- * @file cryptoConfig.h
- * @version $Format:%h%d$
+ * @file cryptoConfig.h
+ * @version $Format:%h%d$
*
- * Configuration file for crypto features.
+ * Configuration file for crypto features.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_CRYPTOCONFIG
-#define _h_PS_CRYPTOCONFIG
+# define _h_PS_CRYPTOCONFIG
/******************************************************************************/
/* Configurable features */
/******************************************************************************/
/**
- Define to enable psTrace*Crypto APIs for debugging the crypto module.
-*/
-//#define USE_CRYPTO_TRACE
+ Define to enable psTrace*Crypto APIs for debugging the crypto module.
+ */
+/* #define USE_CRYPTO_TRACE */
-#ifdef DEBUG
-#define CRYPTO_ASSERT/**< Extra sanity asserts */
-#endif
+# ifdef DEBUG
+/* #define CRYPTO_ASSERT *//**< Extra sanity asserts */
+# endif
/******************************************************************************/
/*
- Use built-in cryptographic library delivered with MatrixSSL
-*/
-#define USE_NATIVE_RSA /* Default built-in software support */
+ Use built-in cryptographic library delivered with MatrixSSL
+ */
+# define USE_NATIVE_RSA /* Default built-in software support */
/******************************************************************************/
/**
- Security related settings.
+ Security related settings.
- @security MIN_*_BITS is the minimum supported key sizes in bits, weaker
- keys will be rejected.
-*/
-#define MIN_ECC_BITS 192/**< @security Affects ECC curves below */
+ @security MIN_*_BITS is the minimum supported key sizes in bits, weaker
+ keys will be rejected.
+ */
+# define MIN_ECC_BITS 192/**< @security Affects ECC curves below */
-#define MIN_RSA_BITS 1024
+# define MIN_RSA_BITS 1024
-#define MIN_DH_BITS 1024
+# define MIN_DH_BITS 1024
-#define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */
+# define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */
/******************************************************************************/
/**
- Public-Key Algorithm Support.
-*/
-#define USE_RSA
-#define USE_ECC
-//#define USE_DH
+ Public-Key Algorithm Support.
+ */
+# define USE_RSA
+# define USE_ECC
+# define USE_DH
/**< @note Enable verification of DSA signatures in certificate validation.
Works only when using the CL/SL library. @pre USE_CERT_PARSE. */
-#define USE_DSA_VERIFY
+/* #define USE_DSA_VERIFY */
/******************************************************************************/
/**
Build the PKCS and ASN1 extra CL sublibraries.
- These are needed by the CL_PKCS API.
-*/
+ These are needed by the CL_PKCS API.
+ */
/******************************************************************************/
/**
- Define to enable the individual NIST Prime curves.
- @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
-*/
-#ifdef USE_ECC
-//#define USE_SECP192R1 /**< @security FIPS allowed for sig ver only. */
-//#define USE_SECP224R1
- #define USE_SECP256R1/**< @security NIST_SHALL */
- #define USE_SECP384R1/**< @security NIST_SHALL */
-//#define USE_SECP521R1
-#endif
+ Define to enable the individual NIST Prime curves.
+ @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
+ */
+# ifdef USE_ECC
+# define USE_SECP192R1/**< @security FIPS allowed for sig ver only. */
+# define USE_SECP224R1
+# define USE_SECP256R1/**< @security NIST_SHALL */
+# define USE_SECP384R1/**< @security NIST_SHALL */
+# define USE_SECP521R1
+# endif
/**
- Define to enable the individual Brainpool curves.
- @see https://tools.ietf.org/html/rfc5639
- @security WARNING: Public points on Brainpool curves are not validated
-*/
-#ifdef USE_ECC
-//#define USE_BRAIN224R1
-//#define USE_BRAIN256R1
-//#define USE_BRAIN384R1
-//#define USE_BRAIN512R1
-#endif
+ Define to enable the individual Brainpool curves.
+ @see https://tools.ietf.org/html/rfc5639
+ @security WARNING: Public points on Brainpool curves are not validated
+ */
+# ifdef USE_ECC
+/* #define USE_BRAIN224R1 */
+/* #define USE_BRAIN256R1 */
+/* #define USE_BRAIN384R1 */
+/* #define USE_BRAIN512R1 */
+# endif
/******************************************************************************/
/**
- Symmetric and AEAD ciphers.
- @security Deprecated ciphers must be enabled in cryptolib.h
-*/
-#define USE_AES/* Enable/Disable AES */
-#define USE_AES_CBC
-#define USE_AES_GCM
+ Symmetric and AEAD ciphers.
+ @security Deprecated ciphers must be enabled in cryptolib.h
+ */
+/* #define USE_AES *//* Enable/Disable AES */
+# define USE_AES_CBC
+# define USE_AES_GCM
-#ifdef USE_LIBSODIUM
-//#define USE_CHACHA20_POLY1305
-#endif
+# ifdef USE_LIBSODIUM
+/* #define USE_CHACHA20_POLY1305 */
+# endif
/** @security 3DES is still relatively secure, however is deprecated for TLS */
-#define USE_3DES
+# define USE_3DES
/******************************************************************************/
/**
- Digest algorithms.
+ Digest algorithms.
- @note SHA256 and above are used with TLS 1.2, and also used for
- certificate signatures on some certificates regardless of TLS version.
+ @note SHA256 and above are used with TLS 1.2, and also used for
+ certificate signatures on some certificates regardless of TLS version.
- @security MD5 is deprecated, but still required in combination with SHA-1
- for TLS handshakes before TLS 1.2, meaning that the strength is at least
- that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable
- MD5 only for this purpose. The only other usage of MD5 by TLS is for
- certificate signatures and MD5 based cipher suites. Both of which are
- disabled at compile time by default.
+ @security MD5 is deprecated, but still required in combination with SHA-1
+ for TLS handshakes before TLS 1.2, meaning that the strength is at least
+ that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable
+ MD5 only for this purpose. The only other usage of MD5 by TLS is for
+ certificate signatures and MD5 based cipher suites. Both of which are
+ disabled at compile time by default.
- @security SHA1 will be deprecated in the future, but is still required in
- combination with MD5 for versions prior to TLS 1.2. In addition, SHA1
- certificates are still commonly used, so SHA1 support may be needed
- to validate older certificates. It is possible to completely disable
- SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting
- only with newer certificates.
-*/
-//#define USE_SHA224 /**< @note Used only for cert signature */
-#define USE_SHA256/**< @note Required for TLS 1.2 and above */
-#define USE_HMAC_SHA256
-#define USE_SHA384/**< @pre USE_SHA512 */
-#define USE_HMAC_SHA384
-#define USE_SHA512
+ @security SHA1 will be deprecated in the future, but is still required in
+ combination with MD5 for versions prior to TLS 1.2. In addition, SHA1
+ certificates are still commonly used, so SHA1 support may be needed
+ to validate older certificates. It is possible to completely disable
+ SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting
+ only with newer certificates.
+ */
+/* #define USE_SHA224 *//**< @note Used only for cert signature */
+# define USE_SHA256/**< @note Required for TLS 1.2 and above */
+# define USE_HMAC_SHA256
+# define USE_SHA384/**< @pre USE_SHA512 */
+# define USE_HMAC_SHA384
+# define USE_SHA512
/**
- @security SHA-1 based hashes are deprecated but enabled by default
- @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below.
-*/
-#define USE_SHA1
-#define USE_HMAC_SHA1
+ @security SHA-1 based hashes are deprecated but enabled by default
+ @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below.
+ */
+# define USE_SHA1
+# define USE_HMAC_SHA1
/**
- @security MD5 is considered insecure, but required by TLS < 1.2
- @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below.
-*/
-#define USE_MD5
-#define USE_MD5SHA1 /* Required for < TLS 1.2 Handshake */
-#define USE_HMAC_MD5 /* Required for < TLS 1.2 Handshake (PRF) */
+ @security MD5 is considered insecure, but required by TLS < 1.2
+ @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below.
+ */
+# define USE_MD5
+# define USE_MD5SHA1/* Required for < TLS 1.2 Handshake */
+# define USE_HMAC_MD5
/**
@security MD2 is considered insecure, but is sometimes used for
- verification of legacy root certificate signatures.
- @note MD2 signature verification also requires
- ENABLE_MD5_SIGNED_CERTS and USE_MD5.
-*/
-//#define USE_MD2
+ verification of legacy root certificate signatures.
+ @note MD2 signature verification also requires
+ ENABLE_MD5_SIGNED_CERTS and USE_MD5.
+ */
+/* #define USE_MD2 */
/* Please enable, unless using no HMAC algorithms. */
-#define USE_HMAC
+# define USE_HMAC
/******************************************************************************/
/**
- X.509 Certificates/PKI
-*/
-#define USE_BASE64_DECODE
-#define USE_X509/**< Enable minimal X.509 support. */
-#define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */
-#define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */
- /**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */
-//#define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
- /**< Support extra distinguished name attributes not mentioned in RFC 5280. */
-//#define USE_EXTRA_DN_ATTRIBUTES
-#define ENABLE_CA_CERT_HASH/**< Used only for TLS trusted CA ind ext. */
-//#define ENABLE_MD5_SIGNED_CERTS /** @security Accept MD5 signed certs? */
-#define ENABLE_SHA1_SIGNED_CERTS/** @security Accept SHA1 signed certs? */
- /**< @security Allow parsing of locally trusted v1 root certs? */
-//#define ALLOW_VERSION_1_ROOT_CERT_PARSE
-#define USE_CRL/***< @pre USE_FULL_CERT_PARSE */
-#define USE_OCSP/**< @pre USE_SHA1 */
+ X.509 Certificates/PKI
+ */
+# define USE_BASE64_DECODE
+# define USE_X509/**< Enable minimal X.509 support. */
+# define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */
+# define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */
+/**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */
+/* #define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
+/**< Support extra distinguished name attributes not mentioned in RFC 5280. */
+/* #define USE_EXTRA_DN_ATTRIBUTES */
+/* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */
+/* #define ENABLE_MD5_SIGNED_CERTS *//** @security Accept MD5 signed certs? */
+# define ENABLE_SHA1_SIGNED_CERTS/** @security Accept SHA1 signed certs? */
+/**< @security Allow parsing of locally trusted v1 root certs? */
+/* #define ALLOW_VERSION_1_ROOT_CERT_PARSE */
+/**
+ When parsing certificates, always also retain the unparsed DER data.
+ Enabling this has the same effect as setting the
+ CERT_STORE_UNPARSED_BUFFER flag in each psX509ParseCert call.
+ */
+/* #define ALWAYS_KEEP_CERT_DER */
+/**
+ Always attempt to match expectedName with the subject CN, even if
+ a supported, but non-matching subjectAltName was presented.
+ The default behaviour is to check the CN only when no supported SAN
+ was presented, in accordance with Section 6.4.4 of RFC 6125.
+ */
+/* #define ALWAYS_CHECK_SUBJECT_CN_IN_HOSTNAME_VALIDATION */
+# define USE_CRL/***< @pre USE_FULL_CERT_PARSE */
+# ifdef USE_CRL
+/**
+ Allow CRL authentication to succeed even when signer CA's cert does not
+ have the keyUsage extension and thus no cRLSign bit.
+ Note that RFC 5280 requires CRL issuer certs to have the keyUsage extension
+ and the cRLSign bit.
+ */
+/* #define ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE */
+# endif
+# define USE_OCSP/**< @pre USE_SHA1 */
/******************************************************************************/
/**
- Various PKCS standards support
-*/
-#define USE_PRIVATE_KEY_PARSING
-//#define USE_PKCS5 /**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */
+ Various PKCS standards support
+ */
+# define USE_PRIVATE_KEY_PARSING
+# define USE_PKCS5/**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */
/**< Enable PBKDF1 in priv key PEM encryption. @pre USE_PKCS5 and @pre USE_MD5. @security Not recommended. */
-//#define USE_PBKDF1
-#define USE_PKCS8/* Alternative private key storage format */
-//#define USE_PKCS12 /**< @pre USE_PKCS8 */
-//#define USE_PKCS1_OAEP /* OAEP padding algorithm */
-//#define USE_PKCS1_PSS /* PSS padding algorithm */
+# define USE_PBKDF1
+# define USE_PKCS8/* Alternative private key storage format */
+# define USE_PKCS12/**< @pre USE_PKCS8 */
+# define USE_PKCS1_OAEP/* OAEP padding algorithm */
+# define USE_PKCS1_PSS/* PSS padding algorithm */
-#endif /* _h_PS_CRYPTOCONFIG */
+#endif /* _h_PS_CRYPTOCONFIG */
/******************************************************************************/
diff --git a/configs/default/matrixsslConfig.h b/configs/default/matrixsslConfig.h
index 8d113cd..3d1af9d 100644
--- a/configs/default/matrixsslConfig.h
+++ b/configs/default/matrixsslConfig.h
@@ -1,160 +1,160 @@
/**
- * @file matrixsslConfig.h
- * @version $Format:%h%d$
+ * @file matrixsslConfig.h
+ * @version $Format:%h%d$
*
- * Configuration settings for building the MatrixSSL library.
- * This configuration is intended to be used in FIPS Mode of operation.
- * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and
- * to enable the most commonly used cipher suites.
+ * Configuration settings for building the MatrixSSL library.
+ * This configuration is intended to be used in FIPS Mode of operation.
+ * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and
+ * to enable the most commonly used cipher suites.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_MATRIXSSLCONFIG
-#define _h_MATRIXSSLCONFIG
+# define _h_MATRIXSSLCONFIG
-#ifdef __cplusplus
+# ifdef __cplusplus
extern "C" {
-#endif
+# endif
/**
- NIST SP 800-52 Rev 1 Conformance.
- Guidelines for the Selection, Configuration, and Use of Transport Layer
- Security (TLS) Implementations
- The key words "shall", "shall not", "should", "should not" and "may"
- are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as
- "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility
- is not relevant.
- @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf
-*/
+ NIST SP 800-52 Rev 1 Conformance.
+ Guidelines for the Selection, Configuration, and Use of Transport Layer
+ Security (TLS) Implementations
+ The key words "shall", "shall not", "should", "should not" and "may"
+ are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as
+ "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility
+ is not relevant.
+ @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf
+ */
/******************************************************************************/
/**
- Show which SSL messages are created and parsed
-*/
-//#define USE_SSL_HANDSHAKE_MSG_TRACE
+ Show which SSL messages are created and parsed
+ */
+/* #define USE_SSL_HANDSHAKE_MSG_TRACE */
/**
- Informational trace that could help pinpoint problems with SSL connections
-*/
-//#define USE_SSL_INFORMATIONAL_TRACE
-//#define USE_DTLS_DEBUG_TRACE
+ Informational trace that could help pinpoint problems with SSL connections
+ */
+/* #define USE_SSL_INFORMATIONAL_TRACE */
+/* #define USE_DTLS_DEBUG_TRACE */
/******************************************************************************/
/**
- Recommended cipher suites.
- Define the following to enable various cipher suites
- At least one of these must be defined. If multiple are defined,
- the handshake negotiation will determine which is best for the connection.
- @note Ephemeral ciphersuites offer perfect forward security (PFS)
- at the cost of a slower TLS handshake.
-*/
+ Recommended cipher suites.
+ Define the following to enable various cipher suites
+ At least one of these must be defined. If multiple are defined,
+ the handshake negotiation will determine which is best for the connection.
+ @note Ephemeral ciphersuites offer perfect forward security (PFS)
+ at the cost of a slower TLS handshake.
+ */
/** Ephemeral ECC DH keys, ECC DSA certificates */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA/**< @security NIST_MAY */
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA/**< @security NIST_MAY */
/* TLS 1.2 ciphers */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */
/** Ephemeral ECC DH keys, RSA certificates */
-#define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+# define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
/* TLS 1.2 ciphers */
-#define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
-#define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+# define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
+# define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */
/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */
-//#define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
-//#define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA */
+/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA */
/* TLS 1.2 ciphers */
-//#define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
-//#define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */
+/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */
/** Non-Ephemeral RSA keys/certificates */
-#define USE_TLS_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHALL */
-#define USE_TLS_RSA_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD */
+# define USE_TLS_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHALL */
+# define USE_TLS_RSA_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD */
/* TLS 1.2 ciphers */
-#define USE_TLS_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */
-#define USE_TLS_RSA_WITH_AES_256_CBC_SHA256/**< @security NIST_MAY */
-#define USE_TLS_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHALL */
-#define USE_TLS_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
+# define USE_TLS_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */
+# define USE_TLS_RSA_WITH_AES_256_CBC_SHA256/**< @security NIST_MAY */
+# define USE_TLS_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHALL */
+# define USE_TLS_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
/******************************************************************************/
/**
- These cipher suites are secure, but not widely deployed.
-*/
+ These cipher suites are secure, but not widely deployed.
+ */
/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */
-//#define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+/* #define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
/** Ephemeral Diffie-Hellman ciphersuites, with PSK authentication */
-//#define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA /**< @security NIST_SHOULD_NOT */
-//#define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA /**< @security NIST_SHOULD_NOT */
+/* #define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD_NOT */
+/* #define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD_NOT */
/** Ephemeral ECC DH keys, RSA certificates */
-#define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA/**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHOULD */
/** Pre-Shared Key Ciphers.
- NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary
+ NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary
See NIST SP 800-52 Rev 1 Appendix C */
-//#define USE_TLS_PSK_WITH_AES_128_CBC_SHA /**< @security NIST_SHOULD_NOT */
-//#define USE_TLS_PSK_WITH_AES_256_CBC_SHA /**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD_NOT */
/* TLS 1.2 ciphers */
-//#define USE_TLS_PSK_WITH_AES_128_CBC_SHA256 /**< @security NIST_SHOULD_NOT */
-//#define USE_TLS_PSK_WITH_AES_256_CBC_SHA384 /**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_256_CBC_SHA384/**< @security NIST_SHOULD_NOT */
/** Non-Ephemeral ECC DH keys, ECC DSA certificates */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA/**< @security NIST_MAY */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA/**< @security NIST_MAY */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA/**< @security NIST_MAY */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA/**< @security NIST_MAY */
/* TLS 1.2 ciphers */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_MAY */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_MAY */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_MAY */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_MAY */
/** Non-Ephemeral ECC DH keys, RSA certificates */
-//#define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
-//#define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+# define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+# define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
/* TLS 1.2 ciphers */
-//#define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
-//#define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
-//#define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
-//#define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+# define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+# define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+# define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+# define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
/** Non-Ephemeral RSA keys/certificates */
-#define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA/**< @security NIST_SHALL */
+/* #define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHALL */
/** @note Some of (non-mandatory) cipher suites mentioned in NIST SP 800-52
Rev 1 are not supported by the MatrixSSL / MatrixDTLS.
@@ -166,171 +166,187 @@ extern "C" {
/******************************************************************************/
/**
- Ephemeral key cache support.
- If not using cache, new key exchange keys are created for each TLS session.
- If using cache, keys are generated initially, and re-used in each
- subsequent TLS connection within a given time frame and usage count.
- @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE
+ Ephemeral key cache support.
+ If not using cache, new key exchange keys are created for each TLS session.
+ If using cache, keys are generated initially, and re-used in each
+ subsequent TLS connection within a given time frame and usage count.
+ @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE
- @security Do not cache Ephemeral ECC keys as it is against some standards,
- including NIST SP 800-56A, when in FIPS 140-2 mode of operation.
-*/
-#define NO_ECC_EPHEMERAL_CACHE/**< @security NIST_SHALL */
-
-/******************************************************************************/
-/**
- Configure Support for TLS protocol versions.
- Define one of:
- USE_TLS_1_2_AND_ABOVE
- USE_TLS_1_1_AND_ABOVE
- USE_TLS_1_0_AND_ABOVE
- @note There is no option for enabling SSL3.0 at this level
-*/
-#define USE_TLS_1_1_AND_ABOVE/**< @security default 1_1_AND_ABOVE */
-//#define USE_TLS_1_2_AND_ABOVE /**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
-//#define USE_TLS_1_0_AND_ABOVE /**< @security no longer recommended. */
-
-/******************************************************************************/
-/**
- Datagram TLS support.
- Enables DTLS in addition to TLS.
- @pre TLS_1_1
-*/
-#define USE_DTLS
-
-/******************************************************************************/
-/**
- Compile time support for server or client side SSL
-*/
-#define USE_CLIENT_SIDE_SSL
-#define USE_SERVER_SIDE_SSL
-
-/******************************************************************************/
-/**
- Client certificate authentication
-*/
-#define USE_CLIENT_AUTH
-
-/**
- Enable if the server should send an empty CertificateRequest message if
- no CA files have been loaded
-*/
-//#define SERVER_CAN_SEND_EMPTY_CERT_REQUEST
-
-/**
- Enabling this define will allow the server to "downgrade" a client auth
- handshake to a standard handshake if the client replies to a
- CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback
- will be called with a NULL cert in this case and the user can determine if
- the handshake should continue in a non-client auth state.
-*/
-//#define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG
-
-/******************************************************************************/
-/**
- Enable the Application Layer Protocol Negotiation extension.
- Servers and Clients will still have to use the required public API to
- set protocols and register application callbacks to negotiate the
- protocol that will be tunneled over TLS.
- @see ALPN section in the developer's guide for information.
+ @security Do not cache Ephemeral ECC keys as it is against some standards,
+ including NIST SP 800-56A, when in FIPS 140-2 mode of operation.
*/
-//#define USE_ALPN
+/* #define NO_ECC_EPHEMERAL_CACHE *//**< @security NIST_SHALL */
/******************************************************************************/
/**
- Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the
- sha1 hash of each CA file to the server for help in server selection.
- This extra level of define is to help isolate the SHA1 requirement
-*/
-#define USE_TRUSTED_CA_INDICATION/**< @security NIST_SHOULD */
-
-/******************************************************************************/
-/**
- A client side configuration that requires a server to provide an OCSP
- response if the client uses the certitificate status request extension.
- The "must staple" terminology is typically associated with certificates
- at the X.509 layer but it is a good description of what is being required
- of the server at the TLS level.
- @pre USE_OCSP must be enbled at the crypto level and the client application
- must use the OCSPstapling session option at run time for this setting to
- have any effect
-*/
-#ifdef USE_OCSP
-#define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */
-#endif
-
-/******************************************************************************/
-/**
- Rehandshaking support.
-
- Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the
- protocol defined in RFC 5748 which fixed a critical exploit in
- the standard TLS specification.
-
- @security Looking towards TLS 1.3, which removes re-handshaking, this
- feature is disabled by default.
-*/
-//#define USE_REHANDSHAKING
-
-/******************************************************************************/
-/**
- If SERVER you may define the number of sessions to cache and how
- long a session will remain valid in the cache from first access.
- Session caching enables very fast "session resumption handshakes".
-
- SSL_SESSION_TABLE_SIZE minimum value is 1
- SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0
-
- @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0
- however, this will also immediately expire SESSION_TICKETS below.
-*/
-#ifdef USE_SERVER_SIDE_SSL
-#define SSL_SESSION_TABLE_SIZE 64
-#define SSL_SESSION_ENTRY_LIFE (86400*1000)/* one day, in milliseconds */
-#endif
-
-/******************************************************************************/
-/**
- Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE
- define applies to this method as well as the standard method. The
- SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list.
-*/
-#define USE_STATELESS_SESSION_TICKETS
-#define SSL_SESSION_TICKET_LIST_LEN 64
-
-/******************************************************************************/
-/**
- The initial buffer sizes for send and receive buffers in each ssl_t session.
- Buffers are internally grown if more incoming or outgoing data storage is
- needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the
- buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced
- to this size. Most standard SSL handshakes require on the order of 1024 B.
-
- SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE
+ Configure Support for TLS protocol versions.
+ Define one of:
+ USE_TLS_1_2_AND_ABOVE
+ USE_TLS_1_1_AND_ABOVE
+ USE_TLS_1_0_AND_ABOVE
+ @note There is no option for enabling SSL3.0 at this level
*/
-#ifndef USE_DTLS
-#define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */
-#define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */
-#else
+# define USE_TLS_1_1_AND_ABOVE/**< @security default 1_1_AND_ABOVE */
+/* #define USE_TLS_1_2_AND_ABOVE *//**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
+/* #define USE_TLS_1_0_AND_ABOVE *//**< @security no longer recommended. */
+
/******************************************************************************/
/**
- The Path Maximum Transmission Unit is the largest datagram that can be
- sent or recieved. It is beyond the scope of DTLS to negotiate this value
- so make sure both sides have agreed on this value. This is an enforced
- limitation in MatrixDTLS so connections will not succeed if a peer has a
- PTMU set larger than this value.
-*/
-#define DTLS_PMTU 1500 /* 1500 Default/Maximum datagram len */
-#define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
-#define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+ Datagram TLS support.
+ Enables DTLS in addition to TLS.
+ @pre TLS_1_1
+ */
+# define USE_DTLS
-//#define DTLS_SEND_RECORDS_INDIVIDUALLY /* Max one record per datagram */
-#endif
+/******************************************************************************/
+/**
+ Compile time support for server or client side SSL
+ */
+# define USE_CLIENT_SIDE_SSL
+# define USE_SERVER_SIDE_SSL
-#ifdef __cplusplus
+/******************************************************************************/
+/**
+ Client certificate authentication
+ */
+# define USE_CLIENT_AUTH
+
+# ifdef USE_CLIENT_AUTH
+/**
+ Enable the handshake_messages signature in the CertificateVerify
+ protocol message to be signed using an external module.
+ */
+/* #define USE_EXT_CERTIFICATE_VERIFY_SIGNING */
+# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING
+/**
+ Compile an example external module that allows the
+ USE_EXT_CERTIFICATE_VERIFY_SIGNING feature to be tested using the example
+ client program and sslTest.
+ */
+/* #define USE_EXT_EXAMPLE_MODULE */
+# endif
+# endif
+
+/**
+ Enable if the server should send an empty CertificateRequest message if
+ no CA files have been loaded
+ */
+/* #define SERVER_CAN_SEND_EMPTY_CERT_REQUEST */
+
+/**
+ Enabling this define will allow the server to "downgrade" a client auth
+ handshake to a standard handshake if the client replies to a
+ CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback
+ will be called with a NULL cert in this case and the user can determine if
+ the handshake should continue in a non-client auth state.
+ */
+/* #define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */
+
+/******************************************************************************/
+/**
+ Enable the Application Layer Protocol Negotiation extension.
+ Servers and Clients will still have to use the required public API to
+ set protocols and register application callbacks to negotiate the
+ protocol that will be tunneled over TLS.
+ @see ALPN section in the developer's guide for information.
+ */
+/* #define USE_ALPN */
+
+/******************************************************************************/
+/**
+ Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the
+ sha1 hash of each CA file to the server for help in server selection.
+ This extra level of define is to help isolate the SHA1 requirement
+ */
+/* #define USE_TRUSTED_CA_INDICATION *//**< @security NIST_SHOULD */
+
+/******************************************************************************/
+/**
+ A client side configuration that requires a server to provide an OCSP
+ response if the client uses the certitificate status request extension.
+ The "must staple" terminology is typically associated with certificates
+ at the X.509 layer but it is a good description of what is being required
+ of the server at the TLS level.
+ @pre USE_OCSP must be enbled at the crypto level and the client application
+ must use the OCSPstapling session option at run time for this setting to
+ have any effect
+ */
+# ifdef USE_OCSP
+# define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */
+# endif
+
+/******************************************************************************/
+/**
+ Rehandshaking support.
+
+ Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the
+ protocol defined in RFC 5748 which fixed a critical exploit in
+ the standard TLS specification.
+
+ @security Looking towards TLS 1.3, which removes re-handshaking, this
+ feature is disabled by default.
+ */
+/* #define USE_REHANDSHAKING */
+
+/******************************************************************************/
+/**
+ If SERVER you may define the number of sessions to cache and how
+ long a session will remain valid in the cache from first access.
+ Session caching enables very fast "session resumption handshakes".
+
+ SSL_SESSION_TABLE_SIZE minimum value is 1
+ SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0
+
+ @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0
+ however, this will also immediately expire SESSION_TICKETS below.
+ */
+# ifdef USE_SERVER_SIDE_SSL
+# define SSL_SESSION_TABLE_SIZE 32
+# define SSL_SESSION_ENTRY_LIFE (86400 * 1000)/* one day, in milliseconds */
+# endif
+
+/******************************************************************************/
+/**
+ Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE
+ define applies to this method as well as the standard method. The
+ SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list.
+ */
+# define USE_STATELESS_SESSION_TICKETS
+# define SSL_SESSION_TICKET_LIST_LEN 32
+
+/******************************************************************************/
+/**
+ The initial buffer sizes for send and receive buffers in each ssl_t session.
+ Buffers are internally grown if more incoming or outgoing data storage is
+ needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the
+ buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced
+ to this size. Most standard SSL handshakes require on the order of 1024 B.
+
+ SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE
+ */
+# ifndef USE_DTLS
+# define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */
+# define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */
+# else
+/******************************************************************************/
+/**
+ The Path Maximum Transmission Unit is the largest datagram that can be
+ sent or recieved. It is beyond the scope of DTLS to negotiate this value
+ so make sure both sides have agreed on this value. This is an enforced
+ limitation in MatrixDTLS so connections will not succeed if a peer has a
+ PTMU set larger than this value.
+ */
+# define DTLS_PMTU 1500 /* 1500 Default/Maximum datagram len */
+# define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+# define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+
+/* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */
+# endif
+
+# ifdef __cplusplus
}
-#endif
+# endif
-#endif /* _h_MATRIXCONFIG */
+#endif /* _h_MATRIXCONFIG */
/******************************************************************************/
diff --git a/configs/noecc/coreConfig.h b/configs/noecc/coreConfig.h
index 1dc1ecf..81fa819 100644
--- a/configs/noecc/coreConfig.h
+++ b/configs/noecc/coreConfig.h
@@ -1,83 +1,83 @@
/**
- * @file coreConfig.h
- * @version $Format:%h%d$
+ * @file coreConfig.h
+ * @version $Format:%h%d$
*
- * Configuration settings for Matrix core module.
+ * Configuration settings for Matrix core module.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_CORECONFIG
-#define _h_PS_CORECONFIG
+# define _h_PS_CORECONFIG
/******************************************************************************/
/* Configurable features */
/******************************************************************************/
/**
- Enable various levels of trace.
- When these option is turned off, messages are silently
- discarded and their text does not take space in the binary image.
-*/
-//#define USE_CORE_TRACE
-#ifndef NO_CORE_ERROR
- #define USE_CORE_ERROR
-#endif
-#ifndef NO_CORE_ASSERT
- #define USE_CORE_ASSERT
-#endif
-
-/**
- If enabled, calls to the psError set of APIs will perform a platform
- abort on the exeutable to aid in debugging.
-*/
-#ifdef DEBUG
-//#define HALT_ON_PS_ERROR /* NOT RECOMMENDED FOR PRODUCTION BUILDS */
-#endif
-
-/**
- Include the psCoreOsdepMutex family of APIs
-
- @note If intending to compile crypto-cl, then this flag should
- always be set.
-*/
-#ifndef NO_MULTITHREADING
-#define USE_MULTITHREADING
-#endif /* NO_MULTITHREADING */
-
-/**
- Include the psNetwork family of APIs
-
- These APIs allow simple high-level socket api.
+ Enable various levels of trace.
+ When these option is turned off, messages are silently
+ discarded and their text does not take space in the binary image.
*/
-#define USE_PS_NETWORKING
+/* #define USE_CORE_TRACE */
+# ifndef NO_CORE_ERROR
+# define USE_CORE_ERROR
+# endif
+# ifndef NO_CORE_ASSERT
+# define USE_CORE_ASSERT
+# endif
-#endif /* _h_PS_CORECONFIG */
+/**
+ If enabled, calls to the psError set of APIs will perform a platform
+ abort on the exeutable to aid in debugging.
+ */
+# ifdef DEBUG
+/* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */
+# endif
+
+/**
+ Include the psCoreOsdepMutex family of APIs
+
+ @note If intending to compile crypto-cl, then this flag should
+ always be set.
+*/
+# ifndef NO_MULTITHREADING
+# define USE_MULTITHREADING
+# endif /* NO_MULTITHREADING */
+
+/**
+ Include the psNetwork family of APIs
+
+ These APIs allow simple high-level socket api.
+ */
+# define USE_PS_NETWORKING
+
+#endif /* _h_PS_CORECONFIG */
/******************************************************************************/
diff --git a/configs/noecc/cryptoConfig.h b/configs/noecc/cryptoConfig.h
index dbb1072..db15553 100644
--- a/configs/noecc/cryptoConfig.h
+++ b/configs/noecc/cryptoConfig.h
@@ -1,220 +1,242 @@
/**
- * @file cryptoConfig.h
- * @version $Format:%h%d$
+ * @file cryptoConfig.h
+ * @version $Format:%h%d$
*
- * Configuration file for crypto features.
+ * Configuration file for crypto features.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_CRYPTOCONFIG
-#define _h_PS_CRYPTOCONFIG
+# define _h_PS_CRYPTOCONFIG
/******************************************************************************/
/* Configurable features */
/******************************************************************************/
/**
- Define to enable psTrace*Crypto APIs for debugging the crypto module.
-*/
-//#define USE_CRYPTO_TRACE
+ Define to enable psTrace*Crypto APIs for debugging the crypto module.
+ */
+/* #define USE_CRYPTO_TRACE */
-#ifdef DEBUG
-//#define CRYPTO_ASSERT /**< Extra sanity asserts */
-#endif
+# ifdef DEBUG
+/* #define CRYPTO_ASSERT *//**< Extra sanity asserts */
+# endif
/******************************************************************************/
/*
- Use built-in cryptographic library delivered with MatrixSSL
-*/
-#define USE_NATIVE_RSA /* Default built-in software support */
+ Use built-in cryptographic library delivered with MatrixSSL
+ */
+# define USE_NATIVE_RSA /* Default built-in software support */
/******************************************************************************/
/**
- Security related settings.
+ Security related settings.
- @security MIN_*_BITS is the minimum supported key sizes in bits, weaker
- keys will be rejected.
-*/
-#define MIN_ECC_BITS 192/**< @security Affects ECC curves below */
+ @security MIN_*_BITS is the minimum supported key sizes in bits, weaker
+ keys will be rejected.
+ */
+# define MIN_ECC_BITS 192/**< @security Affects ECC curves below */
-#define MIN_RSA_BITS 1024
+# define MIN_RSA_BITS 1024
-#define MIN_DH_BITS 1024
+# define MIN_DH_BITS 1024
-#define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */
+# define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */
/******************************************************************************/
/**
- Public-Key Algorithm Support.
-*/
-#define USE_RSA
-//#define USE_ECC
-#define USE_DH
+ Public-Key Algorithm Support.
+ */
+# define USE_RSA
+/* #define USE_ECC */
+# define USE_DH
/**< @note Enable verification of DSA signatures in certificate validation.
Works only when using the CL/SL library. @pre USE_CERT_PARSE. */
-//#define USE_DSA_VERIFY
+/* #define USE_DSA_VERIFY */
/******************************************************************************/
/**
Build the PKCS and ASN1 extra CL sublibraries.
- These are needed by the CL_PKCS API.
-*/
+ These are needed by the CL_PKCS API.
+ */
/******************************************************************************/
/**
- Define to enable the individual NIST Prime curves.
- @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
-*/
-#ifdef USE_ECC
- #define USE_SECP192R1/**< @security FIPS allowed for sig ver only. */
- #define USE_SECP224R1
- #define USE_SECP256R1/**< @security NIST_SHALL */
- #define USE_SECP384R1/**< @security NIST_SHALL */
- #define USE_SECP521R1
-#endif
+ Define to enable the individual NIST Prime curves.
+ @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
+ */
+# ifdef USE_ECC
+# define USE_SECP192R1/**< @security FIPS allowed for sig ver only. */
+# define USE_SECP224R1
+# define USE_SECP256R1/**< @security NIST_SHALL */
+# define USE_SECP384R1/**< @security NIST_SHALL */
+# define USE_SECP521R1
+# endif
/**
- Define to enable the individual Brainpool curves.
- @see https://tools.ietf.org/html/rfc5639
- @security WARNING: Public points on Brainpool curves are not validated
-*/
-#ifdef USE_ECC
-//#define USE_BRAIN224R1
-//#define USE_BRAIN256R1
-//#define USE_BRAIN384R1
-//#define USE_BRAIN512R1
-#endif
+ Define to enable the individual Brainpool curves.
+ @see https://tools.ietf.org/html/rfc5639
+ @security WARNING: Public points on Brainpool curves are not validated
+ */
+# ifdef USE_ECC
+/* #define USE_BRAIN224R1 */
+/* #define USE_BRAIN256R1 */
+/* #define USE_BRAIN384R1 */
+/* #define USE_BRAIN512R1 */
+# endif
/******************************************************************************/
/**
- Symmetric and AEAD ciphers.
- @security Deprecated ciphers must be enabled in cryptolib.h
-*/
-//#define USE_AES /* Enable/Disable AES */
-#define USE_AES_CBC
-#define USE_AES_GCM
+ Symmetric and AEAD ciphers.
+ @security Deprecated ciphers must be enabled in cryptolib.h
+ */
+/* #define USE_AES *//* Enable/Disable AES */
+# define USE_AES_CBC
+# define USE_AES_GCM
-#ifdef USE_LIBSODIUM
-//#define USE_CHACHA20_POLY1305
-#endif
+# ifdef USE_LIBSODIUM
+/* #define USE_CHACHA20_POLY1305 */
+# endif
/** @security 3DES is still relatively secure, however is deprecated for TLS */
-#define USE_3DES
+# define USE_3DES
/******************************************************************************/
/**
- Digest algorithms.
+ Digest algorithms.
- @note SHA256 and above are used with TLS 1.2, and also used for
- certificate signatures on some certificates regardless of TLS version.
+ @note SHA256 and above are used with TLS 1.2, and also used for
+ certificate signatures on some certificates regardless of TLS version.
- @security MD5 is deprecated, but still required in combination with SHA-1
- for TLS handshakes before TLS 1.2, meaning that the strength is at least
- that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable
- MD5 only for this purpose. The only other usage of MD5 by TLS is for
- certificate signatures and MD5 based cipher suites. Both of which are
- disabled at compile time by default.
+ @security MD5 is deprecated, but still required in combination with SHA-1
+ for TLS handshakes before TLS 1.2, meaning that the strength is at least
+ that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable
+ MD5 only for this purpose. The only other usage of MD5 by TLS is for
+ certificate signatures and MD5 based cipher suites. Both of which are
+ disabled at compile time by default.
- @security SHA1 will be deprecated in the future, but is still required in
- combination with MD5 for versions prior to TLS 1.2. In addition, SHA1
- certificates are still commonly used, so SHA1 support may be needed
- to validate older certificates. It is possible to completely disable
- SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting
- only with newer certificates.
-*/
-//#define USE_SHA224 /**< @note Used only for cert signature */
-#define USE_SHA256/**< @note Required for TLS 1.2 and above */
-#define USE_HMAC_SHA256
-#define USE_SHA384/**< @pre USE_SHA512 */
-#define USE_HMAC_SHA384
-#define USE_SHA512
+ @security SHA1 will be deprecated in the future, but is still required in
+ combination with MD5 for versions prior to TLS 1.2. In addition, SHA1
+ certificates are still commonly used, so SHA1 support may be needed
+ to validate older certificates. It is possible to completely disable
+ SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting
+ only with newer certificates.
+ */
+/* #define USE_SHA224 *//**< @note Used only for cert signature */
+# define USE_SHA256/**< @note Required for TLS 1.2 and above */
+# define USE_HMAC_SHA256
+# define USE_SHA384/**< @pre USE_SHA512 */
+# define USE_HMAC_SHA384
+# define USE_SHA512
/**
- @security SHA-1 based hashes are deprecated but enabled by default
- @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below.
-*/
-#define USE_SHA1
-#define USE_HMAC_SHA1
+ @security SHA-1 based hashes are deprecated but enabled by default
+ @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below.
+ */
+# define USE_SHA1
+# define USE_HMAC_SHA1
/**
- @security MD5 is considered insecure, but required by TLS < 1.2
- @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below.
-*/
-#define USE_MD5
-#define USE_MD5SHA1/* Required for < TLS 1.2 Handshake */
-#define USE_HMAC_MD5
+ @security MD5 is considered insecure, but required by TLS < 1.2
+ @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below.
+ */
+# define USE_MD5
+# define USE_MD5SHA1/* Required for < TLS 1.2 Handshake */
+# define USE_HMAC_MD5
/**
@security MD2 is considered insecure, but is sometimes used for
- verification of legacy root certificate signatures.
- @note MD2 signature verification also requires
- ENABLE_MD5_SIGNED_CERTS and USE_MD5.
-*/
-//#define USE_MD2
+ verification of legacy root certificate signatures.
+ @note MD2 signature verification also requires
+ ENABLE_MD5_SIGNED_CERTS and USE_MD5.
+ */
+/* #define USE_MD2 */
/* Please enable, unless using no HMAC algorithms. */
-#define USE_HMAC
+# define USE_HMAC
/******************************************************************************/
/**
- X.509 Certificates/PKI
-*/
-#define USE_BASE64_DECODE
-#define USE_X509/**< Enable minimal X.509 support. */
-#define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */
-#define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */
- /**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */
-//#define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
- /**< Support extra distinguished name attributes not mentioned in RFC 5280. */
-//#define USE_EXTRA_DN_ATTRIBUTES
-//#define ENABLE_CA_CERT_HASH /**< Used only for TLS trusted CA ind ext. */
-//#define ENABLE_MD5_SIGNED_CERTS /** @security Accept MD5 signed certs? */
-#define ENABLE_SHA1_SIGNED_CERTS/** @security Accept SHA1 signed certs? */
- /**< @security Allow parsing of locally trusted v1 root certs? */
-//#define ALLOW_VERSION_1_ROOT_CERT_PARSE
-#define USE_CRL/***< @pre USE_FULL_CERT_PARSE */
-#define USE_OCSP/**< @pre USE_SHA1 */
+ X.509 Certificates/PKI
+ */
+# define USE_BASE64_DECODE
+# define USE_X509/**< Enable minimal X.509 support. */
+# define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */
+# define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */
+/**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */
+/* #define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
+/**< Support extra distinguished name attributes not mentioned in RFC 5280. */
+/* #define USE_EXTRA_DN_ATTRIBUTES */
+/* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */
+/* #define ENABLE_MD5_SIGNED_CERTS *//** @security Accept MD5 signed certs? */
+# define ENABLE_SHA1_SIGNED_CERTS/** @security Accept SHA1 signed certs? */
+/**< @security Allow parsing of locally trusted v1 root certs? */
+/* #define ALLOW_VERSION_1_ROOT_CERT_PARSE */
+/**
+ When parsing certificates, always also retain the unparsed DER data.
+ Enabling this has the same effect as setting the
+ CERT_STORE_UNPARSED_BUFFER flag in each psX509ParseCert call.
+ */
+/* #define ALWAYS_KEEP_CERT_DER */
+/**
+ Always attempt to match expectedName with the subject CN, even if
+ a supported, but non-matching subjectAltName was presented.
+ The default behaviour is to check the CN only when no supported SAN
+ was presented, in accordance with Section 6.4.4 of RFC 6125.
+ */
+/* #define ALWAYS_CHECK_SUBJECT_CN_IN_HOSTNAME_VALIDATION */
+# define USE_CRL/***< @pre USE_FULL_CERT_PARSE */
+# ifdef USE_CRL
+/**
+ Allow CRL authentication to succeed even when signer CA's cert does not
+ have the keyUsage extension and thus no cRLSign bit.
+ Note that RFC 5280 requires CRL issuer certs to have the keyUsage extension
+ and the cRLSign bit.
+ */
+/* #define ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE */
+# endif
+# define USE_OCSP/**< @pre USE_SHA1 */
/******************************************************************************/
/**
- Various PKCS standards support
-*/
-#define USE_PRIVATE_KEY_PARSING
-#define USE_PKCS5/**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */
+ Various PKCS standards support
+ */
+# define USE_PRIVATE_KEY_PARSING
+# define USE_PKCS5/**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */
/**< Enable PBKDF1 in priv key PEM encryption. @pre USE_PKCS5 and @pre USE_MD5. @security Not recommended. */
-#define USE_PBKDF1
-#define USE_PKCS8/* Alternative private key storage format */
-#define USE_PKCS12/**< @pre USE_PKCS8 */
-#define USE_PKCS1_OAEP/* OAEP padding algorithm */
-#define USE_PKCS1_PSS/* PSS padding algorithm */
+# define USE_PBKDF1
+# define USE_PKCS8/* Alternative private key storage format */
+# define USE_PKCS12/**< @pre USE_PKCS8 */
+# define USE_PKCS1_OAEP/* OAEP padding algorithm */
+# define USE_PKCS1_PSS/* PSS padding algorithm */
-#endif /* _h_PS_CRYPTOCONFIG */
+#endif /* _h_PS_CRYPTOCONFIG */
/******************************************************************************/
diff --git a/configs/noecc/matrixsslConfig.h b/configs/noecc/matrixsslConfig.h
index 36ec978..4d80c58 100644
--- a/configs/noecc/matrixsslConfig.h
+++ b/configs/noecc/matrixsslConfig.h
@@ -1,160 +1,160 @@
/**
- * @file matrixsslConfig.h
- * @version $Format:%h%d$
+ * @file matrixsslConfig.h
+ * @version $Format:%h%d$
*
- * Configuration settings for building the MatrixSSL library.
- * This configuration is intended to be used in FIPS Mode of operation.
- * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and
- * to enable the most commonly used cipher suites.
+ * Configuration settings for building the MatrixSSL library.
+ * This configuration is intended to be used in FIPS Mode of operation.
+ * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and
+ * to enable the most commonly used cipher suites.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_MATRIXSSLCONFIG
-#define _h_MATRIXSSLCONFIG
+# define _h_MATRIXSSLCONFIG
-#ifdef __cplusplus
+# ifdef __cplusplus
extern "C" {
-#endif
+# endif
/**
- NIST SP 800-52 Rev 1 Conformance.
- Guidelines for the Selection, Configuration, and Use of Transport Layer
- Security (TLS) Implementations
- The key words "shall", "shall not", "should", "should not" and "may"
- are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as
- "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility
- is not relevant.
- @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf
-*/
+ NIST SP 800-52 Rev 1 Conformance.
+ Guidelines for the Selection, Configuration, and Use of Transport Layer
+ Security (TLS) Implementations
+ The key words "shall", "shall not", "should", "should not" and "may"
+ are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as
+ "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility
+ is not relevant.
+ @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf
+ */
/******************************************************************************/
/**
- Show which SSL messages are created and parsed
-*/
-//#define USE_SSL_HANDSHAKE_MSG_TRACE
+ Show which SSL messages are created and parsed
+ */
+/* #define USE_SSL_HANDSHAKE_MSG_TRACE */
/**
- Informational trace that could help pinpoint problems with SSL connections
-*/
-//#define USE_SSL_INFORMATIONAL_TRACE
-//#define USE_DTLS_DEBUG_TRACE
+ Informational trace that could help pinpoint problems with SSL connections
+ */
+/* #define USE_SSL_INFORMATIONAL_TRACE */
+/* #define USE_DTLS_DEBUG_TRACE */
/******************************************************************************/
/**
- Recommended cipher suites.
- Define the following to enable various cipher suites
- At least one of these must be defined. If multiple are defined,
- the handshake negotiation will determine which is best for the connection.
- @note Ephemeral ciphersuites offer perfect forward security (PFS)
- at the cost of a slower TLS handshake.
-*/
+ Recommended cipher suites.
+ Define the following to enable various cipher suites
+ At least one of these must be defined. If multiple are defined,
+ the handshake negotiation will determine which is best for the connection.
+ @note Ephemeral ciphersuites offer perfect forward security (PFS)
+ at the cost of a slower TLS handshake.
+ */
/** Ephemeral ECC DH keys, ECC DSA certificates */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA /**< @security NIST_MAY */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */
/* TLS 1.2 ciphers */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 /**< @security NIST_MAY */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */
/** Ephemeral ECC DH keys, RSA certificates */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */
/* TLS 1.2 ciphers */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 /**< @security NIST_MAY */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */
/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */
-#define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
-#define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+# define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+# define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
/* TLS 1.2 ciphers */
-#define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
-#define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+# define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+# define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
/** Non-Ephemeral RSA keys/certificates */
-#define USE_TLS_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHALL */
-#define USE_TLS_RSA_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD */
+# define USE_TLS_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHALL */
+# define USE_TLS_RSA_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD */
/* TLS 1.2 ciphers */
-#define USE_TLS_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */
-#define USE_TLS_RSA_WITH_AES_256_CBC_SHA256/**< @security NIST_MAY */
-#define USE_TLS_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHALL */
-#define USE_TLS_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
+# define USE_TLS_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */
+# define USE_TLS_RSA_WITH_AES_256_CBC_SHA256/**< @security NIST_MAY */
+# define USE_TLS_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHALL */
+# define USE_TLS_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
/******************************************************************************/
/**
- These cipher suites are secure, but not widely deployed.
-*/
+ These cipher suites are secure, but not widely deployed.
+ */
/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */
-//#define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+/* #define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
/** Ephemeral Diffie-Hellman ciphersuites, with PSK authentication */
-#define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD_NOT */
-#define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD_NOT */
/** Ephemeral ECC DH keys, RSA certificates */
-//#define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA /**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHOULD */
/** Pre-Shared Key Ciphers.
- NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary
+ NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary
See NIST SP 800-52 Rev 1 Appendix C */
-#define USE_TLS_PSK_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD_NOT */
-#define USE_TLS_PSK_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD_NOT */
/* TLS 1.2 ciphers */
-#define USE_TLS_PSK_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD_NOT */
-#define USE_TLS_PSK_WITH_AES_256_CBC_SHA384/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_256_CBC_SHA384/**< @security NIST_SHOULD_NOT */
/** Non-Ephemeral ECC DH keys, ECC DSA certificates */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA /**< @security NIST_MAY */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA /**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */
/* TLS 1.2 ciphers */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 /**< @security NIST_MAY */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 /**< @security NIST_MAY */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 /**< @security NIST_MAY */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 /**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_MAY */
/** Non-Ephemeral ECC DH keys, RSA certificates */
-//#define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
-//#define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+/* #define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */
+/* #define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */
/* TLS 1.2 ciphers */
-//#define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
-//#define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
-//#define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
-//#define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+/* #define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */
+/* #define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */
+/* #define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */
+/* #define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */
/** Non-Ephemeral RSA keys/certificates */
-//#define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA /**< @security NIST_SHALL */
+/* #define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHALL */
/** @note Some of (non-mandatory) cipher suites mentioned in NIST SP 800-52
Rev 1 are not supported by the MatrixSSL / MatrixDTLS.
@@ -166,171 +166,187 @@ extern "C" {
/******************************************************************************/
/**
- Ephemeral key cache support.
- If not using cache, new key exchange keys are created for each TLS session.
- If using cache, keys are generated initially, and re-used in each
- subsequent TLS connection within a given time frame and usage count.
- @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE
+ Ephemeral key cache support.
+ If not using cache, new key exchange keys are created for each TLS session.
+ If using cache, keys are generated initially, and re-used in each
+ subsequent TLS connection within a given time frame and usage count.
+ @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE
- @security Do not cache Ephemeral ECC keys as it is against some standards,
- including NIST SP 800-56A, when in FIPS 140-2 mode of operation.
-*/
-//#define NO_ECC_EPHEMERAL_CACHE /**< @security NIST_SHALL */
-
-/******************************************************************************/
-/**
- Configure Support for TLS protocol versions.
- Define one of:
- USE_TLS_1_2_AND_ABOVE
- USE_TLS_1_1_AND_ABOVE
- USE_TLS_1_0_AND_ABOVE
- @note There is no option for enabling SSL3.0 at this level
-*/
-#define USE_TLS_1_1_AND_ABOVE/**< @security default 1_1_AND_ABOVE */
-//#define USE_TLS_1_2_AND_ABOVE /**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
-//#define USE_TLS_1_0_AND_ABOVE /**< @security no longer recommended. */
-
-/******************************************************************************/
-/**
- Datagram TLS support.
- Enables DTLS in addition to TLS.
- @pre TLS_1_1
-*/
-#define USE_DTLS
-
-/******************************************************************************/
-/**
- Compile time support for server or client side SSL
-*/
-#define USE_CLIENT_SIDE_SSL
-#define USE_SERVER_SIDE_SSL
-
-/******************************************************************************/
-/**
- Client certificate authentication
-*/
-#define USE_CLIENT_AUTH
-
-/**
- Enable if the server should send an empty CertificateRequest message if
- no CA files have been loaded
-*/
-//#define SERVER_CAN_SEND_EMPTY_CERT_REQUEST
-
-/**
- Enabling this define will allow the server to "downgrade" a client auth
- handshake to a standard handshake if the client replies to a
- CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback
- will be called with a NULL cert in this case and the user can determine if
- the handshake should continue in a non-client auth state.
-*/
-//#define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG
-
-/******************************************************************************/
-/**
- Enable the Application Layer Protocol Negotiation extension.
- Servers and Clients will still have to use the required public API to
- set protocols and register application callbacks to negotiate the
- protocol that will be tunneled over TLS.
- @see ALPN section in the developer's guide for information.
+ @security Do not cache Ephemeral ECC keys as it is against some standards,
+ including NIST SP 800-56A, when in FIPS 140-2 mode of operation.
*/
-//#define USE_ALPN
+/* #define NO_ECC_EPHEMERAL_CACHE *//**< @security NIST_SHALL */
/******************************************************************************/
/**
- Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the
- sha1 hash of each CA file to the server for help in server selection.
- This extra level of define is to help isolate the SHA1 requirement
-*/
-//#define USE_TRUSTED_CA_INDICATION /**< @security NIST_SHOULD */
-
-/******************************************************************************/
-/**
- A client side configuration that requires a server to provide an OCSP
- response if the client uses the certitificate status request extension.
- The "must staple" terminology is typically associated with certificates
- at the X.509 layer but it is a good description of what is being required
- of the server at the TLS level.
- @pre USE_OCSP must be enbled at the crypto level and the client application
- must use the OCSPstapling session option at run time for this setting to
- have any effect
-*/
-#ifdef USE_OCSP
-#define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */
-#endif
-
-/******************************************************************************/
-/**
- Rehandshaking support.
-
- Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the
- protocol defined in RFC 5748 which fixed a critical exploit in
- the standard TLS specification.
-
- @security Looking towards TLS 1.3, which removes re-handshaking, this
- feature is disabled by default.
-*/
-//#define USE_REHANDSHAKING
-
-/******************************************************************************/
-/**
- If SERVER you may define the number of sessions to cache and how
- long a session will remain valid in the cache from first access.
- Session caching enables very fast "session resumption handshakes".
-
- SSL_SESSION_TABLE_SIZE minimum value is 1
- SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0
-
- @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0
- however, this will also immediately expire SESSION_TICKETS below.
-*/
-#ifdef USE_SERVER_SIDE_SSL
-#define SSL_SESSION_TABLE_SIZE 32
-#define SSL_SESSION_ENTRY_LIFE (86400*1000)/* one day, in milliseconds */
-#endif
-
-/******************************************************************************/
-/**
- Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE
- define applies to this method as well as the standard method. The
- SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list.
-*/
-#define USE_STATELESS_SESSION_TICKETS
-#define SSL_SESSION_TICKET_LIST_LEN 32
-
-/******************************************************************************/
-/**
- The initial buffer sizes for send and receive buffers in each ssl_t session.
- Buffers are internally grown if more incoming or outgoing data storage is
- needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the
- buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced
- to this size. Most standard SSL handshakes require on the order of 1024 B.
-
- SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE
+ Configure Support for TLS protocol versions.
+ Define one of:
+ USE_TLS_1_2_AND_ABOVE
+ USE_TLS_1_1_AND_ABOVE
+ USE_TLS_1_0_AND_ABOVE
+ @note There is no option for enabling SSL3.0 at this level
*/
-#ifndef USE_DTLS
-#define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */
-#define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */
-#else
+# define USE_TLS_1_1_AND_ABOVE/**< @security default 1_1_AND_ABOVE */
+/* #define USE_TLS_1_2_AND_ABOVE *//**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
+/* #define USE_TLS_1_0_AND_ABOVE *//**< @security no longer recommended. */
+
/******************************************************************************/
/**
- The Path Maximum Transmission Unit is the largest datagram that can be
- sent or recieved. It is beyond the scope of DTLS to negotiate this value
- so make sure both sides have agreed on this value. This is an enforced
- limitation in MatrixDTLS so connections will not succeed if a peer has a
- PTMU set larger than this value.
-*/
-#define DTLS_PMTU 1500 /* 1500 Default/Maximum datagram len */
-#define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
-#define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+ Datagram TLS support.
+ Enables DTLS in addition to TLS.
+ @pre TLS_1_1
+ */
+# define USE_DTLS
-//#define DTLS_SEND_RECORDS_INDIVIDUALLY /* Max one record per datagram */
-#endif
+/******************************************************************************/
+/**
+ Compile time support for server or client side SSL
+ */
+# define USE_CLIENT_SIDE_SSL
+# define USE_SERVER_SIDE_SSL
-#ifdef __cplusplus
+/******************************************************************************/
+/**
+ Client certificate authentication
+ */
+# define USE_CLIENT_AUTH
+
+# ifdef USE_CLIENT_AUTH
+/**
+ Enable the handshake_messages signature in the CertificateVerify
+ protocol message to be signed using an external module.
+ */
+/* #define USE_EXT_CERTIFICATE_VERIFY_SIGNING */
+# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING
+/**
+ Compile an example external module that allows the
+ USE_EXT_CERTIFICATE_VERIFY_SIGNING feature to be tested using the example
+ client program and sslTest.
+ */
+/* #define USE_EXT_EXAMPLE_MODULE */
+# endif
+# endif
+
+/**
+ Enable if the server should send an empty CertificateRequest message if
+ no CA files have been loaded
+ */
+/* #define SERVER_CAN_SEND_EMPTY_CERT_REQUEST */
+
+/**
+ Enabling this define will allow the server to "downgrade" a client auth
+ handshake to a standard handshake if the client replies to a
+ CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback
+ will be called with a NULL cert in this case and the user can determine if
+ the handshake should continue in a non-client auth state.
+ */
+/* #define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */
+
+/******************************************************************************/
+/**
+ Enable the Application Layer Protocol Negotiation extension.
+ Servers and Clients will still have to use the required public API to
+ set protocols and register application callbacks to negotiate the
+ protocol that will be tunneled over TLS.
+ @see ALPN section in the developer's guide for information.
+ */
+/* #define USE_ALPN */
+
+/******************************************************************************/
+/**
+ Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the
+ sha1 hash of each CA file to the server for help in server selection.
+ This extra level of define is to help isolate the SHA1 requirement
+ */
+/* #define USE_TRUSTED_CA_INDICATION *//**< @security NIST_SHOULD */
+
+/******************************************************************************/
+/**
+ A client side configuration that requires a server to provide an OCSP
+ response if the client uses the certitificate status request extension.
+ The "must staple" terminology is typically associated with certificates
+ at the X.509 layer but it is a good description of what is being required
+ of the server at the TLS level.
+ @pre USE_OCSP must be enbled at the crypto level and the client application
+ must use the OCSPstapling session option at run time for this setting to
+ have any effect
+ */
+# ifdef USE_OCSP
+# define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */
+# endif
+
+/******************************************************************************/
+/**
+ Rehandshaking support.
+
+ Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the
+ protocol defined in RFC 5748 which fixed a critical exploit in
+ the standard TLS specification.
+
+ @security Looking towards TLS 1.3, which removes re-handshaking, this
+ feature is disabled by default.
+ */
+/* #define USE_REHANDSHAKING */
+
+/******************************************************************************/
+/**
+ If SERVER you may define the number of sessions to cache and how
+ long a session will remain valid in the cache from first access.
+ Session caching enables very fast "session resumption handshakes".
+
+ SSL_SESSION_TABLE_SIZE minimum value is 1
+ SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0
+
+ @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0
+ however, this will also immediately expire SESSION_TICKETS below.
+ */
+# ifdef USE_SERVER_SIDE_SSL
+# define SSL_SESSION_TABLE_SIZE 32
+# define SSL_SESSION_ENTRY_LIFE (86400 * 1000)/* one day, in milliseconds */
+# endif
+
+/******************************************************************************/
+/**
+ Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE
+ define applies to this method as well as the standard method. The
+ SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list.
+ */
+# define USE_STATELESS_SESSION_TICKETS
+# define SSL_SESSION_TICKET_LIST_LEN 32
+
+/******************************************************************************/
+/**
+ The initial buffer sizes for send and receive buffers in each ssl_t session.
+ Buffers are internally grown if more incoming or outgoing data storage is
+ needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the
+ buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced
+ to this size. Most standard SSL handshakes require on the order of 1024 B.
+
+ SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE
+ */
+# ifndef USE_DTLS
+# define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */
+# define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */
+# else
+/******************************************************************************/
+/**
+ The Path Maximum Transmission Unit is the largest datagram that can be
+ sent or recieved. It is beyond the scope of DTLS to negotiate this value
+ so make sure both sides have agreed on this value. This is an enforced
+ limitation in MatrixDTLS so connections will not succeed if a peer has a
+ PTMU set larger than this value.
+ */
+# define DTLS_PMTU 1500 /* 1500 Default/Maximum datagram len */
+# define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+# define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+
+/* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */
+# endif
+
+# ifdef __cplusplus
}
-#endif
+# endif
-#endif /* _h_MATRIXCONFIG */
+#endif /* _h_MATRIXCONFIG */
/******************************************************************************/
diff --git a/configs/psk/coreConfig.h b/configs/psk/coreConfig.h
index 74e6d97..6bb01cd 100644
--- a/configs/psk/coreConfig.h
+++ b/configs/psk/coreConfig.h
@@ -1,83 +1,83 @@
/**
- * @file coreConfig.h
- * @version $Format:%h%d$
+ * @file coreConfig.h
+ * @version $Format:%h%d$
*
- * Configuration settings for Matrix core module.
+ * Configuration settings for Matrix core module.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_CORECONFIG
-#define _h_PS_CORECONFIG
+# define _h_PS_CORECONFIG
/******************************************************************************/
/* Configurable features */
/******************************************************************************/
/**
- Enable various levels of trace.
- When these option is turned off, messages are silently
- discarded and their text does not take space in the binary image.
-*/
-//#define USE_CORE_TRACE
-#ifndef NO_CORE_ERROR
- #define USE_CORE_ERROR
-#endif
-#ifndef NO_CORE_ASSERT
- #define USE_CORE_ASSERT
-#endif
-
-/**
- If enabled, calls to the psError set of APIs will perform a platform
- abort on the exeutable to aid in debugging.
-*/
-#ifdef DEBUG
-//#define HALT_ON_PS_ERROR /* NOT RECOMMENDED FOR PRODUCTION BUILDS */
-#endif
-
-/**
- Include the psCoreOsdepMutex family of APIs
-
- @note If intending to compile crypto-cl, then this flag should
- always be set.
-*/
-#ifndef NO_MULTITHREADING
-//#define USE_MULTITHREADING
-#endif /* NO_MULTITHREADING */
-
-/**
- Include the psNetwork family of APIs
-
- These APIs allow simple high-level socket api.
+ Enable various levels of trace.
+ When these option is turned off, messages are silently
+ discarded and their text does not take space in the binary image.
*/
-#define USE_PS_NETWORKING
+/* #define USE_CORE_TRACE */
+# ifndef NO_CORE_ERROR
+# define USE_CORE_ERROR
+# endif
+# ifndef NO_CORE_ASSERT
+# define USE_CORE_ASSERT
+# endif
-#endif /* _h_PS_CORECONFIG */
+/**
+ If enabled, calls to the psError set of APIs will perform a platform
+ abort on the exeutable to aid in debugging.
+ */
+# ifdef DEBUG
+/* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */
+# endif
+
+/**
+ Include the psCoreOsdepMutex family of APIs
+
+ @note If intending to compile crypto-cl, then this flag should
+ always be set.
+*/
+# ifndef NO_MULTITHREADING
+/* #define USE_MULTITHREADING */
+# endif /* NO_MULTITHREADING */
+
+/**
+ Include the psNetwork family of APIs
+
+ These APIs allow simple high-level socket api.
+ */
+# define USE_PS_NETWORKING
+
+#endif /* _h_PS_CORECONFIG */
/******************************************************************************/
diff --git a/configs/psk/cryptoConfig.h b/configs/psk/cryptoConfig.h
index 01ac9ab..65a2689 100644
--- a/configs/psk/cryptoConfig.h
+++ b/configs/psk/cryptoConfig.h
@@ -1,220 +1,242 @@
/**
- * @file cryptoConfig.h
- * @version $Format:%h%d$
+ * @file cryptoConfig.h
+ * @version $Format:%h%d$
*
- * Configuration file for crypto features.
+ * Configuration file for crypto features.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_CRYPTOCONFIG
-#define _h_PS_CRYPTOCONFIG
+# define _h_PS_CRYPTOCONFIG
/******************************************************************************/
/* Configurable features */
/******************************************************************************/
/**
- Define to enable psTrace*Crypto APIs for debugging the crypto module.
-*/
-//#define USE_CRYPTO_TRACE
+ Define to enable psTrace*Crypto APIs for debugging the crypto module.
+ */
+/* #define USE_CRYPTO_TRACE */
-#ifdef DEBUG
-//#define CRYPTO_ASSERT /**< Extra sanity asserts */
-#endif
+# ifdef DEBUG
+/* #define CRYPTO_ASSERT *//**< Extra sanity asserts */
+# endif
/******************************************************************************/
/*
- Use built-in cryptographic library delivered with MatrixSSL
-*/
-#define USE_NATIVE_RSA /* Default built-in software support */
+ Use built-in cryptographic library delivered with MatrixSSL
+ */
+# define USE_NATIVE_RSA /* Default built-in software support */
/******************************************************************************/
/**
- Security related settings.
+ Security related settings.
- @security MIN_*_BITS is the minimum supported key sizes in bits, weaker
- keys will be rejected.
-*/
-#define MIN_ECC_BITS 192/**< @security Affects ECC curves below */
+ @security MIN_*_BITS is the minimum supported key sizes in bits, weaker
+ keys will be rejected.
+ */
+# define MIN_ECC_BITS 192/**< @security Affects ECC curves below */
-#define MIN_RSA_BITS 1024
+# define MIN_RSA_BITS 1024
-#define MIN_DH_BITS 1024
+# define MIN_DH_BITS 1024
-//#define USE_BURN_STACK /**< @security Zero sensitive data from the stack. */
+/* #define USE_BURN_STACK *//**< @security Zero sensitive data from the stack. */
/******************************************************************************/
/**
- Public-Key Algorithm Support.
-*/
-//#define USE_RSA
-//#define USE_ECC
-//#define USE_DH
+ Public-Key Algorithm Support.
+ */
+/* #define USE_RSA */
+/* #define USE_ECC */
+/* #define USE_DH */
/**< @note Enable verification of DSA signatures in certificate validation.
Works only when using the CL/SL library. @pre USE_CERT_PARSE. */
-//#define USE_DSA_VERIFY
+/* #define USE_DSA_VERIFY */
/******************************************************************************/
/**
Build the PKCS and ASN1 extra CL sublibraries.
- These are needed by the CL_PKCS API.
-*/
+ These are needed by the CL_PKCS API.
+ */
/******************************************************************************/
/**
- Define to enable the individual NIST Prime curves.
- @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
-*/
-#ifdef USE_ECC
-//#define USE_SECP192R1 /**< @security FIPS allowed for sig ver only. */
-//#define USE_SECP224R1
-//#define USE_SECP256R1 /**< @security NIST_SHALL */
-//#define USE_SECP384R1 /**< @security NIST_SHALL */
-//#define USE_SECP521R1
-#endif
+ Define to enable the individual NIST Prime curves.
+ @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
+ */
+# ifdef USE_ECC
+/* #define USE_SECP192R1 *//**< @security FIPS allowed for sig ver only. */
+/* #define USE_SECP224R1 */
+/* #define USE_SECP256R1 *//**< @security NIST_SHALL */
+/* #define USE_SECP384R1 *//**< @security NIST_SHALL */
+/* #define USE_SECP521R1 */
+# endif
/**
- Define to enable the individual Brainpool curves.
- @see https://tools.ietf.org/html/rfc5639
- @security WARNING: Public points on Brainpool curves are not validated
-*/
-#ifdef USE_ECC
-//#define USE_BRAIN224R1
-//#define USE_BRAIN256R1
-//#define USE_BRAIN384R1
-//#define USE_BRAIN512R1
-#endif
+ Define to enable the individual Brainpool curves.
+ @see https://tools.ietf.org/html/rfc5639
+ @security WARNING: Public points on Brainpool curves are not validated
+ */
+# ifdef USE_ECC
+/* #define USE_BRAIN224R1 */
+/* #define USE_BRAIN256R1 */
+/* #define USE_BRAIN384R1 */
+/* #define USE_BRAIN512R1 */
+# endif
/******************************************************************************/
/**
- Symmetric and AEAD ciphers.
- @security Deprecated ciphers must be enabled in cryptolib.h
-*/
-//#define USE_AES /* Enable/Disable AES */
-#define USE_AES_CBC
-//#define USE_AES_GCM
+ Symmetric and AEAD ciphers.
+ @security Deprecated ciphers must be enabled in cryptolib.h
+ */
+/* #define USE_AES *//* Enable/Disable AES */
+# define USE_AES_CBC
+/* #define USE_AES_GCM */
-#ifdef USE_LIBSODIUM
-//#define USE_CHACHA20_POLY1305
-#endif
+# ifdef USE_LIBSODIUM
+/* #define USE_CHACHA20_POLY1305 */
+# endif
/** @security 3DES is still relatively secure, however is deprecated for TLS */
-//#define USE_3DES
+/* #define USE_3DES */
/******************************************************************************/
/**
- Digest algorithms.
+ Digest algorithms.
- @note SHA256 and above are used with TLS 1.2, and also used for
- certificate signatures on some certificates regardless of TLS version.
+ @note SHA256 and above are used with TLS 1.2, and also used for
+ certificate signatures on some certificates regardless of TLS version.
- @security MD5 is deprecated, but still required in combination with SHA-1
- for TLS handshakes before TLS 1.2, meaning that the strength is at least
- that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable
- MD5 only for this purpose. The only other usage of MD5 by TLS is for
- certificate signatures and MD5 based cipher suites. Both of which are
- disabled at compile time by default.
+ @security MD5 is deprecated, but still required in combination with SHA-1
+ for TLS handshakes before TLS 1.2, meaning that the strength is at least
+ that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable
+ MD5 only for this purpose. The only other usage of MD5 by TLS is for
+ certificate signatures and MD5 based cipher suites. Both of which are
+ disabled at compile time by default.
- @security SHA1 will be deprecated in the future, but is still required in
- combination with MD5 for versions prior to TLS 1.2. In addition, SHA1
- certificates are still commonly used, so SHA1 support may be needed
- to validate older certificates. It is possible to completely disable
- SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting
- only with newer certificates.
-*/
-//#define USE_SHA224 /**< @note Used only for cert signature */
-#define USE_SHA256/**< @note Required for TLS 1.2 and above */
-#define USE_HMAC_SHA256
-//#define USE_SHA384 /**< @pre USE_SHA512 */
-//#define USE_HMAC_SHA384
-//#define USE_SHA512
+ @security SHA1 will be deprecated in the future, but is still required in
+ combination with MD5 for versions prior to TLS 1.2. In addition, SHA1
+ certificates are still commonly used, so SHA1 support may be needed
+ to validate older certificates. It is possible to completely disable
+ SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting
+ only with newer certificates.
+ */
+/* #define USE_SHA224 *//**< @note Used only for cert signature */
+# define USE_SHA256/**< @note Required for TLS 1.2 and above */
+# define USE_HMAC_SHA256
+/* #define USE_SHA384 *//**< @pre USE_SHA512 */
+/* #define USE_HMAC_SHA384 */
+/* #define USE_SHA512 */
/**
- @security SHA-1 based hashes are deprecated but enabled by default
- @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below.
-*/
-//#define USE_SHA1
-//#define USE_HMAC_SHA1
+ @security SHA-1 based hashes are deprecated but enabled by default
+ @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below.
+ */
+/* #define USE_SHA1 */
+/* #define USE_HMAC_SHA1 */
/**
- @security MD5 is considered insecure, but required by TLS < 1.2
- @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below.
-*/
-//#define USE_MD5
-//#define USE_MD5SHA1 /* Required for < TLS 1.2 Handshake */
-//#define USE_HMAC_MD5
+ @security MD5 is considered insecure, but required by TLS < 1.2
+ @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below.
+ */
+/* #define USE_MD5 */
+/* #define USE_MD5SHA1 *//* Required for < TLS 1.2 Handshake */
+/* #define USE_HMAC_MD5 */
/**
@security MD2 is considered insecure, but is sometimes used for
- verification of legacy root certificate signatures.
- @note MD2 signature verification also requires
- ENABLE_MD5_SIGNED_CERTS and USE_MD5.
-*/
-//#define USE_MD2
+ verification of legacy root certificate signatures.
+ @note MD2 signature verification also requires
+ ENABLE_MD5_SIGNED_CERTS and USE_MD5.
+ */
+/* #define USE_MD2 */
/* Please enable, unless using no HMAC algorithms. */
-#define USE_HMAC
+# define USE_HMAC
/******************************************************************************/
/**
- X.509 Certificates/PKI
-*/
-//#define USE_BASE64_DECODE
-//#define USE_X509 /**< Enable minimal X.509 support. */
-//#define USE_CERT_PARSE /**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */
-//#define USE_FULL_CERT_PARSE /**< @pre USE_CERT_PARSE */
- /**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */
-//#define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
- /**< Support extra distinguished name attributes not mentioned in RFC 5280. */
-//#define USE_EXTRA_DN_ATTRIBUTES
-//#define ENABLE_CA_CERT_HASH /**< Used only for TLS trusted CA ind ext. */
-//#define ENABLE_MD5_SIGNED_CERTS /** @security Accept MD5 signed certs? */
-//#define ENABLE_SHA1_SIGNED_CERTS /** @security Accept SHA1 signed certs? */
- /**< @security Allow parsing of locally trusted v1 root certs? */
-//#define ALLOW_VERSION_1_ROOT_CERT_PARSE
-//#define USE_CRL /***< @pre USE_FULL_CERT_PARSE */
-//#define USE_OCSP /**< @pre USE_SHA1 */
+ X.509 Certificates/PKI
+ */
+/* #define USE_BASE64_DECODE */
+/* #define USE_X509 *//**< Enable minimal X.509 support. */
+/* #define USE_CERT_PARSE *//**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */
+/* #define USE_FULL_CERT_PARSE *//**< @pre USE_CERT_PARSE */
+/**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */
+/* #define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
+/**< Support extra distinguished name attributes not mentioned in RFC 5280. */
+/* #define USE_EXTRA_DN_ATTRIBUTES */
+/* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */
+/* #define ENABLE_MD5_SIGNED_CERTS *//** @security Accept MD5 signed certs? */
+/* #define ENABLE_SHA1_SIGNED_CERTS *//** @security Accept SHA1 signed certs? */
+/**< @security Allow parsing of locally trusted v1 root certs? */
+/* #define ALLOW_VERSION_1_ROOT_CERT_PARSE */
+/**
+ When parsing certificates, always also retain the unparsed DER data.
+ Enabling this has the same effect as setting the
+ CERT_STORE_UNPARSED_BUFFER flag in each psX509ParseCert call.
+ */
+/* #define ALWAYS_KEEP_CERT_DER */
+/**
+ Always attempt to match expectedName with the subject CN, even if
+ a supported, but non-matching subjectAltName was presented.
+ The default behaviour is to check the CN only when no supported SAN
+ was presented, in accordance with Section 6.4.4 of RFC 6125.
+ */
+/* #define ALWAYS_CHECK_SUBJECT_CN_IN_HOSTNAME_VALIDATION */
+/* #define USE_CRL *//***< @pre USE_FULL_CERT_PARSE */
+# ifdef USE_CRL
+/**
+ Allow CRL authentication to succeed even when signer CA's cert does not
+ have the keyUsage extension and thus no cRLSign bit.
+ Note that RFC 5280 requires CRL issuer certs to have the keyUsage extension
+ and the cRLSign bit.
+ */
+/* #define ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE */
+# endif
+/* #define USE_OCSP *//**< @pre USE_SHA1 */
/******************************************************************************/
/**
- Various PKCS standards support
-*/
-//#define USE_PRIVATE_KEY_PARSING
-//#define USE_PKCS5 /**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */
+ Various PKCS standards support
+ */
+/* #define USE_PRIVATE_KEY_PARSING */
+/* #define USE_PKCS5 *//**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */
/**< Enable PBKDF1 in priv key PEM encryption. @pre USE_PKCS5 and @pre USE_MD5. @security Not recommended. */
-//#define USE_PBKDF1
-//#define USE_PKCS8 /* Alternative private key storage format */
-//#define USE_PKCS12 /**< @pre USE_PKCS8 */
-//#define USE_PKCS1_OAEP /* OAEP padding algorithm */
-//#define USE_PKCS1_PSS /* PSS padding algorithm */
+/* #define USE_PBKDF1 */
+/* #define USE_PKCS8 *//* Alternative private key storage format */
+/* #define USE_PKCS12 *//**< @pre USE_PKCS8 */
+/* #define USE_PKCS1_OAEP *//* OAEP padding algorithm */
+/* #define USE_PKCS1_PSS *//* PSS padding algorithm */
-#endif /* _h_PS_CRYPTOCONFIG */
+#endif /* _h_PS_CRYPTOCONFIG */
/******************************************************************************/
diff --git a/configs/psk/matrixsslConfig.h b/configs/psk/matrixsslConfig.h
index 9894ead..682785a 100644
--- a/configs/psk/matrixsslConfig.h
+++ b/configs/psk/matrixsslConfig.h
@@ -1,160 +1,160 @@
/**
- * @file matrixsslConfig.h
- * @version $Format:%h%d$
+ * @file matrixsslConfig.h
+ * @version $Format:%h%d$
*
- * Configuration settings for building the MatrixSSL library.
- * This configuration is intended to be used in FIPS Mode of operation.
- * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and
- * to enable the most commonly used cipher suites.
+ * Configuration settings for building the MatrixSSL library.
+ * This configuration is intended to be used in FIPS Mode of operation.
+ * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and
+ * to enable the most commonly used cipher suites.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_MATRIXSSLCONFIG
-#define _h_MATRIXSSLCONFIG
+# define _h_MATRIXSSLCONFIG
-#ifdef __cplusplus
+# ifdef __cplusplus
extern "C" {
-#endif
+# endif
/**
- NIST SP 800-52 Rev 1 Conformance.
- Guidelines for the Selection, Configuration, and Use of Transport Layer
- Security (TLS) Implementations
- The key words "shall", "shall not", "should", "should not" and "may"
- are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as
- "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility
- is not relevant.
- @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf
-*/
+ NIST SP 800-52 Rev 1 Conformance.
+ Guidelines for the Selection, Configuration, and Use of Transport Layer
+ Security (TLS) Implementations
+ The key words "shall", "shall not", "should", "should not" and "may"
+ are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as
+ "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility
+ is not relevant.
+ @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf
+ */
/******************************************************************************/
/**
- Show which SSL messages are created and parsed
-*/
-//#define USE_SSL_HANDSHAKE_MSG_TRACE
+ Show which SSL messages are created and parsed
+ */
+/* #define USE_SSL_HANDSHAKE_MSG_TRACE */
/**
- Informational trace that could help pinpoint problems with SSL connections
-*/
-//#define USE_SSL_INFORMATIONAL_TRACE
-//#define USE_DTLS_DEBUG_TRACE
+ Informational trace that could help pinpoint problems with SSL connections
+ */
+/* #define USE_SSL_INFORMATIONAL_TRACE */
+/* #define USE_DTLS_DEBUG_TRACE */
/******************************************************************************/
/**
- Recommended cipher suites.
- Define the following to enable various cipher suites
- At least one of these must be defined. If multiple are defined,
- the handshake negotiation will determine which is best for the connection.
- @note Ephemeral ciphersuites offer perfect forward security (PFS)
- at the cost of a slower TLS handshake.
-*/
+ Recommended cipher suites.
+ Define the following to enable various cipher suites
+ At least one of these must be defined. If multiple are defined,
+ the handshake negotiation will determine which is best for the connection.
+ @note Ephemeral ciphersuites offer perfect forward security (PFS)
+ at the cost of a slower TLS handshake.
+ */
/** Ephemeral ECC DH keys, ECC DSA certificates */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA /**< @security NIST_MAY */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */
/* TLS 1.2 ciphers */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 /**< @security NIST_MAY */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */
/** Ephemeral ECC DH keys, RSA certificates */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */
/* TLS 1.2 ciphers */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 /**< @security NIST_MAY */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */
/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */
-//#define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
-//#define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA */
+/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA */
/* TLS 1.2 ciphers */
-//#define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
-//#define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */
+/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */
/** Non-Ephemeral RSA keys/certificates */
-//#define USE_TLS_RSA_WITH_AES_128_CBC_SHA /**< @security NIST_SHALL */
-//#define USE_TLS_RSA_WITH_AES_256_CBC_SHA /**< @security NIST_SHOULD */
+/* #define USE_TLS_RSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHALL */
+/* #define USE_TLS_RSA_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD */
/* TLS 1.2 ciphers */
-//#define USE_TLS_RSA_WITH_AES_128_CBC_SHA256 /**< @security NIST_MAY */
-//#define USE_TLS_RSA_WITH_AES_256_CBC_SHA256 /**< @security NIST_MAY */
-//#define USE_TLS_RSA_WITH_AES_128_GCM_SHA256 /**< @security NIST_SHALL */
-//#define USE_TLS_RSA_WITH_AES_256_GCM_SHA384 /**< @security NIST_SHOULD */
+/* #define USE_TLS_RSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_MAY */
+/* #define USE_TLS_RSA_WITH_AES_256_CBC_SHA256 *//**< @security NIST_MAY */
+/* #define USE_TLS_RSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHALL */
+/* #define USE_TLS_RSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */
/******************************************************************************/
/**
- These cipher suites are secure, but not widely deployed.
-*/
+ These cipher suites are secure, but not widely deployed.
+ */
/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */
-//#define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+/* #define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
/** Ephemeral Diffie-Hellman ciphersuites, with PSK authentication */
-//#define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA /**< @security NIST_SHOULD_NOT */
-//#define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA /**< @security NIST_SHOULD_NOT */
+/* #define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD_NOT */
+/* #define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD_NOT */
/** Ephemeral ECC DH keys, RSA certificates */
-//#define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA /**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHOULD */
/** Pre-Shared Key Ciphers.
- NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary
+ NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary
See NIST SP 800-52 Rev 1 Appendix C */
-//#define USE_TLS_PSK_WITH_AES_128_CBC_SHA /**< @security NIST_SHOULD_NOT */
-//#define USE_TLS_PSK_WITH_AES_256_CBC_SHA /**< @security NIST_SHOULD_NOT */
+/* #define USE_TLS_PSK_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD_NOT */
+/* #define USE_TLS_PSK_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD_NOT */
/* TLS 1.2 ciphers */
-#define USE_TLS_PSK_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD_NOT */
-//#define USE_TLS_PSK_WITH_AES_256_CBC_SHA384 /**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD_NOT */
+/* #define USE_TLS_PSK_WITH_AES_256_CBC_SHA384 *//**< @security NIST_SHOULD_NOT */
/** Non-Ephemeral ECC DH keys, ECC DSA certificates */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA /**< @security NIST_MAY */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA /**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */
/* TLS 1.2 ciphers */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 /**< @security NIST_MAY */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 /**< @security NIST_MAY */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 /**< @security NIST_MAY */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 /**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_MAY */
/** Non-Ephemeral ECC DH keys, RSA certificates */
-//#define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
-//#define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+/* #define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */
+/* #define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */
/* TLS 1.2 ciphers */
-//#define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
-//#define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
-//#define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
-//#define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+/* #define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */
+/* #define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */
+/* #define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */
+/* #define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */
/** Non-Ephemeral RSA keys/certificates */
-//#define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA /**< @security NIST_SHALL */
+/* #define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHALL */
/** @note Some of (non-mandatory) cipher suites mentioned in NIST SP 800-52
Rev 1 are not supported by the MatrixSSL / MatrixDTLS.
@@ -166,171 +166,187 @@ extern "C" {
/******************************************************************************/
/**
- Ephemeral key cache support.
- If not using cache, new key exchange keys are created for each TLS session.
- If using cache, keys are generated initially, and re-used in each
- subsequent TLS connection within a given time frame and usage count.
- @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE
+ Ephemeral key cache support.
+ If not using cache, new key exchange keys are created for each TLS session.
+ If using cache, keys are generated initially, and re-used in each
+ subsequent TLS connection within a given time frame and usage count.
+ @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE
- @security Do not cache Ephemeral ECC keys as it is against some standards,
- including NIST SP 800-56A, when in FIPS 140-2 mode of operation.
-*/
-//#define NO_ECC_EPHEMERAL_CACHE /**< @security NIST_SHALL */
-
-/******************************************************************************/
-/**
- Configure Support for TLS protocol versions.
- Define one of:
- USE_TLS_1_2_AND_ABOVE
- USE_TLS_1_1_AND_ABOVE
- USE_TLS_1_0_AND_ABOVE
- @note There is no option for enabling SSL3.0 at this level
-*/
-//#define USE_TLS_1_1_AND_ABOVE /**< @security default 1_1_AND_ABOVE */
-#define USE_TLS_1_2_AND_ABOVE/**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
-//#define USE_TLS_1_0_AND_ABOVE /**< @security no longer recommended. */
-
-/******************************************************************************/
-/**
- Datagram TLS support.
- Enables DTLS in addition to TLS.
- @pre TLS_1_1
-*/
-//#define USE_DTLS
-
-/******************************************************************************/
-/**
- Compile time support for server or client side SSL
-*/
-#define USE_CLIENT_SIDE_SSL
-#define USE_SERVER_SIDE_SSL
-
-/******************************************************************************/
-/**
- Client certificate authentication
-*/
-//#define USE_CLIENT_AUTH
-
-/**
- Enable if the server should send an empty CertificateRequest message if
- no CA files have been loaded
-*/
-//#define SERVER_CAN_SEND_EMPTY_CERT_REQUEST
-
-/**
- Enabling this define will allow the server to "downgrade" a client auth
- handshake to a standard handshake if the client replies to a
- CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback
- will be called with a NULL cert in this case and the user can determine if
- the handshake should continue in a non-client auth state.
-*/
-//#define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG
-
-/******************************************************************************/
-/**
- Enable the Application Layer Protocol Negotiation extension.
- Servers and Clients will still have to use the required public API to
- set protocols and register application callbacks to negotiate the
- protocol that will be tunneled over TLS.
- @see ALPN section in the developer's guide for information.
+ @security Do not cache Ephemeral ECC keys as it is against some standards,
+ including NIST SP 800-56A, when in FIPS 140-2 mode of operation.
*/
-//#define USE_ALPN
+/* #define NO_ECC_EPHEMERAL_CACHE *//**< @security NIST_SHALL */
/******************************************************************************/
/**
- Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the
- sha1 hash of each CA file to the server for help in server selection.
- This extra level of define is to help isolate the SHA1 requirement
-*/
-//#define USE_TRUSTED_CA_INDICATION /**< @security NIST_SHOULD */
-
-/******************************************************************************/
-/**
- A client side configuration that requires a server to provide an OCSP
- response if the client uses the certitificate status request extension.
- The "must staple" terminology is typically associated with certificates
- at the X.509 layer but it is a good description of what is being required
- of the server at the TLS level.
- @pre USE_OCSP must be enbled at the crypto level and the client application
- must use the OCSPstapling session option at run time for this setting to
- have any effect
-*/
-#ifdef USE_OCSP
-#define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */
-#endif
-
-/******************************************************************************/
-/**
- Rehandshaking support.
-
- Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the
- protocol defined in RFC 5748 which fixed a critical exploit in
- the standard TLS specification.
-
- @security Looking towards TLS 1.3, which removes re-handshaking, this
- feature is disabled by default.
-*/
-//#define USE_REHANDSHAKING
-
-/******************************************************************************/
-/**
- If SERVER you may define the number of sessions to cache and how
- long a session will remain valid in the cache from first access.
- Session caching enables very fast "session resumption handshakes".
-
- SSL_SESSION_TABLE_SIZE minimum value is 1
- SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0
-
- @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0
- however, this will also immediately expire SESSION_TICKETS below.
-*/
-#ifdef USE_SERVER_SIDE_SSL
-#define SSL_SESSION_TABLE_SIZE 32
-#define SSL_SESSION_ENTRY_LIFE (86400*1000)/* one day, in milliseconds */
-#endif
-
-/******************************************************************************/
-/**
- Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE
- define applies to this method as well as the standard method. The
- SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list.
-*/
-//#define USE_STATELESS_SESSION_TICKETS
-#define SSL_SESSION_TICKET_LIST_LEN 32
-
-/******************************************************************************/
-/**
- The initial buffer sizes for send and receive buffers in each ssl_t session.
- Buffers are internally grown if more incoming or outgoing data storage is
- needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the
- buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced
- to this size. Most standard SSL handshakes require on the order of 1024 B.
-
- SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE
+ Configure Support for TLS protocol versions.
+ Define one of:
+ USE_TLS_1_2_AND_ABOVE
+ USE_TLS_1_1_AND_ABOVE
+ USE_TLS_1_0_AND_ABOVE
+ @note There is no option for enabling SSL3.0 at this level
*/
-#ifndef USE_DTLS
-#define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */
-#define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */
-#else
+/* #define USE_TLS_1_1_AND_ABOVE *//**< @security default 1_1_AND_ABOVE */
+# define USE_TLS_1_2_AND_ABOVE/**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
+/* #define USE_TLS_1_0_AND_ABOVE *//**< @security no longer recommended. */
+
/******************************************************************************/
/**
- The Path Maximum Transmission Unit is the largest datagram that can be
- sent or recieved. It is beyond the scope of DTLS to negotiate this value
- so make sure both sides have agreed on this value. This is an enforced
- limitation in MatrixDTLS so connections will not succeed if a peer has a
- PTMU set larger than this value.
-*/
-#define DTLS_PMTU 1500 /* 1500 Default/Maximum datagram len */
-#define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
-#define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+ Datagram TLS support.
+ Enables DTLS in addition to TLS.
+ @pre TLS_1_1
+ */
+/* #define USE_DTLS */
-//#define DTLS_SEND_RECORDS_INDIVIDUALLY /* Max one record per datagram */
-#endif
+/******************************************************************************/
+/**
+ Compile time support for server or client side SSL
+ */
+# define USE_CLIENT_SIDE_SSL
+# define USE_SERVER_SIDE_SSL
-#ifdef __cplusplus
+/******************************************************************************/
+/**
+ Client certificate authentication
+ */
+/* #define USE_CLIENT_AUTH */
+
+# ifdef USE_CLIENT_AUTH
+/**
+ Enable the handshake_messages signature in the CertificateVerify
+ protocol message to be signed using an external module.
+ */
+/* #define USE_EXT_CERTIFICATE_VERIFY_SIGNING */
+# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING
+/**
+ Compile an example external module that allows the
+ USE_EXT_CERTIFICATE_VERIFY_SIGNING feature to be tested using the example
+ client program and sslTest.
+ */
+/* #define USE_EXT_EXAMPLE_MODULE */
+# endif
+# endif
+
+/**
+ Enable if the server should send an empty CertificateRequest message if
+ no CA files have been loaded
+ */
+/* #define SERVER_CAN_SEND_EMPTY_CERT_REQUEST */
+
+/**
+ Enabling this define will allow the server to "downgrade" a client auth
+ handshake to a standard handshake if the client replies to a
+ CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback
+ will be called with a NULL cert in this case and the user can determine if
+ the handshake should continue in a non-client auth state.
+ */
+/* #define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */
+
+/******************************************************************************/
+/**
+ Enable the Application Layer Protocol Negotiation extension.
+ Servers and Clients will still have to use the required public API to
+ set protocols and register application callbacks to negotiate the
+ protocol that will be tunneled over TLS.
+ @see ALPN section in the developer's guide for information.
+ */
+/* #define USE_ALPN */
+
+/******************************************************************************/
+/**
+ Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the
+ sha1 hash of each CA file to the server for help in server selection.
+ This extra level of define is to help isolate the SHA1 requirement
+ */
+/* #define USE_TRUSTED_CA_INDICATION *//**< @security NIST_SHOULD */
+
+/******************************************************************************/
+/**
+ A client side configuration that requires a server to provide an OCSP
+ response if the client uses the certitificate status request extension.
+ The "must staple" terminology is typically associated with certificates
+ at the X.509 layer but it is a good description of what is being required
+ of the server at the TLS level.
+ @pre USE_OCSP must be enbled at the crypto level and the client application
+ must use the OCSPstapling session option at run time for this setting to
+ have any effect
+ */
+# ifdef USE_OCSP
+# define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */
+# endif
+
+/******************************************************************************/
+/**
+ Rehandshaking support.
+
+ Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the
+ protocol defined in RFC 5748 which fixed a critical exploit in
+ the standard TLS specification.
+
+ @security Looking towards TLS 1.3, which removes re-handshaking, this
+ feature is disabled by default.
+ */
+/* #define USE_REHANDSHAKING */
+
+/******************************************************************************/
+/**
+ If SERVER you may define the number of sessions to cache and how
+ long a session will remain valid in the cache from first access.
+ Session caching enables very fast "session resumption handshakes".
+
+ SSL_SESSION_TABLE_SIZE minimum value is 1
+ SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0
+
+ @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0
+ however, this will also immediately expire SESSION_TICKETS below.
+ */
+# ifdef USE_SERVER_SIDE_SSL
+# define SSL_SESSION_TABLE_SIZE 32
+# define SSL_SESSION_ENTRY_LIFE (86400 * 1000)/* one day, in milliseconds */
+# endif
+
+/******************************************************************************/
+/**
+ Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE
+ define applies to this method as well as the standard method. The
+ SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list.
+ */
+/* #define USE_STATELESS_SESSION_TICKETS */
+# define SSL_SESSION_TICKET_LIST_LEN 32
+
+/******************************************************************************/
+/**
+ The initial buffer sizes for send and receive buffers in each ssl_t session.
+ Buffers are internally grown if more incoming or outgoing data storage is
+ needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the
+ buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced
+ to this size. Most standard SSL handshakes require on the order of 1024 B.
+
+ SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE
+ */
+# ifndef USE_DTLS
+# define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */
+# define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */
+# else
+/******************************************************************************/
+/**
+ The Path Maximum Transmission Unit is the largest datagram that can be
+ sent or recieved. It is beyond the scope of DTLS to negotiate this value
+ so make sure both sides have agreed on this value. This is an enforced
+ limitation in MatrixDTLS so connections will not succeed if a peer has a
+ PTMU set larger than this value.
+ */
+# define DTLS_PMTU 1500 /* 1500 Default/Maximum datagram len */
+# define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+# define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+
+/* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */
+# endif
+
+# ifdef __cplusplus
}
-#endif
+# endif
-#endif /* _h_MATRIXCONFIG */
+#endif /* _h_MATRIXCONFIG */
/******************************************************************************/
diff --git a/configs/rsaonly/coreConfig.h b/configs/rsaonly/coreConfig.h
index 1dc1ecf..81fa819 100644
--- a/configs/rsaonly/coreConfig.h
+++ b/configs/rsaonly/coreConfig.h
@@ -1,83 +1,83 @@
/**
- * @file coreConfig.h
- * @version $Format:%h%d$
+ * @file coreConfig.h
+ * @version $Format:%h%d$
*
- * Configuration settings for Matrix core module.
+ * Configuration settings for Matrix core module.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_CORECONFIG
-#define _h_PS_CORECONFIG
+# define _h_PS_CORECONFIG
/******************************************************************************/
/* Configurable features */
/******************************************************************************/
/**
- Enable various levels of trace.
- When these option is turned off, messages are silently
- discarded and their text does not take space in the binary image.
-*/
-//#define USE_CORE_TRACE
-#ifndef NO_CORE_ERROR
- #define USE_CORE_ERROR
-#endif
-#ifndef NO_CORE_ASSERT
- #define USE_CORE_ASSERT
-#endif
-
-/**
- If enabled, calls to the psError set of APIs will perform a platform
- abort on the exeutable to aid in debugging.
-*/
-#ifdef DEBUG
-//#define HALT_ON_PS_ERROR /* NOT RECOMMENDED FOR PRODUCTION BUILDS */
-#endif
-
-/**
- Include the psCoreOsdepMutex family of APIs
-
- @note If intending to compile crypto-cl, then this flag should
- always be set.
-*/
-#ifndef NO_MULTITHREADING
-#define USE_MULTITHREADING
-#endif /* NO_MULTITHREADING */
-
-/**
- Include the psNetwork family of APIs
-
- These APIs allow simple high-level socket api.
+ Enable various levels of trace.
+ When these option is turned off, messages are silently
+ discarded and their text does not take space in the binary image.
*/
-#define USE_PS_NETWORKING
+/* #define USE_CORE_TRACE */
+# ifndef NO_CORE_ERROR
+# define USE_CORE_ERROR
+# endif
+# ifndef NO_CORE_ASSERT
+# define USE_CORE_ASSERT
+# endif
-#endif /* _h_PS_CORECONFIG */
+/**
+ If enabled, calls to the psError set of APIs will perform a platform
+ abort on the exeutable to aid in debugging.
+ */
+# ifdef DEBUG
+/* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */
+# endif
+
+/**
+ Include the psCoreOsdepMutex family of APIs
+
+ @note If intending to compile crypto-cl, then this flag should
+ always be set.
+*/
+# ifndef NO_MULTITHREADING
+# define USE_MULTITHREADING
+# endif /* NO_MULTITHREADING */
+
+/**
+ Include the psNetwork family of APIs
+
+ These APIs allow simple high-level socket api.
+ */
+# define USE_PS_NETWORKING
+
+#endif /* _h_PS_CORECONFIG */
/******************************************************************************/
diff --git a/configs/rsaonly/cryptoConfig.h b/configs/rsaonly/cryptoConfig.h
index 41fbbfb..a9a0e32 100644
--- a/configs/rsaonly/cryptoConfig.h
+++ b/configs/rsaonly/cryptoConfig.h
@@ -1,220 +1,242 @@
/**
- * @file cryptoConfig.h
- * @version $Format:%h%d$
+ * @file cryptoConfig.h
+ * @version $Format:%h%d$
*
- * Configuration file for crypto features.
+ * Configuration file for crypto features.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_CRYPTOCONFIG
-#define _h_PS_CRYPTOCONFIG
+# define _h_PS_CRYPTOCONFIG
/******************************************************************************/
/* Configurable features */
/******************************************************************************/
/**
- Define to enable psTrace*Crypto APIs for debugging the crypto module.
-*/
-//#define USE_CRYPTO_TRACE
+ Define to enable psTrace*Crypto APIs for debugging the crypto module.
+ */
+/* #define USE_CRYPTO_TRACE */
-#ifdef DEBUG
-//#define CRYPTO_ASSERT /**< Extra sanity asserts */
-#endif
+# ifdef DEBUG
+/* #define CRYPTO_ASSERT *//**< Extra sanity asserts */
+# endif
/******************************************************************************/
/*
- Use built-in cryptographic library delivered with MatrixSSL
-*/
-#define USE_NATIVE_RSA /* Default built-in software support */
+ Use built-in cryptographic library delivered with MatrixSSL
+ */
+# define USE_NATIVE_RSA /* Default built-in software support */
/******************************************************************************/
/**
- Security related settings.
+ Security related settings.
- @security MIN_*_BITS is the minimum supported key sizes in bits, weaker
- keys will be rejected.
-*/
-#define MIN_ECC_BITS 192/**< @security Affects ECC curves below */
+ @security MIN_*_BITS is the minimum supported key sizes in bits, weaker
+ keys will be rejected.
+ */
+# define MIN_ECC_BITS 192/**< @security Affects ECC curves below */
-#define MIN_RSA_BITS 1024
+# define MIN_RSA_BITS 1024
-#define MIN_DH_BITS 1024
+# define MIN_DH_BITS 1024
-#define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */
+# define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */
/******************************************************************************/
/**
- Public-Key Algorithm Support.
-*/
-#define USE_RSA
-//#define USE_ECC
-//#define USE_DH
+ Public-Key Algorithm Support.
+ */
+# define USE_RSA
+/* #define USE_ECC */
+/* #define USE_DH */
/**< @note Enable verification of DSA signatures in certificate validation.
Works only when using the CL/SL library. @pre USE_CERT_PARSE. */
-//#define USE_DSA_VERIFY
+/* #define USE_DSA_VERIFY */
/******************************************************************************/
/**
Build the PKCS and ASN1 extra CL sublibraries.
- These are needed by the CL_PKCS API.
-*/
+ These are needed by the CL_PKCS API.
+ */
/******************************************************************************/
/**
- Define to enable the individual NIST Prime curves.
- @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
-*/
-#ifdef USE_ECC
- #define USE_SECP192R1/**< @security FIPS allowed for sig ver only. */
- #define USE_SECP224R1
- #define USE_SECP256R1/**< @security NIST_SHALL */
- #define USE_SECP384R1/**< @security NIST_SHALL */
- #define USE_SECP521R1
-#endif
+ Define to enable the individual NIST Prime curves.
+ @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
+ */
+# ifdef USE_ECC
+# define USE_SECP192R1/**< @security FIPS allowed for sig ver only. */
+# define USE_SECP224R1
+# define USE_SECP256R1/**< @security NIST_SHALL */
+# define USE_SECP384R1/**< @security NIST_SHALL */
+# define USE_SECP521R1
+# endif
/**
- Define to enable the individual Brainpool curves.
- @see https://tools.ietf.org/html/rfc5639
- @security WARNING: Public points on Brainpool curves are not validated
-*/
-#ifdef USE_ECC
-//#define USE_BRAIN224R1
-//#define USE_BRAIN256R1
-//#define USE_BRAIN384R1
-//#define USE_BRAIN512R1
-#endif
+ Define to enable the individual Brainpool curves.
+ @see https://tools.ietf.org/html/rfc5639
+ @security WARNING: Public points on Brainpool curves are not validated
+ */
+# ifdef USE_ECC
+/* #define USE_BRAIN224R1 */
+/* #define USE_BRAIN256R1 */
+/* #define USE_BRAIN384R1 */
+/* #define USE_BRAIN512R1 */
+# endif
/******************************************************************************/
/**
- Symmetric and AEAD ciphers.
- @security Deprecated ciphers must be enabled in cryptolib.h
-*/
-//#define USE_AES /* Enable/Disable AES */
-#define USE_AES_CBC
-#define USE_AES_GCM
+ Symmetric and AEAD ciphers.
+ @security Deprecated ciphers must be enabled in cryptolib.h
+ */
+/* #define USE_AES *//* Enable/Disable AES */
+# define USE_AES_CBC
+# define USE_AES_GCM
-#ifdef USE_LIBSODIUM
-//#define USE_CHACHA20_POLY1305
-#endif
+# ifdef USE_LIBSODIUM
+/* #define USE_CHACHA20_POLY1305 */
+# endif
/** @security 3DES is still relatively secure, however is deprecated for TLS */
-#define USE_3DES
+# define USE_3DES
/******************************************************************************/
/**
- Digest algorithms.
+ Digest algorithms.
- @note SHA256 and above are used with TLS 1.2, and also used for
- certificate signatures on some certificates regardless of TLS version.
+ @note SHA256 and above are used with TLS 1.2, and also used for
+ certificate signatures on some certificates regardless of TLS version.
- @security MD5 is deprecated, but still required in combination with SHA-1
- for TLS handshakes before TLS 1.2, meaning that the strength is at least
- that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable
- MD5 only for this purpose. The only other usage of MD5 by TLS is for
- certificate signatures and MD5 based cipher suites. Both of which are
- disabled at compile time by default.
+ @security MD5 is deprecated, but still required in combination with SHA-1
+ for TLS handshakes before TLS 1.2, meaning that the strength is at least
+ that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable
+ MD5 only for this purpose. The only other usage of MD5 by TLS is for
+ certificate signatures and MD5 based cipher suites. Both of which are
+ disabled at compile time by default.
- @security SHA1 will be deprecated in the future, but is still required in
- combination with MD5 for versions prior to TLS 1.2. In addition, SHA1
- certificates are still commonly used, so SHA1 support may be needed
- to validate older certificates. It is possible to completely disable
- SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting
- only with newer certificates.
-*/
-//#define USE_SHA224 /**< @note Used only for cert signature */
-#define USE_SHA256/**< @note Required for TLS 1.2 and above */
-#define USE_HMAC_SHA256
-#define USE_SHA384/**< @pre USE_SHA512 */
-#define USE_HMAC_SHA384
-#define USE_SHA512
+ @security SHA1 will be deprecated in the future, but is still required in
+ combination with MD5 for versions prior to TLS 1.2. In addition, SHA1
+ certificates are still commonly used, so SHA1 support may be needed
+ to validate older certificates. It is possible to completely disable
+ SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting
+ only with newer certificates.
+ */
+/* #define USE_SHA224 *//**< @note Used only for cert signature */
+# define USE_SHA256/**< @note Required for TLS 1.2 and above */
+# define USE_HMAC_SHA256
+# define USE_SHA384/**< @pre USE_SHA512 */
+# define USE_HMAC_SHA384
+# define USE_SHA512
/**
- @security SHA-1 based hashes are deprecated but enabled by default
- @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below.
-*/
-#define USE_SHA1
-#define USE_HMAC_SHA1
+ @security SHA-1 based hashes are deprecated but enabled by default
+ @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below.
+ */
+# define USE_SHA1
+# define USE_HMAC_SHA1
/**
- @security MD5 is considered insecure, but required by TLS < 1.2
- @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below.
-*/
-#define USE_MD5
-#define USE_MD5SHA1/* Required for < TLS 1.2 Handshake */
-#define USE_HMAC_MD5
+ @security MD5 is considered insecure, but required by TLS < 1.2
+ @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below.
+ */
+# define USE_MD5
+# define USE_MD5SHA1/* Required for < TLS 1.2 Handshake */
+# define USE_HMAC_MD5
/**
@security MD2 is considered insecure, but is sometimes used for
- verification of legacy root certificate signatures.
- @note MD2 signature verification also requires
- ENABLE_MD5_SIGNED_CERTS and USE_MD5.
-*/
-//#define USE_MD2
+ verification of legacy root certificate signatures.
+ @note MD2 signature verification also requires
+ ENABLE_MD5_SIGNED_CERTS and USE_MD5.
+ */
+/* #define USE_MD2 */
/* Please enable, unless using no HMAC algorithms. */
-#define USE_HMAC
+# define USE_HMAC
/******************************************************************************/
/**
- X.509 Certificates/PKI
-*/
-#define USE_BASE64_DECODE
-#define USE_X509/**< Enable minimal X.509 support. */
-#define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */
-#define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */
- /**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */
-//#define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
- /**< Support extra distinguished name attributes not mentioned in RFC 5280. */
-//#define USE_EXTRA_DN_ATTRIBUTES
-//#define ENABLE_CA_CERT_HASH /**< Used only for TLS trusted CA ind ext. */
-//#define ENABLE_MD5_SIGNED_CERTS /** @security Accept MD5 signed certs? */
-#define ENABLE_SHA1_SIGNED_CERTS/** @security Accept SHA1 signed certs? */
- /**< @security Allow parsing of locally trusted v1 root certs? */
-//#define ALLOW_VERSION_1_ROOT_CERT_PARSE
-#define USE_CRL/***< @pre USE_FULL_CERT_PARSE */
-#define USE_OCSP/**< @pre USE_SHA1 */
+ X.509 Certificates/PKI
+ */
+# define USE_BASE64_DECODE
+# define USE_X509/**< Enable minimal X.509 support. */
+# define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */
+# define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */
+/**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */
+/* #define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
+/**< Support extra distinguished name attributes not mentioned in RFC 5280. */
+/* #define USE_EXTRA_DN_ATTRIBUTES */
+/* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */
+/* #define ENABLE_MD5_SIGNED_CERTS *//** @security Accept MD5 signed certs? */
+# define ENABLE_SHA1_SIGNED_CERTS/** @security Accept SHA1 signed certs? */
+/**< @security Allow parsing of locally trusted v1 root certs? */
+/* #define ALLOW_VERSION_1_ROOT_CERT_PARSE */
+/**
+ When parsing certificates, always also retain the unparsed DER data.
+ Enabling this has the same effect as setting the
+ CERT_STORE_UNPARSED_BUFFER flag in each psX509ParseCert call.
+ */
+/* #define ALWAYS_KEEP_CERT_DER */
+/**
+ Always attempt to match expectedName with the subject CN, even if
+ a supported, but non-matching subjectAltName was presented.
+ The default behaviour is to check the CN only when no supported SAN
+ was presented, in accordance with Section 6.4.4 of RFC 6125.
+ */
+/* #define ALWAYS_CHECK_SUBJECT_CN_IN_HOSTNAME_VALIDATION */
+# define USE_CRL/***< @pre USE_FULL_CERT_PARSE */
+# ifdef USE_CRL
+/**
+ Allow CRL authentication to succeed even when signer CA's cert does not
+ have the keyUsage extension and thus no cRLSign bit.
+ Note that RFC 5280 requires CRL issuer certs to have the keyUsage extension
+ and the cRLSign bit.
+ */
+/* #define ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE */
+# endif
+# define USE_OCSP/**< @pre USE_SHA1 */
/******************************************************************************/
/**
- Various PKCS standards support
-*/
-#define USE_PRIVATE_KEY_PARSING
-#define USE_PKCS5/**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */
+ Various PKCS standards support
+ */
+# define USE_PRIVATE_KEY_PARSING
+# define USE_PKCS5/**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */
/**< Enable PBKDF1 in priv key PEM encryption. @pre USE_PKCS5 and @pre USE_MD5. @security Not recommended. */
-#define USE_PBKDF1
-#define USE_PKCS8/* Alternative private key storage format */
-#define USE_PKCS12/**< @pre USE_PKCS8 */
-#define USE_PKCS1_OAEP/* OAEP padding algorithm */
-#define USE_PKCS1_PSS/* PSS padding algorithm */
+# define USE_PBKDF1
+# define USE_PKCS8/* Alternative private key storage format */
+# define USE_PKCS12/**< @pre USE_PKCS8 */
+# define USE_PKCS1_OAEP/* OAEP padding algorithm */
+# define USE_PKCS1_PSS/* PSS padding algorithm */
-#endif /* _h_PS_CRYPTOCONFIG */
+#endif /* _h_PS_CRYPTOCONFIG */
/******************************************************************************/
diff --git a/configs/rsaonly/matrixsslConfig.h b/configs/rsaonly/matrixsslConfig.h
index e48a431..b724133 100644
--- a/configs/rsaonly/matrixsslConfig.h
+++ b/configs/rsaonly/matrixsslConfig.h
@@ -1,160 +1,160 @@
/**
- * @file matrixsslConfig.h
- * @version $Format:%h%d$
+ * @file matrixsslConfig.h
+ * @version $Format:%h%d$
*
- * Configuration settings for building the MatrixSSL library.
- * This configuration is intended to be used in FIPS Mode of operation.
- * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and
- * to enable the most commonly used cipher suites.
+ * Configuration settings for building the MatrixSSL library.
+ * This configuration is intended to be used in FIPS Mode of operation.
+ * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and
+ * to enable the most commonly used cipher suites.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_MATRIXSSLCONFIG
-#define _h_MATRIXSSLCONFIG
+# define _h_MATRIXSSLCONFIG
-#ifdef __cplusplus
+# ifdef __cplusplus
extern "C" {
-#endif
+# endif
/**
- NIST SP 800-52 Rev 1 Conformance.
- Guidelines for the Selection, Configuration, and Use of Transport Layer
- Security (TLS) Implementations
- The key words "shall", "shall not", "should", "should not" and "may"
- are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as
- "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility
- is not relevant.
- @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf
-*/
+ NIST SP 800-52 Rev 1 Conformance.
+ Guidelines for the Selection, Configuration, and Use of Transport Layer
+ Security (TLS) Implementations
+ The key words "shall", "shall not", "should", "should not" and "may"
+ are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as
+ "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility
+ is not relevant.
+ @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf
+ */
/******************************************************************************/
/**
- Show which SSL messages are created and parsed
-*/
-//#define USE_SSL_HANDSHAKE_MSG_TRACE
+ Show which SSL messages are created and parsed
+ */
+/* #define USE_SSL_HANDSHAKE_MSG_TRACE */
/**
- Informational trace that could help pinpoint problems with SSL connections
-*/
-//#define USE_SSL_INFORMATIONAL_TRACE
-//#define USE_DTLS_DEBUG_TRACE
+ Informational trace that could help pinpoint problems with SSL connections
+ */
+/* #define USE_SSL_INFORMATIONAL_TRACE */
+/* #define USE_DTLS_DEBUG_TRACE */
/******************************************************************************/
/**
- Recommended cipher suites.
- Define the following to enable various cipher suites
- At least one of these must be defined. If multiple are defined,
- the handshake negotiation will determine which is best for the connection.
- @note Ephemeral ciphersuites offer perfect forward security (PFS)
- at the cost of a slower TLS handshake.
-*/
+ Recommended cipher suites.
+ Define the following to enable various cipher suites
+ At least one of these must be defined. If multiple are defined,
+ the handshake negotiation will determine which is best for the connection.
+ @note Ephemeral ciphersuites offer perfect forward security (PFS)
+ at the cost of a slower TLS handshake.
+ */
/** Ephemeral ECC DH keys, ECC DSA certificates */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA /**< @security NIST_MAY */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */
/* TLS 1.2 ciphers */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 /**< @security NIST_MAY */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */
/** Ephemeral ECC DH keys, RSA certificates */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */
/* TLS 1.2 ciphers */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 /**< @security NIST_MAY */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 /**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */
/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */
-//#define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
-//#define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA */
+/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA */
/* TLS 1.2 ciphers */
-//#define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
-//#define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */
+/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */
/** Non-Ephemeral RSA keys/certificates */
-#define USE_TLS_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHALL */
-#define USE_TLS_RSA_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD */
+# define USE_TLS_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHALL */
+# define USE_TLS_RSA_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD */
/* TLS 1.2 ciphers */
-#define USE_TLS_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */
-#define USE_TLS_RSA_WITH_AES_256_CBC_SHA256/**< @security NIST_MAY */
-#define USE_TLS_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHALL */
-#define USE_TLS_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
+# define USE_TLS_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */
+# define USE_TLS_RSA_WITH_AES_256_CBC_SHA256/**< @security NIST_MAY */
+# define USE_TLS_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHALL */
+# define USE_TLS_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
/******************************************************************************/
/**
- These cipher suites are secure, but not widely deployed.
-*/
+ These cipher suites are secure, but not widely deployed.
+ */
/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */
-//#define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+/* #define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
/** Ephemeral Diffie-Hellman ciphersuites, with PSK authentication */
-//#define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA /**< @security NIST_SHOULD_NOT */
-//#define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA /**< @security NIST_SHOULD_NOT */
+/* #define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD_NOT */
+/* #define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD_NOT */
/** Ephemeral ECC DH keys, RSA certificates */
-//#define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA /**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHOULD */
/** Pre-Shared Key Ciphers.
- NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary
+ NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary
See NIST SP 800-52 Rev 1 Appendix C */
-#define USE_TLS_PSK_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD_NOT */
-#define USE_TLS_PSK_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD_NOT */
/* TLS 1.2 ciphers */
-#define USE_TLS_PSK_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD_NOT */
-#define USE_TLS_PSK_WITH_AES_256_CBC_SHA384/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_256_CBC_SHA384/**< @security NIST_SHOULD_NOT */
/** Non-Ephemeral ECC DH keys, ECC DSA certificates */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA /**< @security NIST_MAY */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA /**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA *//**< @security NIST_MAY */
/* TLS 1.2 ciphers */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 /**< @security NIST_MAY */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 /**< @security NIST_MAY */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 /**< @security NIST_MAY */
-//#define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 /**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 *//**< @security NIST_MAY */
+/* #define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 *//**< @security NIST_MAY */
/** Non-Ephemeral ECC DH keys, RSA certificates */
-//#define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
-//#define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+/* #define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */
+/* #define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */
/* TLS 1.2 ciphers */
-//#define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
-//#define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
-//#define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
-//#define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+/* #define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */
+/* #define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */
+/* #define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */
+/* #define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */
/** Non-Ephemeral RSA keys/certificates */
-//#define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA /**< @security NIST_SHALL */
+/* #define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHALL */
/** @note Some of (non-mandatory) cipher suites mentioned in NIST SP 800-52
Rev 1 are not supported by the MatrixSSL / MatrixDTLS.
@@ -166,171 +166,187 @@ extern "C" {
/******************************************************************************/
/**
- Ephemeral key cache support.
- If not using cache, new key exchange keys are created for each TLS session.
- If using cache, keys are generated initially, and re-used in each
- subsequent TLS connection within a given time frame and usage count.
- @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE
+ Ephemeral key cache support.
+ If not using cache, new key exchange keys are created for each TLS session.
+ If using cache, keys are generated initially, and re-used in each
+ subsequent TLS connection within a given time frame and usage count.
+ @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE
- @security Do not cache Ephemeral ECC keys as it is against some standards,
- including NIST SP 800-56A, when in FIPS 140-2 mode of operation.
-*/
-//#define NO_ECC_EPHEMERAL_CACHE /**< @security NIST_SHALL */
-
-/******************************************************************************/
-/**
- Configure Support for TLS protocol versions.
- Define one of:
- USE_TLS_1_2_AND_ABOVE
- USE_TLS_1_1_AND_ABOVE
- USE_TLS_1_0_AND_ABOVE
- @note There is no option for enabling SSL3.0 at this level
-*/
-#define USE_TLS_1_1_AND_ABOVE/**< @security default 1_1_AND_ABOVE */
-//#define USE_TLS_1_2_AND_ABOVE /**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
-//#define USE_TLS_1_0_AND_ABOVE /**< @security no longer recommended. */
-
-/******************************************************************************/
-/**
- Datagram TLS support.
- Enables DTLS in addition to TLS.
- @pre TLS_1_1
-*/
-#define USE_DTLS
-
-/******************************************************************************/
-/**
- Compile time support for server or client side SSL
-*/
-#define USE_CLIENT_SIDE_SSL
-#define USE_SERVER_SIDE_SSL
-
-/******************************************************************************/
-/**
- Client certificate authentication
-*/
-#define USE_CLIENT_AUTH
-
-/**
- Enable if the server should send an empty CertificateRequest message if
- no CA files have been loaded
-*/
-//#define SERVER_CAN_SEND_EMPTY_CERT_REQUEST
-
-/**
- Enabling this define will allow the server to "downgrade" a client auth
- handshake to a standard handshake if the client replies to a
- CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback
- will be called with a NULL cert in this case and the user can determine if
- the handshake should continue in a non-client auth state.
-*/
-//#define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG
-
-/******************************************************************************/
-/**
- Enable the Application Layer Protocol Negotiation extension.
- Servers and Clients will still have to use the required public API to
- set protocols and register application callbacks to negotiate the
- protocol that will be tunneled over TLS.
- @see ALPN section in the developer's guide for information.
+ @security Do not cache Ephemeral ECC keys as it is against some standards,
+ including NIST SP 800-56A, when in FIPS 140-2 mode of operation.
*/
-//#define USE_ALPN
+/* #define NO_ECC_EPHEMERAL_CACHE *//**< @security NIST_SHALL */
/******************************************************************************/
/**
- Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the
- sha1 hash of each CA file to the server for help in server selection.
- This extra level of define is to help isolate the SHA1 requirement
-*/
-//#define USE_TRUSTED_CA_INDICATION /**< @security NIST_SHOULD */
-
-/******************************************************************************/
-/**
- A client side configuration that requires a server to provide an OCSP
- response if the client uses the certitificate status request extension.
- The "must staple" terminology is typically associated with certificates
- at the X.509 layer but it is a good description of what is being required
- of the server at the TLS level.
- @pre USE_OCSP must be enbled at the crypto level and the client application
- must use the OCSPstapling session option at run time for this setting to
- have any effect
-*/
-#ifdef USE_OCSP
-#define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */
-#endif
-
-/******************************************************************************/
-/**
- Rehandshaking support.
-
- Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the
- protocol defined in RFC 5748 which fixed a critical exploit in
- the standard TLS specification.
-
- @security Looking towards TLS 1.3, which removes re-handshaking, this
- feature is disabled by default.
-*/
-//#define USE_REHANDSHAKING
-
-/******************************************************************************/
-/**
- If SERVER you may define the number of sessions to cache and how
- long a session will remain valid in the cache from first access.
- Session caching enables very fast "session resumption handshakes".
-
- SSL_SESSION_TABLE_SIZE minimum value is 1
- SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0
-
- @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0
- however, this will also immediately expire SESSION_TICKETS below.
-*/
-#ifdef USE_SERVER_SIDE_SSL
-#define SSL_SESSION_TABLE_SIZE 32
-#define SSL_SESSION_ENTRY_LIFE (86400*1000)/* one day, in milliseconds */
-#endif
-
-/******************************************************************************/
-/**
- Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE
- define applies to this method as well as the standard method. The
- SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list.
-*/
-#define USE_STATELESS_SESSION_TICKETS
-#define SSL_SESSION_TICKET_LIST_LEN 32
-
-/******************************************************************************/
-/**
- The initial buffer sizes for send and receive buffers in each ssl_t session.
- Buffers are internally grown if more incoming or outgoing data storage is
- needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the
- buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced
- to this size. Most standard SSL handshakes require on the order of 1024 B.
-
- SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE
+ Configure Support for TLS protocol versions.
+ Define one of:
+ USE_TLS_1_2_AND_ABOVE
+ USE_TLS_1_1_AND_ABOVE
+ USE_TLS_1_0_AND_ABOVE
+ @note There is no option for enabling SSL3.0 at this level
*/
-#ifndef USE_DTLS
-#define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */
-#define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */
-#else
+# define USE_TLS_1_1_AND_ABOVE/**< @security default 1_1_AND_ABOVE */
+/* #define USE_TLS_1_2_AND_ABOVE *//**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
+/* #define USE_TLS_1_0_AND_ABOVE *//**< @security no longer recommended. */
+
/******************************************************************************/
/**
- The Path Maximum Transmission Unit is the largest datagram that can be
- sent or recieved. It is beyond the scope of DTLS to negotiate this value
- so make sure both sides have agreed on this value. This is an enforced
- limitation in MatrixDTLS so connections will not succeed if a peer has a
- PTMU set larger than this value.
-*/
-#define DTLS_PMTU 1500 /* 1500 Default/Maximum datagram len */
-#define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
-#define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+ Datagram TLS support.
+ Enables DTLS in addition to TLS.
+ @pre TLS_1_1
+ */
+# define USE_DTLS
-//#define DTLS_SEND_RECORDS_INDIVIDUALLY /* Max one record per datagram */
-#endif
+/******************************************************************************/
+/**
+ Compile time support for server or client side SSL
+ */
+# define USE_CLIENT_SIDE_SSL
+# define USE_SERVER_SIDE_SSL
-#ifdef __cplusplus
+/******************************************************************************/
+/**
+ Client certificate authentication
+ */
+# define USE_CLIENT_AUTH
+
+# ifdef USE_CLIENT_AUTH
+/**
+ Enable the handshake_messages signature in the CertificateVerify
+ protocol message to be signed using an external module.
+ */
+/* #define USE_EXT_CERTIFICATE_VERIFY_SIGNING */
+# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING
+/**
+ Compile an example external module that allows the
+ USE_EXT_CERTIFICATE_VERIFY_SIGNING feature to be tested using the example
+ client program and sslTest.
+ */
+/* #define USE_EXT_EXAMPLE_MODULE */
+# endif
+# endif
+
+/**
+ Enable if the server should send an empty CertificateRequest message if
+ no CA files have been loaded
+ */
+/* #define SERVER_CAN_SEND_EMPTY_CERT_REQUEST */
+
+/**
+ Enabling this define will allow the server to "downgrade" a client auth
+ handshake to a standard handshake if the client replies to a
+ CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback
+ will be called with a NULL cert in this case and the user can determine if
+ the handshake should continue in a non-client auth state.
+ */
+/* #define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */
+
+/******************************************************************************/
+/**
+ Enable the Application Layer Protocol Negotiation extension.
+ Servers and Clients will still have to use the required public API to
+ set protocols and register application callbacks to negotiate the
+ protocol that will be tunneled over TLS.
+ @see ALPN section in the developer's guide for information.
+ */
+/* #define USE_ALPN */
+
+/******************************************************************************/
+/**
+ Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the
+ sha1 hash of each CA file to the server for help in server selection.
+ This extra level of define is to help isolate the SHA1 requirement
+ */
+/* #define USE_TRUSTED_CA_INDICATION *//**< @security NIST_SHOULD */
+
+/******************************************************************************/
+/**
+ A client side configuration that requires a server to provide an OCSP
+ response if the client uses the certitificate status request extension.
+ The "must staple" terminology is typically associated with certificates
+ at the X.509 layer but it is a good description of what is being required
+ of the server at the TLS level.
+ @pre USE_OCSP must be enbled at the crypto level and the client application
+ must use the OCSPstapling session option at run time for this setting to
+ have any effect
+ */
+# ifdef USE_OCSP
+# define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */
+# endif
+
+/******************************************************************************/
+/**
+ Rehandshaking support.
+
+ Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the
+ protocol defined in RFC 5748 which fixed a critical exploit in
+ the standard TLS specification.
+
+ @security Looking towards TLS 1.3, which removes re-handshaking, this
+ feature is disabled by default.
+ */
+/* #define USE_REHANDSHAKING */
+
+/******************************************************************************/
+/**
+ If SERVER you may define the number of sessions to cache and how
+ long a session will remain valid in the cache from first access.
+ Session caching enables very fast "session resumption handshakes".
+
+ SSL_SESSION_TABLE_SIZE minimum value is 1
+ SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0
+
+ @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0
+ however, this will also immediately expire SESSION_TICKETS below.
+ */
+# ifdef USE_SERVER_SIDE_SSL
+# define SSL_SESSION_TABLE_SIZE 32
+# define SSL_SESSION_ENTRY_LIFE (86400 * 1000)/* one day, in milliseconds */
+# endif
+
+/******************************************************************************/
+/**
+ Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE
+ define applies to this method as well as the standard method. The
+ SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list.
+ */
+# define USE_STATELESS_SESSION_TICKETS
+# define SSL_SESSION_TICKET_LIST_LEN 32
+
+/******************************************************************************/
+/**
+ The initial buffer sizes for send and receive buffers in each ssl_t session.
+ Buffers are internally grown if more incoming or outgoing data storage is
+ needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the
+ buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced
+ to this size. Most standard SSL handshakes require on the order of 1024 B.
+
+ SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE
+ */
+# ifndef USE_DTLS
+# define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */
+# define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */
+# else
+/******************************************************************************/
+/**
+ The Path Maximum Transmission Unit is the largest datagram that can be
+ sent or recieved. It is beyond the scope of DTLS to negotiate this value
+ so make sure both sides have agreed on this value. This is an enforced
+ limitation in MatrixDTLS so connections will not succeed if a peer has a
+ PTMU set larger than this value.
+ */
+# define DTLS_PMTU 1500 /* 1500 Default/Maximum datagram len */
+# define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+# define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+
+/* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */
+# endif
+
+# ifdef __cplusplus
}
-#endif
+# endif
-#endif /* _h_MATRIXCONFIG */
+#endif /* _h_MATRIXCONFIG */
/******************************************************************************/
diff --git a/configs/tls/coreConfig.h b/configs/tls/coreConfig.h
index 1dc1ecf..81fa819 100644
--- a/configs/tls/coreConfig.h
+++ b/configs/tls/coreConfig.h
@@ -1,83 +1,83 @@
/**
- * @file coreConfig.h
- * @version $Format:%h%d$
+ * @file coreConfig.h
+ * @version $Format:%h%d$
*
- * Configuration settings for Matrix core module.
+ * Configuration settings for Matrix core module.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_CORECONFIG
-#define _h_PS_CORECONFIG
+# define _h_PS_CORECONFIG
/******************************************************************************/
/* Configurable features */
/******************************************************************************/
/**
- Enable various levels of trace.
- When these option is turned off, messages are silently
- discarded and their text does not take space in the binary image.
-*/
-//#define USE_CORE_TRACE
-#ifndef NO_CORE_ERROR
- #define USE_CORE_ERROR
-#endif
-#ifndef NO_CORE_ASSERT
- #define USE_CORE_ASSERT
-#endif
-
-/**
- If enabled, calls to the psError set of APIs will perform a platform
- abort on the exeutable to aid in debugging.
-*/
-#ifdef DEBUG
-//#define HALT_ON_PS_ERROR /* NOT RECOMMENDED FOR PRODUCTION BUILDS */
-#endif
-
-/**
- Include the psCoreOsdepMutex family of APIs
-
- @note If intending to compile crypto-cl, then this flag should
- always be set.
-*/
-#ifndef NO_MULTITHREADING
-#define USE_MULTITHREADING
-#endif /* NO_MULTITHREADING */
-
-/**
- Include the psNetwork family of APIs
-
- These APIs allow simple high-level socket api.
+ Enable various levels of trace.
+ When these option is turned off, messages are silently
+ discarded and their text does not take space in the binary image.
*/
-#define USE_PS_NETWORKING
+/* #define USE_CORE_TRACE */
+# ifndef NO_CORE_ERROR
+# define USE_CORE_ERROR
+# endif
+# ifndef NO_CORE_ASSERT
+# define USE_CORE_ASSERT
+# endif
-#endif /* _h_PS_CORECONFIG */
+/**
+ If enabled, calls to the psError set of APIs will perform a platform
+ abort on the exeutable to aid in debugging.
+ */
+# ifdef DEBUG
+/* #define HALT_ON_PS_ERROR *//* NOT RECOMMENDED FOR PRODUCTION BUILDS */
+# endif
+
+/**
+ Include the psCoreOsdepMutex family of APIs
+
+ @note If intending to compile crypto-cl, then this flag should
+ always be set.
+*/
+# ifndef NO_MULTITHREADING
+# define USE_MULTITHREADING
+# endif /* NO_MULTITHREADING */
+
+/**
+ Include the psNetwork family of APIs
+
+ These APIs allow simple high-level socket api.
+ */
+# define USE_PS_NETWORKING
+
+#endif /* _h_PS_CORECONFIG */
/******************************************************************************/
diff --git a/configs/tls/cryptoConfig.h b/configs/tls/cryptoConfig.h
index a42fe38..6a08ea4 100644
--- a/configs/tls/cryptoConfig.h
+++ b/configs/tls/cryptoConfig.h
@@ -1,220 +1,242 @@
/**
- * @file cryptoConfig.h
- * @version $Format:%h%d$
+ * @file cryptoConfig.h
+ * @version $Format:%h%d$
*
- * Configuration file for crypto features.
+ * Configuration file for crypto features.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_CRYPTOCONFIG
-#define _h_PS_CRYPTOCONFIG
+# define _h_PS_CRYPTOCONFIG
/******************************************************************************/
/* Configurable features */
/******************************************************************************/
/**
- Define to enable psTrace*Crypto APIs for debugging the crypto module.
-*/
-//#define USE_CRYPTO_TRACE
+ Define to enable psTrace*Crypto APIs for debugging the crypto module.
+ */
+/* #define USE_CRYPTO_TRACE */
-#ifdef DEBUG
-//#define CRYPTO_ASSERT /**< Extra sanity asserts */
-#endif
+# ifdef DEBUG
+/* #define CRYPTO_ASSERT *//**< Extra sanity asserts */
+# endif
/******************************************************************************/
/*
- Use built-in cryptographic library delivered with MatrixSSL
-*/
-#define USE_NATIVE_RSA /* Default built-in software support */
+ Use built-in cryptographic library delivered with MatrixSSL
+ */
+# define USE_NATIVE_RSA /* Default built-in software support */
/******************************************************************************/
/**
- Security related settings.
+ Security related settings.
- @security MIN_*_BITS is the minimum supported key sizes in bits, weaker
- keys will be rejected.
-*/
-#define MIN_ECC_BITS 192/**< @security Affects ECC curves below */
+ @security MIN_*_BITS is the minimum supported key sizes in bits, weaker
+ keys will be rejected.
+ */
+# define MIN_ECC_BITS 192/**< @security Affects ECC curves below */
-#define MIN_RSA_BITS 1024
+# define MIN_RSA_BITS 1024
-#define MIN_DH_BITS 1024
+# define MIN_DH_BITS 1024
-#define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */
+# define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */
/******************************************************************************/
/**
- Public-Key Algorithm Support.
-*/
-#define USE_RSA
-#define USE_ECC
-//#define USE_DH
+ Public-Key Algorithm Support.
+ */
+# define USE_RSA
+# define USE_ECC
+/* #define USE_DH */
/**< @note Enable verification of DSA signatures in certificate validation.
Works only when using the CL/SL library. @pre USE_CERT_PARSE. */
-//#define USE_DSA_VERIFY
+/* #define USE_DSA_VERIFY */
/******************************************************************************/
/**
Build the PKCS and ASN1 extra CL sublibraries.
- These are needed by the CL_PKCS API.
-*/
+ These are needed by the CL_PKCS API.
+ */
/******************************************************************************/
/**
- Define to enable the individual NIST Prime curves.
- @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
-*/
-#ifdef USE_ECC
- #define USE_SECP192R1/**< @security FIPS allowed for sig ver only. */
- #define USE_SECP224R1
- #define USE_SECP256R1/**< @security NIST_SHALL */
- #define USE_SECP384R1/**< @security NIST_SHALL */
- #define USE_SECP521R1
-#endif
+ Define to enable the individual NIST Prime curves.
+ @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
+ */
+# ifdef USE_ECC
+# define USE_SECP192R1/**< @security FIPS allowed for sig ver only. */
+# define USE_SECP224R1
+# define USE_SECP256R1/**< @security NIST_SHALL */
+# define USE_SECP384R1/**< @security NIST_SHALL */
+# define USE_SECP521R1
+# endif
/**
- Define to enable the individual Brainpool curves.
- @see https://tools.ietf.org/html/rfc5639
- @security WARNING: Public points on Brainpool curves are not validated
-*/
-#ifdef USE_ECC
-//#define USE_BRAIN224R1
-//#define USE_BRAIN256R1
-//#define USE_BRAIN384R1
-//#define USE_BRAIN512R1
-#endif
+ Define to enable the individual Brainpool curves.
+ @see https://tools.ietf.org/html/rfc5639
+ @security WARNING: Public points on Brainpool curves are not validated
+ */
+# ifdef USE_ECC
+/* #define USE_BRAIN224R1 */
+/* #define USE_BRAIN256R1 */
+/* #define USE_BRAIN384R1 */
+/* #define USE_BRAIN512R1 */
+# endif
/******************************************************************************/
/**
- Symmetric and AEAD ciphers.
- @security Deprecated ciphers must be enabled in cryptolib.h
-*/
-//#define USE_AES /* Enable/Disable AES */
-#define USE_AES_CBC
-#define USE_AES_GCM
+ Symmetric and AEAD ciphers.
+ @security Deprecated ciphers must be enabled in cryptolib.h
+ */
+/* #define USE_AES *//* Enable/Disable AES */
+# define USE_AES_CBC
+# define USE_AES_GCM
-#ifdef USE_LIBSODIUM
-//#define USE_CHACHA20_POLY1305
-#endif
+# ifdef USE_LIBSODIUM
+/* #define USE_CHACHA20_POLY1305 */
+# endif
/** @security 3DES is still relatively secure, however is deprecated for TLS */
-#define USE_3DES
+# define USE_3DES
/******************************************************************************/
/**
- Digest algorithms.
+ Digest algorithms.
- @note SHA256 and above are used with TLS 1.2, and also used for
- certificate signatures on some certificates regardless of TLS version.
+ @note SHA256 and above are used with TLS 1.2, and also used for
+ certificate signatures on some certificates regardless of TLS version.
- @security MD5 is deprecated, but still required in combination with SHA-1
- for TLS handshakes before TLS 1.2, meaning that the strength is at least
- that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable
- MD5 only for this purpose. The only other usage of MD5 by TLS is for
- certificate signatures and MD5 based cipher suites. Both of which are
- disabled at compile time by default.
+ @security MD5 is deprecated, but still required in combination with SHA-1
+ for TLS handshakes before TLS 1.2, meaning that the strength is at least
+ that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable
+ MD5 only for this purpose. The only other usage of MD5 by TLS is for
+ certificate signatures and MD5 based cipher suites. Both of which are
+ disabled at compile time by default.
- @security SHA1 will be deprecated in the future, but is still required in
- combination with MD5 for versions prior to TLS 1.2. In addition, SHA1
- certificates are still commonly used, so SHA1 support may be needed
- to validate older certificates. It is possible to completely disable
- SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting
- only with newer certificates.
-*/
-//#define USE_SHA224 /**< @note Used only for cert signature */
-#define USE_SHA256/**< @note Required for TLS 1.2 and above */
-#define USE_HMAC_SHA256
-#define USE_SHA384/**< @pre USE_SHA512 */
-#define USE_HMAC_SHA384
-#define USE_SHA512
+ @security SHA1 will be deprecated in the future, but is still required in
+ combination with MD5 for versions prior to TLS 1.2. In addition, SHA1
+ certificates are still commonly used, so SHA1 support may be needed
+ to validate older certificates. It is possible to completely disable
+ SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting
+ only with newer certificates.
+ */
+/* #define USE_SHA224 *//**< @note Used only for cert signature */
+# define USE_SHA256/**< @note Required for TLS 1.2 and above */
+# define USE_HMAC_SHA256
+# define USE_SHA384/**< @pre USE_SHA512 */
+# define USE_HMAC_SHA384
+# define USE_SHA512
/**
- @security SHA-1 based hashes are deprecated but enabled by default
- @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below.
-*/
-#define USE_SHA1
-#define USE_HMAC_SHA1
+ @security SHA-1 based hashes are deprecated but enabled by default
+ @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below.
+ */
+# define USE_SHA1
+# define USE_HMAC_SHA1
/**
- @security MD5 is considered insecure, but required by TLS < 1.2
- @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below.
-*/
-#define USE_MD5
-#define USE_MD5SHA1/* Required for < TLS 1.2 Handshake */
-#define USE_HMAC_MD5
+ @security MD5 is considered insecure, but required by TLS < 1.2
+ @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below.
+ */
+# define USE_MD5
+# define USE_MD5SHA1/* Required for < TLS 1.2 Handshake */
+# define USE_HMAC_MD5
/**
@security MD2 is considered insecure, but is sometimes used for
- verification of legacy root certificate signatures.
- @note MD2 signature verification also requires
- ENABLE_MD5_SIGNED_CERTS and USE_MD5.
-*/
-//#define USE_MD2
+ verification of legacy root certificate signatures.
+ @note MD2 signature verification also requires
+ ENABLE_MD5_SIGNED_CERTS and USE_MD5.
+ */
+/* #define USE_MD2 */
/* Please enable, unless using no HMAC algorithms. */
-#define USE_HMAC
+# define USE_HMAC
/******************************************************************************/
/**
- X.509 Certificates/PKI
-*/
-#define USE_BASE64_DECODE
-#define USE_X509/**< Enable minimal X.509 support. */
-#define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */
-#define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */
- /**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */
-//#define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
- /**< Support extra distinguished name attributes not mentioned in RFC 5280. */
-//#define USE_EXTRA_DN_ATTRIBUTES
-//#define ENABLE_CA_CERT_HASH /**< Used only for TLS trusted CA ind ext. */
-//#define ENABLE_MD5_SIGNED_CERTS /** @security Accept MD5 signed certs? */
-#define ENABLE_SHA1_SIGNED_CERTS/** @security Accept SHA1 signed certs? */
- /**< @security Allow parsing of locally trusted v1 root certs? */
-//#define ALLOW_VERSION_1_ROOT_CERT_PARSE
-#define USE_CRL/***< @pre USE_FULL_CERT_PARSE */
-#define USE_OCSP/**< @pre USE_SHA1 */
+ X.509 Certificates/PKI
+ */
+# define USE_BASE64_DECODE
+# define USE_X509/**< Enable minimal X.509 support. */
+# define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */
+# define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */
+/**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */
+/* #define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
+/**< Support extra distinguished name attributes not mentioned in RFC 5280. */
+/* #define USE_EXTRA_DN_ATTRIBUTES */
+/* #define ENABLE_CA_CERT_HASH *//**< Used only for TLS trusted CA ind ext. */
+/* #define ENABLE_MD5_SIGNED_CERTS *//** @security Accept MD5 signed certs? */
+# define ENABLE_SHA1_SIGNED_CERTS/** @security Accept SHA1 signed certs? */
+/**< @security Allow parsing of locally trusted v1 root certs? */
+/* #define ALLOW_VERSION_1_ROOT_CERT_PARSE */
+/**
+ When parsing certificates, always also retain the unparsed DER data.
+ Enabling this has the same effect as setting the
+ CERT_STORE_UNPARSED_BUFFER flag in each psX509ParseCert call.
+ */
+/* #define ALWAYS_KEEP_CERT_DER */
+/**
+ Always attempt to match expectedName with the subject CN, even if
+ a supported, but non-matching subjectAltName was presented.
+ The default behaviour is to check the CN only when no supported SAN
+ was presented, in accordance with Section 6.4.4 of RFC 6125.
+ */
+/* #define ALWAYS_CHECK_SUBJECT_CN_IN_HOSTNAME_VALIDATION */
+# define USE_CRL/***< @pre USE_FULL_CERT_PARSE */
+# ifdef USE_CRL
+/**
+ Allow CRL authentication to succeed even when signer CA's cert does not
+ have the keyUsage extension and thus no cRLSign bit.
+ Note that RFC 5280 requires CRL issuer certs to have the keyUsage extension
+ and the cRLSign bit.
+ */
+/* #define ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE */
+# endif
+# define USE_OCSP/**< @pre USE_SHA1 */
/******************************************************************************/
/**
- Various PKCS standards support
-*/
-#define USE_PRIVATE_KEY_PARSING
-#define USE_PKCS5/**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */
+ Various PKCS standards support
+ */
+# define USE_PRIVATE_KEY_PARSING
+# define USE_PKCS5/**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */
/**< Enable PBKDF1 in priv key PEM encryption. @pre USE_PKCS5 and @pre USE_MD5. @security Not recommended. */
-#define USE_PBKDF1
-#define USE_PKCS8/* Alternative private key storage format */
-#define USE_PKCS12/**< @pre USE_PKCS8 */
-#define USE_PKCS1_OAEP/* OAEP padding algorithm */
-#define USE_PKCS1_PSS/* PSS padding algorithm */
+# define USE_PBKDF1
+# define USE_PKCS8/* Alternative private key storage format */
+# define USE_PKCS12/**< @pre USE_PKCS8 */
+# define USE_PKCS1_OAEP/* OAEP padding algorithm */
+# define USE_PKCS1_PSS/* PSS padding algorithm */
-#endif /* _h_PS_CRYPTOCONFIG */
+#endif /* _h_PS_CRYPTOCONFIG */
/******************************************************************************/
diff --git a/configs/tls/matrixsslConfig.h b/configs/tls/matrixsslConfig.h
index fdfc689..3d1af9d 100644
--- a/configs/tls/matrixsslConfig.h
+++ b/configs/tls/matrixsslConfig.h
@@ -1,160 +1,160 @@
/**
- * @file matrixsslConfig.h
- * @version $Format:%h%d$
+ * @file matrixsslConfig.h
+ * @version $Format:%h%d$
*
- * Configuration settings for building the MatrixSSL library.
- * This configuration is intended to be used in FIPS Mode of operation.
- * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and
- * to enable the most commonly used cipher suites.
+ * Configuration settings for building the MatrixSSL library.
+ * This configuration is intended to be used in FIPS Mode of operation.
+ * The configuration aims to be compatible with NIST SP 800-52 Rev 1 and
+ * to enable the most commonly used cipher suites.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_MATRIXSSLCONFIG
-#define _h_MATRIXSSLCONFIG
+# define _h_MATRIXSSLCONFIG
-#ifdef __cplusplus
+# ifdef __cplusplus
extern "C" {
-#endif
+# endif
/**
- NIST SP 800-52 Rev 1 Conformance.
- Guidelines for the Selection, Configuration, and Use of Transport Layer
- Security (TLS) Implementations
- The key words "shall", "shall not", "should", "should not" and "may"
- are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as
- "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility
- is not relevant.
- @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf
-*/
+ NIST SP 800-52 Rev 1 Conformance.
+ Guidelines for the Selection, Configuration, and Use of Transport Layer
+ Security (TLS) Implementations
+ The key words "shall", "shall not", "should", "should not" and "may"
+ are used as references to the NIST SP 800-52 Rev 1. Algorithms marked as
+ "shall" must not be disabled unless NIST SP 800-52 Rev 1 compatibility
+ is not relevant.
+ @see http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r1.pdf
+ */
/******************************************************************************/
/**
- Show which SSL messages are created and parsed
-*/
-//#define USE_SSL_HANDSHAKE_MSG_TRACE
+ Show which SSL messages are created and parsed
+ */
+/* #define USE_SSL_HANDSHAKE_MSG_TRACE */
/**
- Informational trace that could help pinpoint problems with SSL connections
-*/
-//#define USE_SSL_INFORMATIONAL_TRACE
-//#define USE_DTLS_DEBUG_TRACE
+ Informational trace that could help pinpoint problems with SSL connections
+ */
+/* #define USE_SSL_INFORMATIONAL_TRACE */
+/* #define USE_DTLS_DEBUG_TRACE */
/******************************************************************************/
/**
- Recommended cipher suites.
- Define the following to enable various cipher suites
- At least one of these must be defined. If multiple are defined,
- the handshake negotiation will determine which is best for the connection.
- @note Ephemeral ciphersuites offer perfect forward security (PFS)
- at the cost of a slower TLS handshake.
-*/
+ Recommended cipher suites.
+ Define the following to enable various cipher suites
+ At least one of these must be defined. If multiple are defined,
+ the handshake negotiation will determine which is best for the connection.
+ @note Ephemeral ciphersuites offer perfect forward security (PFS)
+ at the cost of a slower TLS handshake.
+ */
/** Ephemeral ECC DH keys, ECC DSA certificates */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA/**< @security NIST_MAY */
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA/**< @security NIST_MAY */
/* TLS 1.2 ciphers */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */
/** Ephemeral ECC DH keys, RSA certificates */
-#define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+# define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
/* TLS 1.2 ciphers */
-#define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
-#define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */
-#define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
-//#define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+# define USE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
+# define USE_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHOULD */
+# define USE_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */
/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */
-//#define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
-//#define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA */
+/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA */
/* TLS 1.2 ciphers */
-//#define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
-//#define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+/* #define USE_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */
+/* #define USE_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */
/** Non-Ephemeral RSA keys/certificates */
-#define USE_TLS_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHALL */
-#define USE_TLS_RSA_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD */
+# define USE_TLS_RSA_WITH_AES_128_CBC_SHA/**< @security NIST_SHALL */
+# define USE_TLS_RSA_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD */
/* TLS 1.2 ciphers */
-#define USE_TLS_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */
-#define USE_TLS_RSA_WITH_AES_256_CBC_SHA256/**< @security NIST_MAY */
-#define USE_TLS_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHALL */
-#define USE_TLS_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
+# define USE_TLS_RSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */
+# define USE_TLS_RSA_WITH_AES_256_CBC_SHA256/**< @security NIST_MAY */
+# define USE_TLS_RSA_WITH_AES_128_GCM_SHA256/**< @security NIST_SHALL */
+# define USE_TLS_RSA_WITH_AES_256_GCM_SHA384/**< @security NIST_SHOULD */
/******************************************************************************/
/**
- These cipher suites are secure, but not widely deployed.
-*/
+ These cipher suites are secure, but not widely deployed.
+ */
/** Ephemeral Diffie-Hellman ciphersuites, with RSA certificates */
-//#define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+/* #define USE_SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
/** Ephemeral Diffie-Hellman ciphersuites, with PSK authentication */
-//#define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA /**< @security NIST_SHOULD_NOT */
-//#define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA /**< @security NIST_SHOULD_NOT */
+/* #define USE_TLS_DHE_PSK_WITH_AES_128_CBC_SHA *//**< @security NIST_SHOULD_NOT */
+/* #define USE_TLS_DHE_PSK_WITH_AES_256_CBC_SHA *//**< @security NIST_SHOULD_NOT */
/** Ephemeral ECC DH keys, RSA certificates */
-//#define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA /**< @security NIST_SHOULD */
+/* #define USE_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHOULD */
/** Pre-Shared Key Ciphers.
- NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary
+ NIST SP 800-52 Rev 1 recommends against using PSK unless neccessary
See NIST SP 800-52 Rev 1 Appendix C */
-#define USE_TLS_PSK_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD_NOT */
-#define USE_TLS_PSK_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_128_CBC_SHA/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_256_CBC_SHA/**< @security NIST_SHOULD_NOT */
/* TLS 1.2 ciphers */
-#define USE_TLS_PSK_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD_NOT */
-#define USE_TLS_PSK_WITH_AES_256_CBC_SHA384/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_128_CBC_SHA256/**< @security NIST_SHOULD_NOT */
+# define USE_TLS_PSK_WITH_AES_256_CBC_SHA384/**< @security NIST_SHOULD_NOT */
/** Non-Ephemeral ECC DH keys, ECC DSA certificates */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA/**< @security NIST_MAY */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA/**< @security NIST_MAY */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA/**< @security NIST_MAY */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA/**< @security NIST_MAY */
/* TLS 1.2 ciphers */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_MAY */
-#define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_MAY */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256/**< @security NIST_MAY */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384/**< @security NIST_MAY */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256/**< @security NIST_MAY */
+# define USE_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384/**< @security NIST_MAY */
/** Non-Ephemeral ECC DH keys, RSA certificates */
-#define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
-#define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+# define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+# define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
/* TLS 1.2 ciphers */
-#define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
-#define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
-#define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
-#define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+# define USE_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+# define USE_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+# define USE_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+# define USE_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
/** Non-Ephemeral RSA keys/certificates */
-//#define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA /**< @security NIST_SHALL */
+/* #define USE_SSL_RSA_WITH_3DES_EDE_CBC_SHA *//**< @security NIST_SHALL */
/** @note Some of (non-mandatory) cipher suites mentioned in NIST SP 800-52
Rev 1 are not supported by the MatrixSSL / MatrixDTLS.
@@ -166,171 +166,187 @@ extern "C" {
/******************************************************************************/
/**
- Ephemeral key cache support.
- If not using cache, new key exchange keys are created for each TLS session.
- If using cache, keys are generated initially, and re-used in each
- subsequent TLS connection within a given time frame and usage count.
- @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE
+ Ephemeral key cache support.
+ If not using cache, new key exchange keys are created for each TLS session.
+ If using cache, keys are generated initially, and re-used in each
+ subsequent TLS connection within a given time frame and usage count.
+ @see ECC_EPHEMERAL_CACHE_SECONDS and ECC_EPHEMERAL_CACHE_USAGE
- @security Do not cache Ephemeral ECC keys as it is against some standards,
- including NIST SP 800-56A, when in FIPS 140-2 mode of operation.
-*/
-//#define NO_ECC_EPHEMERAL_CACHE /**< @security NIST_SHALL */
-
-/******************************************************************************/
-/**
- Configure Support for TLS protocol versions.
- Define one of:
- USE_TLS_1_2_AND_ABOVE
- USE_TLS_1_1_AND_ABOVE
- USE_TLS_1_0_AND_ABOVE
- @note There is no option for enabling SSL3.0 at this level
-*/
-#define USE_TLS_1_1_AND_ABOVE/**< @security default 1_1_AND_ABOVE */
-//#define USE_TLS_1_2_AND_ABOVE /**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
-//#define USE_TLS_1_0_AND_ABOVE /**< @security no longer recommended. */
-
-/******************************************************************************/
-/**
- Datagram TLS support.
- Enables DTLS in addition to TLS.
- @pre TLS_1_1
-*/
-#define USE_DTLS
-
-/******************************************************************************/
-/**
- Compile time support for server or client side SSL
-*/
-#define USE_CLIENT_SIDE_SSL
-#define USE_SERVER_SIDE_SSL
-
-/******************************************************************************/
-/**
- Client certificate authentication
-*/
-#define USE_CLIENT_AUTH
-
-/**
- Enable if the server should send an empty CertificateRequest message if
- no CA files have been loaded
-*/
-//#define SERVER_CAN_SEND_EMPTY_CERT_REQUEST
-
-/**
- Enabling this define will allow the server to "downgrade" a client auth
- handshake to a standard handshake if the client replies to a
- CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback
- will be called with a NULL cert in this case and the user can determine if
- the handshake should continue in a non-client auth state.
-*/
-//#define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG
-
-/******************************************************************************/
-/**
- Enable the Application Layer Protocol Negotiation extension.
- Servers and Clients will still have to use the required public API to
- set protocols and register application callbacks to negotiate the
- protocol that will be tunneled over TLS.
- @see ALPN section in the developer's guide for information.
+ @security Do not cache Ephemeral ECC keys as it is against some standards,
+ including NIST SP 800-56A, when in FIPS 140-2 mode of operation.
*/
-//#define USE_ALPN
+/* #define NO_ECC_EPHEMERAL_CACHE *//**< @security NIST_SHALL */
/******************************************************************************/
/**
- Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the
- sha1 hash of each CA file to the server for help in server selection.
- This extra level of define is to help isolate the SHA1 requirement
-*/
-//#define USE_TRUSTED_CA_INDICATION /**< @security NIST_SHOULD */
-
-/******************************************************************************/
-/**
- A client side configuration that requires a server to provide an OCSP
- response if the client uses the certitificate status request extension.
- The "must staple" terminology is typically associated with certificates
- at the X.509 layer but it is a good description of what is being required
- of the server at the TLS level.
- @pre USE_OCSP must be enbled at the crypto level and the client application
- must use the OCSPstapling session option at run time for this setting to
- have any effect
-*/
-#ifdef USE_OCSP
-#define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */
-#endif
-
-/******************************************************************************/
-/**
- Rehandshaking support.
-
- Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the
- protocol defined in RFC 5748 which fixed a critical exploit in
- the standard TLS specification.
-
- @security Looking towards TLS 1.3, which removes re-handshaking, this
- feature is disabled by default.
-*/
-//#define USE_REHANDSHAKING
-
-/******************************************************************************/
-/**
- If SERVER you may define the number of sessions to cache and how
- long a session will remain valid in the cache from first access.
- Session caching enables very fast "session resumption handshakes".
-
- SSL_SESSION_TABLE_SIZE minimum value is 1
- SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0
-
- @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0
- however, this will also immediately expire SESSION_TICKETS below.
-*/
-#ifdef USE_SERVER_SIDE_SSL
-#define SSL_SESSION_TABLE_SIZE 32
-#define SSL_SESSION_ENTRY_LIFE (86400*1000)/* one day, in milliseconds */
-#endif
-
-/******************************************************************************/
-/**
- Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE
- define applies to this method as well as the standard method. The
- SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list.
-*/
-#define USE_STATELESS_SESSION_TICKETS
-#define SSL_SESSION_TICKET_LIST_LEN 32
-
-/******************************************************************************/
-/**
- The initial buffer sizes for send and receive buffers in each ssl_t session.
- Buffers are internally grown if more incoming or outgoing data storage is
- needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the
- buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced
- to this size. Most standard SSL handshakes require on the order of 1024 B.
-
- SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE
+ Configure Support for TLS protocol versions.
+ Define one of:
+ USE_TLS_1_2_AND_ABOVE
+ USE_TLS_1_1_AND_ABOVE
+ USE_TLS_1_0_AND_ABOVE
+ @note There is no option for enabling SSL3.0 at this level
*/
-#ifndef USE_DTLS
-#define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */
-#define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */
-#else
+# define USE_TLS_1_1_AND_ABOVE/**< @security default 1_1_AND_ABOVE */
+/* #define USE_TLS_1_2_AND_ABOVE *//**< @security better than 1_1_AND_ABOVE if no backwards compatiblity concerns */
+/* #define USE_TLS_1_0_AND_ABOVE *//**< @security no longer recommended. */
+
/******************************************************************************/
/**
- The Path Maximum Transmission Unit is the largest datagram that can be
- sent or recieved. It is beyond the scope of DTLS to negotiate this value
- so make sure both sides have agreed on this value. This is an enforced
- limitation in MatrixDTLS so connections will not succeed if a peer has a
- PTMU set larger than this value.
-*/
-#define DTLS_PMTU 1500 /* 1500 Default/Maximum datagram len */
-#define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
-#define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+ Datagram TLS support.
+ Enables DTLS in addition to TLS.
+ @pre TLS_1_1
+ */
+# define USE_DTLS
-//#define DTLS_SEND_RECORDS_INDIVIDUALLY /* Max one record per datagram */
-#endif
+/******************************************************************************/
+/**
+ Compile time support for server or client side SSL
+ */
+# define USE_CLIENT_SIDE_SSL
+# define USE_SERVER_SIDE_SSL
-#ifdef __cplusplus
+/******************************************************************************/
+/**
+ Client certificate authentication
+ */
+# define USE_CLIENT_AUTH
+
+# ifdef USE_CLIENT_AUTH
+/**
+ Enable the handshake_messages signature in the CertificateVerify
+ protocol message to be signed using an external module.
+ */
+/* #define USE_EXT_CERTIFICATE_VERIFY_SIGNING */
+# ifdef USE_EXT_CERTIFICATE_VERIFY_SIGNING
+/**
+ Compile an example external module that allows the
+ USE_EXT_CERTIFICATE_VERIFY_SIGNING feature to be tested using the example
+ client program and sslTest.
+ */
+/* #define USE_EXT_EXAMPLE_MODULE */
+# endif
+# endif
+
+/**
+ Enable if the server should send an empty CertificateRequest message if
+ no CA files have been loaded
+ */
+/* #define SERVER_CAN_SEND_EMPTY_CERT_REQUEST */
+
+/**
+ Enabling this define will allow the server to "downgrade" a client auth
+ handshake to a standard handshake if the client replies to a
+ CERTIFICATE_REQUEST with an empty CERTIFICATE message. The user callback
+ will be called with a NULL cert in this case and the user can determine if
+ the handshake should continue in a non-client auth state.
+ */
+/* #define SERVER_WILL_ACCEPT_EMPTY_CLIENT_CERT_MSG */
+
+/******************************************************************************/
+/**
+ Enable the Application Layer Protocol Negotiation extension.
+ Servers and Clients will still have to use the required public API to
+ set protocols and register application callbacks to negotiate the
+ protocol that will be tunneled over TLS.
+ @see ALPN section in the developer's guide for information.
+ */
+/* #define USE_ALPN */
+
+/******************************************************************************/
+/**
+ Enable the Trusted CA Indication CLIENT_HELLO extension. Will send the
+ sha1 hash of each CA file to the server for help in server selection.
+ This extra level of define is to help isolate the SHA1 requirement
+ */
+/* #define USE_TRUSTED_CA_INDICATION *//**< @security NIST_SHOULD */
+
+/******************************************************************************/
+/**
+ A client side configuration that requires a server to provide an OCSP
+ response if the client uses the certitificate status request extension.
+ The "must staple" terminology is typically associated with certificates
+ at the X.509 layer but it is a good description of what is being required
+ of the server at the TLS level.
+ @pre USE_OCSP must be enbled at the crypto level and the client application
+ must use the OCSPstapling session option at run time for this setting to
+ have any effect
+ */
+# ifdef USE_OCSP
+# define USE_OCSP_MUST_STAPLE /**< @security NIST_SHALL */
+# endif
+
+/******************************************************************************/
+/**
+ Rehandshaking support.
+
+ Enabling USE_REHANDSHAKING will allow secure-rehandshakes using the
+ protocol defined in RFC 5748 which fixed a critical exploit in
+ the standard TLS specification.
+
+ @security Looking towards TLS 1.3, which removes re-handshaking, this
+ feature is disabled by default.
+ */
+/* #define USE_REHANDSHAKING */
+
+/******************************************************************************/
+/**
+ If SERVER you may define the number of sessions to cache and how
+ long a session will remain valid in the cache from first access.
+ Session caching enables very fast "session resumption handshakes".
+
+ SSL_SESSION_TABLE_SIZE minimum value is 1
+ SSL_SESSION_ENTRY_LIFE is in milliseconds, minimum 0
+
+ @note Session caching can be disabled by setting SSL_SESSION_ENTRY_LIFE to 0
+ however, this will also immediately expire SESSION_TICKETS below.
+ */
+# ifdef USE_SERVER_SIDE_SSL
+# define SSL_SESSION_TABLE_SIZE 32
+# define SSL_SESSION_ENTRY_LIFE (86400 * 1000)/* one day, in milliseconds */
+# endif
+
+/******************************************************************************/
+/**
+ Use RFC 5077 session resumption mechanism. The SSL_SESSION_ENTRY_LIFE
+ define applies to this method as well as the standard method. The
+ SSL_SESSION_TICKET_LIST_LEN is the max size of the server key list.
+ */
+# define USE_STATELESS_SESSION_TICKETS
+# define SSL_SESSION_TICKET_LIST_LEN 32
+
+/******************************************************************************/
+/**
+ The initial buffer sizes for send and receive buffers in each ssl_t session.
+ Buffers are internally grown if more incoming or outgoing data storage is
+ needed, up to a maximum of SSL_MAX_BUF_SIZE. Once the memory used by the
+ buffer again drops below SSL_DEFAULT_X_BUF_SIZE, the buffer will be reduced
+ to this size. Most standard SSL handshakes require on the order of 1024 B.
+
+ SSL_DEFAULT_x_BUF_SIZE value in bytes, maximum SSL_MAX_BUF_SIZE
+ */
+# ifndef USE_DTLS
+# define SSL_DEFAULT_IN_BUF_SIZE 1500 /* Base recv buf size, bytes */
+# define SSL_DEFAULT_OUT_BUF_SIZE 1500 /* Base send buf size, bytes */
+# else
+/******************************************************************************/
+/**
+ The Path Maximum Transmission Unit is the largest datagram that can be
+ sent or recieved. It is beyond the scope of DTLS to negotiate this value
+ so make sure both sides have agreed on this value. This is an enforced
+ limitation in MatrixDTLS so connections will not succeed if a peer has a
+ PTMU set larger than this value.
+ */
+# define DTLS_PMTU 1500 /* 1500 Default/Maximum datagram len */
+# define SSL_DEFAULT_IN_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+# define SSL_DEFAULT_OUT_BUF_SIZE DTLS_PMTU /* See PMTU comments above */
+
+/* #define DTLS_SEND_RECORDS_INDIVIDUALLY *//* Max one record per datagram */
+# endif
+
+# ifdef __cplusplus
}
-#endif
+# endif
-#endif /* _h_MATRIXCONFIG */
+#endif /* _h_MATRIXCONFIG */
/******************************************************************************/
diff --git a/core/Makefile b/core/Makefile
index 76e57fc..f1db298 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -11,6 +11,7 @@ SRC:=\
memset_s.c \
corelib.c \
psbuf.c \
+ psUtil.c \
$(OSDEP)/osdep.c
ASM:=memset_s.s
@@ -24,11 +25,11 @@ compile: $(ASM) $(OBJS) $(STATIC)
# Special rule to build memset_s function without optimization
memset_s.o: memset_s.c
- $(CC) -O0 -Wall -ffunction-sections -fdata-sections -o $@ -c $<
+ $(CC) -O0 -Wall -ffunction-sections -fdata-sections -o $@ $(CFLAGS_MEMSET_S) -c $<
# Generate the (.s) assembly file to verify zero is being performed
$(ASM): memset_s.c
- $(CC) -O0 -g -fverbose-asm -S $<
+ $(CC) -O0 -g -fverbose-asm $(CFLAGS_MEMSET_S) -S $<
# Additional Dependencies
$(OBJS): $(MATRIXSSL_ROOT)/common.mk Makefile *.h
diff --git a/core/POSIX/osdep.c b/core/POSIX/osdep.c
index d5eb2da..1b47d6d 100644
--- a/core/POSIX/osdep.c
+++ b/core/POSIX/osdep.c
@@ -1,72 +1,75 @@
/**
- * @file osdep.c
- * @version $Format:%h%d$
+ * @file osdep.c
+ * @version $Format:%h%d$
*
- * POSIX layer.
- * Mac OSX 10.5
- * Linux
+ * POSIX layer.
+ * Mac OSX 10.5
+ * Linux
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#include "../coreApi.h"
+#include "../osdep.h"
#ifdef POSIX
/******************************************************************************/
/*
- Universal system POSIX headers and then PScore/coreApi.h
- OS-specific header includes should be added to PScore/osdep.h
-*/
-#include /* abort() */
-#include /* open(), O_RDONLY, ect... */
-#include /* close() */
-#include /* errno */
-#include /* gettimeofday */
+ Universal system POSIX headers and then PScore/coreApi.h
+ OS-specific header includes should be added to PScore/osdep.h
+ */
+# include /* abort() */
+# include /* open(), O_RDONLY, ect... */
+# include /* close() */
+# include /* errno */
+# include /* gettimeofday */
/******************************************************************************/
/*
- TIME FUNCTIONS
-*/
-#ifndef USE_HIGHRES_TIME
+ TIME FUNCTIONS
+ */
+# ifndef USE_HIGHRES_TIME
/******************************************************************************/
/*
- Module open and close
-*/
+ Module open and close
+ */
int osdepTimeOpen(void)
{
- psTime_t lt;
+ psTime_t lt;
+
/*
- Just a check that gettimeofday is functioning
-*/
- if (gettimeofday(<, NULL) < 0) {
- return PS_FAILURE;
- }
- return PS_SUCCESS;
+ Just a check that gettimeofday is functioning
+ */
+ if (gettimeofday(<, NULL) < 0)
+ {
+ return PS_FAILURE;
+ }
+ return PS_SUCCESS;
}
void osdepTimeClose(void)
@@ -74,65 +77,71 @@ void osdepTimeClose(void)
}
/*
- PScore Public API implementations
+ PScore Public API implementations
- This function always returns seconds/ticks AND OPTIONALLY populates
- whatever psTime_t happens to be on the given platform.
-*/
+ This function always returns seconds/ticks AND OPTIONALLY populates
+ whatever psTime_t happens to be on the given platform.
+ */
int32 psGetTime(psTime_t *t, void *userPtr)
{
- psTime_t lt;
+ psTime_t lt;
- if (t == NULL) {
- if (gettimeofday(<, NULL) < 0) {
- return PS_FAILURE;
- }
- return lt.tv_sec;
- }
+ if (t == NULL)
+ {
+ if (gettimeofday(<, NULL) < 0)
+ {
+ return PS_FAILURE;
+ }
+ return lt.tv_sec;
+ }
- if (gettimeofday(t, NULL) < 0) {
- return PS_FAILURE;
- }
- return t->tv_sec;
+ if (gettimeofday(t, NULL) < 0)
+ {
+ return PS_FAILURE;
+ }
+ return t->tv_sec;
}
int32 psDiffMsecs(psTime_t then, psTime_t now, void *userPtr)
{
- if (now.tv_usec < then.tv_usec) {
- now.tv_sec--;
- now.tv_usec += 1000000; /* borrow 1 second worth of usec */
- }
- return (int32)((now.tv_sec - then.tv_sec) * 1000) +
- ((now.tv_usec - then.tv_usec)/ 1000);
+ if (now.tv_usec < then.tv_usec)
+ {
+ now.tv_sec--;
+ now.tv_usec += 1000000; /* borrow 1 second worth of usec */
+ }
+ return (int32) ((now.tv_sec - then.tv_sec) * 1000) +
+ ((now.tv_usec - then.tv_usec) / 1000);
}
int32 psCompareTime(psTime_t a, psTime_t b, void *userPtr)
{
/*
- Time comparison. 1 if 'a' is less than or equal. 0 if 'a' is greater
-*/
- if (a.tv_sec < b.tv_sec) {
- return 1;
- }
- if (a.tv_sec == b.tv_sec && a.tv_usec <= b.tv_usec) {
- return 1;
- }
- return 0;
+ Time comparison. 1 if 'a' is less than or equal. 0 if 'a' is greater
+ */
+ if (a.tv_sec < b.tv_sec)
+ {
+ return 1;
+ }
+ if (a.tv_sec == b.tv_sec && a.tv_usec <= b.tv_usec)
+ {
+ return 1;
+ }
+ return 0;
}
-#else /* USE_HIGHRES_TIME */
+# else /* USE_HIGHRES_TIME */
/******************************************************************************/
-#ifdef __APPLE__
+# ifdef __APPLE__
/* MAC OS X */
-#include
+# include
static mach_timebase_info_data_t hiresFreq;
int osdepTimeOpen(void)
{
- mach_timebase_info(&hiresFreq);
- return PS_SUCCESS;
+ mach_timebase_info(&hiresFreq);
+ return PS_SUCCESS;
}
void osdepTimeClose(void)
@@ -141,37 +150,38 @@ void osdepTimeClose(void)
int32 psGetTime(psTime_t *t, void *userPtr)
{
- psTime_t lt;
+ psTime_t lt;
- if (t == NULL) {
- t = <
- }
- *t = mach_absolute_time();
- return (int32)((*t * hiresFreq.numer) / (hiresFreq.denom * 1000000000L));
+ if (t == NULL)
+ {
+ t = <
+ }
+ *t = mach_absolute_time();
+ return (int32) ((*t * hiresFreq.numer) / (hiresFreq.denom * 1000000000L));
}
int32 psDiffMsecs(psTime_t then, psTime_t now, void *userPtr)
{
- return (int32)(((now - then) * hiresFreq.numer) / (hiresFreq.denom * 1000000));
+ return (int32) (((now - then) * hiresFreq.numer) / (hiresFreq.denom * 1000000));
}
int64_t psDiffUsecs(psTime_t then, psTime_t now)
{
- return (int64_t)(((now - then) * hiresFreq.numer) / (hiresFreq.denom * 1000));
+ return (int64_t) (((now - then) * hiresFreq.numer) / (hiresFreq.denom * 1000));
}
int32 psCompareTime(psTime_t a, psTime_t b, void *userPtr)
{
- return a <= b ? 1 : 0;
+ return a <= b ? 1 : 0;
}
/******************************************************************************/
-#else /* !APPLE, !tile */
+# else /* !APPLE, !tile */
/******************************************************************************/
/* LINUX */
int osdepTimeOpen(void)
{
- return PS_SUCCESS;
+ return PS_SUCCESS;
}
void osdepTimeClose(void)
@@ -180,62 +190,67 @@ void osdepTimeClose(void)
int32 psGetTime(psTime_t *t, void *userPtr)
{
- psTime_t lt;
+ psTime_t lt;
- if (t == NULL) {
- t = <
- }
- clock_gettime(CLOCK_MONOTONIC, t);
- return t->tv_sec;
+ if (t == NULL)
+ {
+ t = <
+ }
+ clock_gettime(CLOCK_MONOTONIC, t);
+ return t->tv_sec;
}
int32 psDiffMsecs(psTime_t then, psTime_t now, void *userPtr)
{
- if (now.tv_nsec < then.tv_nsec) {
- now.tv_sec--;
- now.tv_nsec += 1000000000L; /* borrow 1 second worth of nsec */
- }
- return (int32)((now.tv_sec - then.tv_sec) * 1000) +
- ((now.tv_nsec - then.tv_nsec)/ 1000000);
+ if (now.tv_nsec < then.tv_nsec)
+ {
+ now.tv_sec--;
+ now.tv_nsec += 1000000000L; /* borrow 1 second worth of nsec */
+ }
+ return (int32) ((now.tv_sec - then.tv_sec) * 1000) +
+ ((now.tv_nsec - then.tv_nsec) / 1000000);
}
int64_t psDiffUsecs(psTime_t then, psTime_t now)
{
- if (now.tv_nsec < then.tv_nsec) {
- now.tv_sec--;
- now.tv_nsec += 1000000000L; /* borrow 1 second worth of nsec */
- }
- return (int32)((now.tv_sec - then.tv_sec) * 1000000) +
- ((now.tv_nsec - then.tv_nsec)/ 1000);
+ if (now.tv_nsec < then.tv_nsec)
+ {
+ now.tv_sec--;
+ now.tv_nsec += 1000000000L; /* borrow 1 second worth of nsec */
+ }
+ return (int32) ((now.tv_sec - then.tv_sec) * 1000000) +
+ ((now.tv_nsec - then.tv_nsec) / 1000);
}
int32 psCompareTime(psTime_t a, psTime_t b, void *userPtr)
{
- /* Time comparison. 1 if 'a' is less than or equal. 0 if 'a' is greater */
- if (a.tv_sec < b.tv_sec) {
- return 1;
- }
- if (a.tv_sec == b.tv_sec && a.tv_nsec <= b.tv_nsec) {
- return 1;
- }
- return 0;
+ /* Time comparison. 1 if 'a' is less than or equal. 0 if 'a' is greater */
+ if (a.tv_sec < b.tv_sec)
+ {
+ return 1;
+ }
+ if (a.tv_sec == b.tv_sec && a.tv_nsec <= b.tv_nsec)
+ {
+ return 1;
+ }
+ return 0;
}
-#endif /* !APPLE */
+# endif /* !APPLE */
-#endif /* USE_HIGHRES_TIME */
+# endif /* USE_HIGHRES_TIME */
/******************************************************************************/
-#ifdef USE_MULTITHREADING
+# ifdef USE_MULTITHREADING
/******************************************************************************/
/*
- MUTEX FUNCTIONS
-*/
+ MUTEX FUNCTIONS
+ */
/******************************************************************************/
int32_t osdepMutexOpen(void)
{
- return PS_SUCCESS;
+ return PS_SUCCESS;
}
void osdepMutexClose(void)
@@ -244,180 +259,210 @@ void osdepMutexClose(void)
int32_t psCreateMutex(psMutex_t *mutex, uint32_t flags)
{
- pthread_mutexattr_t attr;
- int rc;
+ pthread_mutexattr_t attr;
+ int rc;
- if (flags & ~PS_SHARED) {
- psErrorInt("psCreateMutex unsupported flag %u\n", flags);
- return PS_PLATFORM_FAIL;
- }
- if ((rc = pthread_mutexattr_init(&attr)) < 0) {
- psErrorInt("pthread_mutexattr_init failed %d\n", rc);
- return PS_PLATFORM_FAIL;
- }
- if ((flags & PS_SHARED) &&
- (rc = pthread_mutexattr_setpshared(&attr,
- PTHREAD_PROCESS_SHARED)) < 0) {
- pthread_mutexattr_destroy(&attr);
- psErrorInt("pthread_mutexattr shared failed %d\n", rc);
- return PS_PLATFORM_FAIL;
- }
- if ((rc = pthread_mutex_init(mutex, &attr)) != 0) {
- pthread_mutexattr_destroy(&attr);
- psErrorInt("pthread_mutex_init failed %d\n", rc);
- return PS_PLATFORM_FAIL;
- }
- if (pthread_mutexattr_destroy(&attr) != 0) {
- psTraceCore("pthread_mutexattr_destroy failed\n");
- }
- return PS_SUCCESS;
+ if (flags & ~PS_SHARED)
+ {
+ psErrorInt("psCreateMutex unsupported flag %u\n", flags);
+ return PS_PLATFORM_FAIL;
+ }
+ if ((rc = pthread_mutexattr_init(&attr)) < 0)
+ {
+ psErrorInt("pthread_mutexattr_init failed %d\n", rc);
+ return PS_PLATFORM_FAIL;
+ }
+ if ((flags & PS_SHARED) &&
+ (rc = pthread_mutexattr_setpshared(&attr,
+ PTHREAD_PROCESS_SHARED)) < 0)
+ {
+ pthread_mutexattr_destroy(&attr);
+ psErrorInt("pthread_mutexattr shared failed %d\n", rc);
+ return PS_PLATFORM_FAIL;
+ }
+ if ((rc = pthread_mutex_init(mutex, &attr)) != 0)
+ {
+ pthread_mutexattr_destroy(&attr);
+ psErrorInt("pthread_mutex_init failed %d\n", rc);
+ return PS_PLATFORM_FAIL;
+ }
+ if (pthread_mutexattr_destroy(&attr) != 0)
+ {
+ psTraceCore("pthread_mutexattr_destroy failed\n");
+ }
+ return PS_SUCCESS;
}
void psLockMutex(psMutex_t *mutex)
{
- if (pthread_mutex_lock(mutex) != 0) {
- psTraceCore("pthread_mutex_lock failed\n");
- abort(); /* Catastrophic error: mutex does not work correctly. */
- }
+ if (pthread_mutex_lock(mutex) != 0)
+ {
+ psTraceCore("pthread_mutex_lock failed\n");
+ abort(); /* Catastrophic error: mutex does not work correctly. */
+ }
}
void psUnlockMutex(psMutex_t *mutex)
{
- if (pthread_mutex_unlock(mutex) != 0) {
- psTraceCore("pthread_mutex_unlock failed\n");
- abort(); /* Catastrophic error: mutex does not work correctly. */
- }
+ if (pthread_mutex_unlock(mutex) != 0)
+ {
+ psTraceCore("pthread_mutex_unlock failed\n");
+ abort(); /* Catastrophic error: mutex does not work correctly. */
+ }
}
void psDestroyMutex(psMutex_t *mutex)
{
- pthread_mutex_destroy(mutex);
+ pthread_mutex_destroy(mutex);
}
-#endif /* USE_MULTITHREADING */
+# endif /* USE_MULTITHREADING */
/******************************************************************************/
/******************************************************************************/
/*
- ENTROPY FUNCTIONS
-*/
+ ENTROPY FUNCTIONS
+ */
/******************************************************************************/
-#define MAX_RAND_READS 1024
+# define MAX_RAND_READS 1024
static int32 urandfd = -1;
static int32 randfd = -1;
/*
- Module open and close
-*/
+ Module open and close
+ */
int osdepEntropyOpen(void)
{
/*
- Open /dev/random access non-blocking.
-*/
- if ((urandfd = open("/dev/urandom", O_RDONLY)) < 0) {
- psErrorInt("open of urandom failed %d\n", urandfd);
- return PS_PLATFORM_FAIL;
- }
+ Open /dev/random access non-blocking.
+ */
+ if ((urandfd = open("/dev/urandom", O_RDONLY)) < 0)
+ {
+ psErrorInt("open of urandom failed %d\n", urandfd);
+ return PS_PLATFORM_FAIL;
+ }
/*
- For platforms that don't have /dev/random, just assign it to urandom
-*/
- if ((randfd = open("/dev/random", O_RDONLY | O_NONBLOCK)) < 0) {
- randfd=urandfd;
- }
- return PS_SUCCESS;
+ For platforms that don't have /dev/random, just assign it to urandom
+ */
+ if ((randfd = open("/dev/random", O_RDONLY | O_NONBLOCK)) < 0)
+ {
+ randfd = urandfd;
+ }
+ return PS_SUCCESS;
}
void osdepEntropyClose(void)
{
- if (randfd != urandfd) {
- close(randfd);
- }
- close(urandfd);
+ if (randfd != urandfd)
+ {
+ close(randfd);
+ }
+ close(urandfd);
}
/*
- PScore Public API implementations
-*/
+ PScore Public API implementations
+ */
int32 psGetEntropy(unsigned char *bytes, uint32 size, void *userPtr)
{
/*
- Read from /dev/random non-blocking first, then from urandom if it would
- block. Also, handle file closure case and re-open.
-*/
- int32 rc, sanity, retry, readBytes;
- unsigned char *where = bytes;
+ Read from /dev/random non-blocking first, then from urandom if it would
+ block. Also, handle file closure case and re-open.
+ */
+ int32 rc, sanity, retry, readBytes;
+ unsigned char *where = bytes;
- sanity = retry = rc = readBytes = 0;
+ sanity = retry = rc = readBytes = 0;
- while (size) {
- if ((rc = read(randfd, where, size)) < 0 || sanity > MAX_RAND_READS) {
- if (errno == EINTR) {
- if (sanity > MAX_RAND_READS) {
- psTraceCore("psGetEntropy failed randfd sanity\n");
- return PS_PLATFORM_FAIL;
- }
- sanity++;
- continue;
- } else if (errno == EAGAIN) {
- break;
- } else if (errno == EBADF && retry == 0) {
- close(randfd);
- if ((randfd = open("/dev/random", O_RDONLY | O_NONBLOCK)) < 0) {
- break;
- }
- retry++;
- continue;
- } else {
- break;
- }
- }
- readBytes += rc;
- where += rc;
- size -= rc;
- }
+ while (size)
+ {
+ if ((rc = read(randfd, where, size)) < 0 || sanity > MAX_RAND_READS)
+ {
+ if (errno == EINTR)
+ {
+ if (sanity > MAX_RAND_READS)
+ {
+ psTraceCore("psGetEntropy failed randfd sanity\n");
+ return PS_PLATFORM_FAIL;
+ }
+ sanity++;
+ continue;
+ }
+ else if (errno == EAGAIN)
+ {
+ break;
+ }
+ else if (errno == EBADF && retry == 0)
+ {
+ close(randfd);
+ if ((randfd = open("/dev/random", O_RDONLY | O_NONBLOCK)) < 0)
+ {
+ break;
+ }
+ retry++;
+ continue;
+ }
+ else
+ {
+ break;
+ }
+ }
+ readBytes += rc;
+ where += rc;
+ size -= rc;
+ }
- sanity = retry = 0;
- while (size) {
- if ((rc = read(urandfd, where, size)) < 0 || sanity > MAX_RAND_READS) {
- if (errno == EINTR) {
- if (sanity > MAX_RAND_READS) {
- psTraceCore("psGetEntropy failed urandfd sanity\n");
- return PS_PLATFORM_FAIL;
- }
- sanity++;
- continue;
- } else if (errno == EBADF && retry == 0) {
- close(urandfd);
- if ((urandfd =
- open("/dev/urandom", O_RDONLY | O_NONBLOCK)) < 0) {
- psTraceCore("psGetEntropy failed urandom open\n");
- return PS_PLATFORM_FAIL;
- }
- retry++;
- continue;
- } else {
- psTraceIntCore("psGetEntropy fail errno %d\n", errno);
- return PS_PLATFORM_FAIL;
- }
- }
- readBytes += rc;
- where += rc;
- size -= rc;
- }
- return readBytes;
+ sanity = retry = 0;
+ while (size)
+ {
+ if ((rc = read(urandfd, where, size)) < 0 || sanity > MAX_RAND_READS)
+ {
+ if (errno == EINTR)
+ {
+ if (sanity > MAX_RAND_READS)
+ {
+ psTraceCore("psGetEntropy failed urandfd sanity\n");
+ return PS_PLATFORM_FAIL;
+ }
+ sanity++;
+ continue;
+ }
+ else if (errno == EBADF && retry == 0)
+ {
+ close(urandfd);
+ if ((urandfd =
+ open("/dev/urandom", O_RDONLY | O_NONBLOCK)) < 0)
+ {
+ psTraceCore("psGetEntropy failed urandom open\n");
+ return PS_PLATFORM_FAIL;
+ }
+ retry++;
+ continue;
+ }
+ else
+ {
+ psTraceIntCore("psGetEntropy fail errno %d\n", errno);
+ return PS_PLATFORM_FAIL;
+ }
+ }
+ readBytes += rc;
+ where += rc;
+ size -= rc;
+ }
+ return readBytes;
}
/******************************************************************************/
/******************************************************************************/
/*
- RAW TRACE FUNCTIONS
-*/
+ RAW TRACE FUNCTIONS
+ */
/******************************************************************************/
int osdepTraceOpen(void)
{
- return PS_SUCCESS;
+ return PS_SUCCESS;
}
void osdepTraceClose(void)
@@ -426,91 +471,109 @@ void osdepTraceClose(void)
void _psTrace(const char *msg)
{
- printf("%s", msg);
+ printf("%s", msg);
}
/* message should contain one %s, unless value is NULL */
void _psTraceStr(const char *message, const char *value)
{
- if (value) {
- printf(message, value);
- } else {
- printf("%s", message);
- }
+ if (value)
+ {
+ printf(message, value);
+ }
+ else
+ {
+ printf("%s", message);
+ }
}
/* message should contain one %d */
void _psTraceInt(const char *message, int32 value)
{
- printf(message, value);
+ printf(message, value);
}
/* message should contain one %p */
void _psTracePtr(const char *message, const void *value)
{
- printf(message, value);
+ printf(message, value);
}
/******************************************************************************/
-#ifdef HALT_ON_PS_ERROR
+# ifdef HALT_ON_PS_ERROR
/******************************************************************************/
/*
- POSIX - abort() on psError when HALT_ON_PS_ERROR enabled
-*/
+ POSIX - abort() on psError when HALT_ON_PS_ERROR enabled
+ */
void osdepBreak(void)
{
- abort();
+ abort();
}
-#endif /* HALT_ON_PS_ERROR */
+# endif /* HALT_ON_PS_ERROR */
-#ifdef MATRIX_USE_FILE_SYSTEM
+# ifdef MATRIX_USE_FILE_SYSTEM
/******************************************************************************/
/*
- FILE APIs
-*/
+ FILE APIs
+ */
/**
- Allocate a buffer and read in a file.
- @note Caller must free 'buf' parameter on success.
- Callers do not need to free buf on function failure.
-*/
-int32 psGetFileBuf(psPool_t *pool, const char *fileName, unsigned char **buf,
- int32 *bufLen)
+ Allocate a buffer and read in a file.
+ @note Caller must free 'buf' parameter on success.
+ Callers do not need to free buf on function failure.
+
+ Two variants: psGetFileBuf takes in a filename, psGetFileBufFp takes in
+ a pointer to an already opened FILE.
+ */
+int32 psGetFileBufFp(psPool_t *pool, FILE *fp, unsigned char **buf,
+ int32 *bufLen)
{
- FILE *fp;
- struct stat f_stat;
- size_t tmp = 0;
+ struct stat f_stat;
+ size_t tmp = 0;
- *bufLen = 0;
- *buf = NULL;
+ if (fstat(fileno(fp), &f_stat) != 0)
+ {
+ fclose(fp);
+ psTraceStrCore("Unable to stat %s\n", (char *) fileName);
+ return PS_PLATFORM_FAIL;
+ }
+ *buf = psMalloc(pool, (size_t) (f_stat.st_size + 1));
+ if (*buf == NULL)
+ {
+ fclose(fp);
+ return PS_MEM_FAIL;
+ }
+ memset(*buf, 0x0, (size_t) f_stat.st_size + 1);
- if (fileName == NULL) {
- return PS_ARG_FAIL;
- }
- if ((fp = fopen(fileName, "r")) == NULL) {
- psTraceStrCore("Unable to open %s\n", (char*)fileName);
- return PS_PLATFORM_FAIL;
- }
- if (fstat(fileno(fp), &f_stat) != 0) {
- fclose(fp);
- psTraceStrCore("Unable to stat %s\n", (char*)fileName);
- return PS_PLATFORM_FAIL;
- }
- *buf = psMalloc(pool, (size_t)(f_stat.st_size + 1));
- if (*buf == NULL) {
- fclose(fp);
- return PS_MEM_FAIL;
- }
- memset(*buf, 0x0, (size_t)f_stat.st_size + 1);
-
- while (((tmp = fread(*buf + *bufLen, sizeof(char), 512, fp)) > 0) &&
- (*bufLen < f_stat.st_size)) {
- *bufLen += (int32)tmp;
- }
- fclose(fp);
- return PS_SUCCESS;
+ while (((tmp = fread(*buf + *bufLen, sizeof(char), 512, fp)) > 0) &&
+ (*bufLen < f_stat.st_size))
+ {
+ *bufLen += (int32) tmp;
+ }
+ fclose(fp);
+ return PS_SUCCESS;
}
-#endif /* MATRIX_USE_FILE_SYSTEM */
-#endif /* POSIX */
+
+int32 psGetFileBuf(psPool_t *pool, const char *fileName, unsigned char **buf,
+ int32 *bufLen)
+{
+ FILE *fp;
+
+ *bufLen = 0;
+ *buf = NULL;
+
+ if (fileName == NULL)
+ {
+ return PS_ARG_FAIL;
+ }
+ if ((fp = fopen(fileName, "r")) == NULL)
+ {
+ psTraceStrCore("Unable to open %s\n", (char *) fileName);
+ return PS_PLATFORM_FAIL;
+ }
+ return psGetFileBufFp(pool, fp, buf, bufLen);
+}
+# endif /* MATRIX_USE_FILE_SYSTEM */
+#endif /* POSIX */
/******************************************************************************/
diff --git a/core/WIN32/osdep.c b/core/WIN32/osdep.c
index 5b202b6..a531c9b 100644
--- a/core/WIN32/osdep.c
+++ b/core/WIN32/osdep.c
@@ -1,57 +1,60 @@
/**
- * @file osdep.c
- * @version $Format:%h%d$
+ * @file osdep.c
+ * @version $Format:%h%d$
*
- * WIN32 platform PScore .
+ * WIN32 platform PScore .
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2016 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#include "../coreApi.h"
+#include "../osdep.h"
#ifdef WIN32
-#include
+# include
/******************************************************************************/
/* TIME */
-static LARGE_INTEGER hiresStart; /* zero-time */
-static LARGE_INTEGER hiresFreq; /* tics per second */
+static LARGE_INTEGER hiresStart; /* zero-time */
+static LARGE_INTEGER hiresFreq; /* tics per second */
int osdepTimeOpen(void)
{
- if (QueryPerformanceFrequency(&hiresFreq) == PS_FALSE) {
- return PS_FAILURE;
- }
- if (QueryPerformanceCounter(&hiresStart) == PS_FALSE) {
- return PS_FAILURE;
- }
- return PS_SUCCESS;
+ if (QueryPerformanceFrequency(&hiresFreq) == PS_FALSE)
+ {
+ return PS_FAILURE;
+ }
+ if (QueryPerformanceCounter(&hiresStart) == PS_FALSE)
+ {
+ return PS_FAILURE;
+ }
+ return PS_SUCCESS;
}
void osdepTimeClose(void)
@@ -61,47 +64,49 @@ void osdepTimeClose(void)
/* PScore Public API implementations */
int32 psGetTime(psTime_t *t, void *userPtr)
{
- psTime_t lt;
- __int64 diff;
- int32 d;
+ psTime_t lt;
+ __int64 diff;
+ int32 d;
- if (t == NULL) {
- QueryPerformanceCounter(<);
- diff = lt.QuadPart - hiresStart.QuadPart;
- d = (int32)((diff * 1000) / hiresFreq.QuadPart);
- return d;
- }
+ if (t == NULL)
+ {
+ QueryPerformanceCounter(<);
+ diff = lt.QuadPart - hiresStart.QuadPart;
+ d = (int32) ((diff * 1000) / hiresFreq.QuadPart);
+ return d;
+ }
- QueryPerformanceCounter(t);
- diff = t->QuadPart - hiresStart.QuadPart;
- d = (int32)((diff * 1000) / hiresFreq.QuadPart);
- return d;
+ QueryPerformanceCounter(t);
+ diff = t->QuadPart - hiresStart.QuadPart;
+ d = (int32) ((diff * 1000) / hiresFreq.QuadPart);
+ return d;
}
int32 psDiffMsecs(psTime_t then, psTime_t now, void *userPtr)
{
- __int64 diff;
+ __int64 diff;
- diff = now.QuadPart - then.QuadPart;
- return (int32)((diff*1000) / hiresFreq.QuadPart);
+ diff = now.QuadPart - then.QuadPart;
+ return (int32) ((diff * 1000) / hiresFreq.QuadPart);
}
int32 psCompareTime(psTime_t a, psTime_t b, void *userPtr)
{
- if (a.QuadPart <= b.QuadPart) {
- return 1;
- }
- return 0;
+ if (a.QuadPart <= b.QuadPart)
+ {
+ return 1;
+ }
+ return 0;
}
/******************************************************************************/
/* MUTEX */
-#ifdef USE_MULTITHREADING
+# ifdef USE_MULTITHREADING
int32_t osdepMutexOpen(void)
{
- return PS_SUCCESS;
+ return PS_SUCCESS;
}
void osdepMutexClose(void)
@@ -110,54 +115,57 @@ void osdepMutexClose(void)
int32_t psCreateMutex(psMutex_t *mutex, uint32_t flags)
{
- if (flags) {
- psErrorInt("psCreateMutex unsupported flag %u\n", flags);
- return PS_PLATFORM_FAIL;
- }
- InitializeCriticalSection(mutex); /* Does not return a value */
- return PS_SUCCESS;
+ if (flags)
+ {
+ psErrorInt("psCreateMutex unsupported flag %u\n", flags);
+ return PS_PLATFORM_FAIL;
+ }
+ InitializeCriticalSection(mutex); /* Does not return a value */
+ return PS_SUCCESS;
}
void psLockMutex(psMutex_t *mutex)
{
- EnterCriticalSection(mutex);
+ EnterCriticalSection(mutex);
}
void psUnlockMutex(psMutex_t *mutex)
{
- LeaveCriticalSection(mutex);
+ LeaveCriticalSection(mutex);
}
void psDestroyMutex(psMutex_t *mutex)
{
- DeleteCriticalSection(mutex);
+ DeleteCriticalSection(mutex);
}
-#endif /* USE_MULTITHREADING */
+# endif /* USE_MULTITHREADING */
/******************************************************************************/
/* ENTROPY */
-static HCRYPTPROV hProv; /* Crypto context for random bytes */
+static HCRYPTPROV hProv; /* Crypto context for random bytes */
int osdepEntropyOpen(void)
{
- if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
- CRYPT_VERIFYCONTEXT)) {
- return PS_FAILURE;
- }
- return PS_SUCCESS;
+ if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT))
+ {
+ return PS_FAILURE;
+ }
+ return PS_SUCCESS;
}
void osdepEntropyClose(void)
{
- CryptReleaseContext(hProv, 0);
+ CryptReleaseContext(hProv, 0);
}
int32 psGetEntropy(unsigned char *bytes, uint32 size, void *userPtr)
{
- if (CryptGenRandom(hProv, size, bytes)) {
- return size;
- }
- return PS_FAILURE;
+ if (CryptGenRandom(hProv, size, bytes))
+ {
+ return size;
+ }
+ return PS_FAILURE;
}
/******************************************************************************/
@@ -165,7 +173,7 @@ int32 psGetEntropy(unsigned char *bytes, uint32 size, void *userPtr)
int osdepTraceOpen(void)
{
- return PS_SUCCESS;
+ return PS_SUCCESS;
}
void osdepTraceClose(void)
@@ -174,104 +182,112 @@ void osdepTraceClose(void)
void _psTrace(const char *msg)
{
- printf("%s", msg);
+ printf("%s", msg);
}
/* Message should contain one %s, unless value is NULL */
void _psTraceStr(const char *message, const char *value)
{
- if (value) {
- printf(message, value);
- } else {
- printf("%s", message);
- }
+ if (value)
+ {
+ printf(message, value);
+ }
+ else
+ {
+ printf("%s", message);
+ }
}
/* message should contain one %d */
void _psTraceInt(const char *message, int32 value)
{
- printf(message, value);
+ printf(message, value);
}
/* message should contain one %p */
void _psTracePtr(const char *message, const void *value)
{
- printf(message, value);
+ printf(message, value);
}
/******************************************************************************/
/* DEBUGGING */
-#ifdef HALT_ON_PS_ERROR
+# ifdef HALT_ON_PS_ERROR
void osdepBreak(void)
{
- /* System halt on psError (and assert) */
- DebugBreak();
+ /* System halt on psError (and assert) */
+ DebugBreak();
}
-#endif /* HALT_ON_PS_ERROR */
+# endif /* HALT_ON_PS_ERROR */
/******************************************************************************/
/* FILE SYSTEM */
-#ifdef MATRIX_USE_FILE_SYSTEM
+# ifdef MATRIX_USE_FILE_SYSTEM
/*
- Memory info:
- Caller must free 'buf' parameter on success
- Callers do not need to free buf on function failure
-*/
+ Memory info:
+ Caller must free 'buf' parameter on success
+ Callers do not need to free buf on function failure
+ */
int32 psGetFileBuf(psPool_t *pool, const char *fileName, unsigned char **buf,
- int32 *bufLen)
+ int32 *bufLen)
{
- DWORD dwAttributes;
- HANDLE hFile;
- int32 size;
- DWORD tmp = 0;
+ DWORD dwAttributes;
+ HANDLE hFile;
+ int32 size;
+ DWORD tmp = 0;
- *bufLen = 0;
- *buf = NULL;
+ *bufLen = 0;
+ *buf = NULL;
- dwAttributes = GetFileAttributesA(fileName);
- if (dwAttributes != 0xFFFFFFFF && dwAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- psTraceStrCore("Unable to find %s\n", (char*)fileName);
- return PS_PLATFORM_FAIL;
- }
+ dwAttributes = GetFileAttributesA(fileName);
+ if (dwAttributes != 0xFFFFFFFF && dwAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ psTraceStrCore("Unable to find %s\n", (char *) fileName);
+ return PS_PLATFORM_FAIL;
+ }
- /* Open an existing file read-only (we are not actually creating) */
- if ((hFile = CreateFileA(fileName, GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) {
- psTraceStrCore("Unable to open %s\n", (char*)fileName);
- return PS_PLATFORM_FAIL;
- }
+ /* Open an existing file read-only (we are not actually creating) */
+ if ((hFile = CreateFileA(fileName, GENERIC_READ,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
+ {
+ psTraceStrCore("Unable to open %s\n", (char *) fileName);
+ return PS_PLATFORM_FAIL;
+ }
- size = GetFileSize(hFile, NULL);
+ size = GetFileSize(hFile, NULL);
- *buf = psMalloc(pool, size + 1);
- if (*buf == NULL) {
- CloseHandle(hFile);
- return PS_MEM_FAIL;
- }
- memset(*buf, 0x0, size + 1);
+ *buf = psMalloc(pool, size + 1);
+ if (*buf == NULL)
+ {
+ CloseHandle(hFile);
+ return PS_MEM_FAIL;
+ }
+ memset(*buf, 0x0, size + 1);
- while (*bufLen < size) {
- if (ReadFile(hFile, *buf + *bufLen,
- (size - *bufLen > 512 ? 512 : size - *bufLen),
- &tmp, NULL) == FALSE) {
+ while (*bufLen < size)
+ {
+ if (ReadFile(hFile, *buf + *bufLen,
+ (size - *bufLen > 512 ? 512 : size - *bufLen),
+ &tmp, NULL) == FALSE)
+ {
- psFree(*buf, pool);
- psTraceStrCore("Unable to read %s\n", (char*)fileName);
- CloseHandle(hFile);
- return PS_PLATFORM_FAIL;
- }
- *bufLen += (int32)tmp;
- }
+ psFree(*buf, pool);
+ psTraceStrCore("Unable to read %s\n", (char *) fileName);
+ CloseHandle(hFile);
+ return PS_PLATFORM_FAIL;
+ }
+ *bufLen += (int32) tmp;
+ }
- CloseHandle(hFile);
- return PS_SUCCESS;
+ CloseHandle(hFile);
+ return PS_SUCCESS;
}
-#endif /* MATRIX_USE_FILE_SYSTEM */
+# endif /* MATRIX_USE_FILE_SYSTEM */
-#endif /* WIN32 */
+#endif /* WIN32 */
/******************************************************************************/
diff --git a/core/coreApi.h b/core/coreApi.h
index 90714b2..ce98a17 100644
--- a/core/coreApi.h
+++ b/core/coreApi.h
@@ -1,164 +1,148 @@
/**
- * @file coreApi.h
- * @version $Format:%h%d$
+ * @file coreApi.h
+ * @version $Format:%h%d$
*
- * Prototypes for the Matrix core public APIs.
+ * Prototypes for the Matrix core public APIs.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_COREAPI
-#define _h_PS_COREAPI
+# define _h_PS_COREAPI
-#ifdef __cplusplus
+# ifdef __cplusplus
extern "C" {
-#endif
+# endif
-#ifdef MATRIX_CONFIGURATION_INCDIR_FIRST
-#include /* Must be first included */
-#else
-#include "coreConfig.h" /* Must be first included */
-#endif
-#include "osdep.h"
-#include "list.h"
-#include "psmalloc.h"
+# ifdef MATRIX_CONFIGURATION_INCDIR_FIRST
+# include /* Must be first included */
+# else
+# include "coreConfig.h" /* Must be first included */
+# endif
+# include "osdep-types.h"
+# include "list.h"
+# include "psmalloc.h"
/******************************************************************************/
/*
- psCore helper macros: for communicating with compiler
- These macros allow to remove spurious warnings.
-*/
-
-/* Tell compiler a variable is intended that it can be set, but not used.
- (The variable is for debugging, future extension or used in some
- conditionally disabled/unifdeffed branches of execution). */
-#define PS_VARIABLE_SET_BUT_UNUSED(x) do { (void)(x); } while(0)
-
-/* Tell compiler a variable is intended that it can be unused.
- This is for compilers which detect variables that are not set.
- (The variable is for debugging, future extension or used in some
- conditionally disabled/unifdeffed branches of execution). */
-#define PS_VARIABLE_UNUSED(x) do { (void)(x); } while(0)
-
-/* Tell compiler a function parameter is intended that it can be unused.
- This is for compilers which detect parameters that are not used.
- (The parameter is for debugging, future extension or used in some
- conditionally disabled/unifdeffed branches of execution). */
-#define PS_PARAMETER_UNUSED(x) do { (void)(x); } while(0)
+ psCore return codes
+ */
+# define PS_CORE_IS_OPEN 1
/******************************************************************************/
/*
- psCore return codes
-*/
-#define PS_CORE_IS_OPEN 1
+ Universal return codes
+ */
+# define PS_SUCCESS 0
+# define PS_FAILURE -1
+# define PS_FAIL PS_FAILURE/* Just another name */
-/******************************************************************************/
-/*
- Universal return codes
-*/
-#define PS_SUCCESS 0
-#define PS_FAILURE -1
-#define PS_FAIL PS_FAILURE /* Just another name */
-
-/* NOTE: Failure return codes MUST be < 0 */
-/* NOTE: The range for core error codes should be between -2 and -29 */
-#define PS_ARG_FAIL -6 /* Failure due to bad function param */
-#define PS_PLATFORM_FAIL -7 /* Failure as a result of system call error */
-#define PS_MEM_FAIL -8 /* Failure to allocate requested memory */
-#define PS_LIMIT_FAIL -9 /* Failure on sanity/limit tests */
-#define PS_UNSUPPORTED_FAIL -10 /* Unimplemented feature error */
-#define PS_DISABLED_FEATURE_FAIL -11 /* Incorrect #define toggle for feature */
-#define PS_PROTOCOL_FAIL -12 /* A protocol error occurred */
-#define PS_TIMEOUT_FAIL -13 /* A timeout occurred and MAY be an error */
-#define PS_INTERRUPT_FAIL -14 /* An interrupt occurred and MAY be an error */
-#define PS_PENDING -15 /* In process. Not necessarily an error */
-#define PS_EAGAIN -16 /* Try again later. Not necessarily an error */
-#define PS_OUTPUT_LENGTH -17 /* Output length negotiation:
- output buffer is too small. */
-#define PS_HOSTNAME_RESOLUTION -18 /* Cannot resolve host name. */
-#define PS_CONNECT -19 /* Cannot connect to remote host. */
-#define PS_TRUE 1
-#define PS_FALSE 0
+/* NOTE: Failure return codes MUST be < 0 */
+/* NOTE: The range for core error codes should be between -2 and -29 */
+# define PS_ARG_FAIL -6 /* Failure due to bad function param */
+# define PS_PLATFORM_FAIL -7 /* Failure as a result of system call error */
+# define PS_MEM_FAIL -8 /* Failure to allocate requested memory */
+# define PS_LIMIT_FAIL -9 /* Failure on sanity/limit tests */
+# define PS_UNSUPPORTED_FAIL -10 /* Unimplemented feature error */
+# define PS_DISABLED_FEATURE_FAIL -11 /* Incorrect #define toggle for feature */
+# define PS_PROTOCOL_FAIL -12 /* A protocol error occurred */
+# define PS_TIMEOUT_FAIL -13 /* A timeout occurred and MAY be an error */
+# define PS_INTERRUPT_FAIL -14 /* An interrupt occurred and MAY be an error */
+# define PS_PENDING -15 /* In process. Not necessarily an error */
+# define PS_EAGAIN -16 /* Try again later. Not necessarily an error */
+# define PS_OUTPUT_LENGTH -17 /* Output length negotiation:
+ output buffer is too small. */
+# define PS_HOSTNAME_RESOLUTION -18 /* Cannot resolve host name. */
+# define PS_CONNECT -19 /* Cannot connect to remote host. */
+# define PS_INSECURE_PROTOCOL -20 /* The operation needs to use insecure protocol.
+ The caller needs to accept use of insecure
+ protocol. */
+# define PS_VERIFICATION_FAILED -21 /* Signature verification failed. */
+# define PS_TRUE 1
+# define PS_FALSE 0
/******************************************************************************/
/* Public structures */
/******************************************************************************/
/*
- psBuf_t
- Empty buffer:
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- |.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|
- ^
- \end
- \start
- \buf
- size = 16
- len = (end - start) = 0
+ psBuf_t
+ Empty buffer:
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ |.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|.|
+ ^
+ \end
+ \start
+ \buf
+ size = 16
+ len = (end - start) = 0
- Buffer with data:
+ Buffer with data:
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- |.|.|a|b|c|d|e|f|g|h|i|j|.|.|.|.|
- ^ ^ ^
- | | \end
- | \start
- \buf
- size = 16
- len = (end - start) = 10
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ |.|.|a|b|c|d|e|f|g|h|i|j|.|.|.|.|
+ ^ ^ ^
+ | | \end
+ | \start
+ \buf
+ size = 16
+ len = (end - start) = 10
- Read from start pointer
- Write to end pointer
- Free from buf pointer
-*/
-typedef struct {
- unsigned char *buf; /* Pointer to the start of the buffer */
- unsigned char *start; /* Pointer to start of valid data */
- unsigned char *end; /* Pointer to first byte of invalid data */
- int32 size; /* Size of buffer in bytes */
+ Read from start pointer
+ Write to end pointer
+ Free from buf pointer
+ */
+typedef struct
+{
+ unsigned char *buf; /* Pointer to the start of the buffer */
+ unsigned char *start; /* Pointer to start of valid data */
+ unsigned char *end; /* Pointer to first byte of invalid data */
+ int32 size; /* Size of buffer in bytes */
} psBuf_t;
/* Dynamically allocated automatically resizing psBuf_t. */
struct psDynBuf;
typedef struct psDynBuf psDynBuf_t;
-struct psDynBuf {
+struct psDynBuf
+{
psBuf_t buf;
psPool_t *pool;
int err;
psDynBuf_t *master;
};
-#define PS_DYNBUF_GROW 256 /* Usual grow amount. */
+# define PS_DYNBUF_GROW 256 /* Usual grow amount. */
/* Buffer for parsing input. */
struct psParseBuf;
typedef struct psParseBuf psParseBuf_t;
/* The contents of parsebuf are exactly the same than psDynBuf_t.
this allows them to share some of implementation. */
-struct psParseBuf {
+struct psParseBuf
+{
psBuf_t buf;
psPool_t *pool;
int err;
@@ -170,31 +154,31 @@ struct psParseBuf {
extern psPool_t * const psStaticAllocationsPool;
/* Function definitions for Static and Dynamic Buffer API. */
-#include "psbuf.h"
+# include "psbuf.h"
/******************************************************************************/
-#ifdef MATRIX_USE_FILE_SYSTEM
- #define FILESYSTEM_CONFIG_STR "Y"
-#else
- #define FILESYSTEM_CONFIG_STR "N"
-#endif
- #define PSMALLOC_CONFIG_STR "N"
-#ifdef USE_MULTITHREADING
- #define MULTITHREAD_CONFIG_STR "Y"
-#else
- #define MULTITHREAD_CONFIG_STR "N"
-#endif
+# ifdef MATRIX_USE_FILE_SYSTEM
+# define FILESYSTEM_CONFIG_STR "Y"
+# else
+# define FILESYSTEM_CONFIG_STR "N"
+# endif
+# define PSMALLOC_CONFIG_STR "N"
+# ifdef USE_MULTITHREADING
+# define MULTITHREAD_CONFIG_STR "Y"
+# else
+# define MULTITHREAD_CONFIG_STR "N"
+# endif
-#define PSCORE_CONFIG \
- "Y" \
- FILESYSTEM_CONFIG_STR \
- PSMALLOC_CONFIG_STR \
- MULTITHREAD_CONFIG_STR
+# define PSCORE_CONFIG \
+ "Y" \
+ FILESYSTEM_CONFIG_STR \
+ PSMALLOC_CONFIG_STR \
+ MULTITHREAD_CONFIG_STR
/******************************************************************************/
/* Public APIs */
- #include
+# include
/******************************************************************************/
/* struct tm is standard for representing broken-down time in C89, C99 and
@@ -206,177 +190,189 @@ typedef struct tm psBrokenDownTime_t;
*/
typedef time_t psTimeSeconds_t;
-PSPUBLIC int32 psCoreOpen(const char *config);
-PSPUBLIC void psCoreClose(void);
-PSPUBLIC void psBurnStack(uint32 len);
-PSPUBLIC int32 memcmpct(const void *s1, const void *s2, size_t len);
+PSPUBLIC int32 psCoreOpen(const char *config);
+PSPUBLIC void psCoreClose(void);
+PSPUBLIC void psBurnStack(uint32 len);
+PSPUBLIC int32 memcmpct(const void *s1, const void *s2, size_t len);
-PSPUBLIC void psFreeAndClear(void *ptrptr, psPool_t *pool);
+PSPUBLIC void psFreeAndClear(void *ptrptr, psPool_t *pool);
/******************************************************************************/
/*
- Public interface to functionality defined by functions in C89/C99 standards.
+ Public interface to functionality defined by functions in C89/C99 standards.
These function may be substituted with OS/psdep.c in nonstandard
systems.
Return broken-down time similar to gmtime(&time(NULL)). The function allows
offset in seconds.
-*/
+ */
PSPUBLIC int32 psGetBrokenDownGMTime(psBrokenDownTime_t *t,
- int offset);
+ int offset);
/* Add specified value to broken down time. */
PSPUBLIC int32 psBrokenDownTimeAdd(psBrokenDownTime_t *res, int32 offset);
-#define PS_BROKENDOWN_TIME_STR_LEN 16 /* Good until year 9999. */
+# define PS_BROKENDOWN_TIME_STR_LEN 16 /* Good until year 9999. */
+# define PS_BROKENDOWN_TIME_IMPORT_LEN 12 /* Minimum proper time import format
+ length. */
PSPUBLIC int32 psBrokenDownTimeStr(const psBrokenDownTime_t *t1,
- char (*string)[PS_BROKENDOWN_TIME_STR_LEN]);
-#define PS_BROKENDOWN_TIME_IMPORT_STRICT_ZULU 1 /* Require Z as timezone. */
-#define PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR 2 /* Use two digit year for
- range 1950-2049. */
+ char (*string)[PS_BROKENDOWN_TIME_STR_LEN]);
+# define PS_BROKENDOWN_TIME_IMPORT_STRICT_ZULU 1 /* Require Z as timezone. */
+# define PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR 2 /* Use two digit year for
+ range 1950-2049. */
PSPUBLIC int32 psBrokenDownTimeImportSeconds(psBrokenDownTime_t *t,
- psTimeSeconds_t s);
+ psTimeSeconds_t s);
PSPUBLIC int32 psBrokenDownTimeImport(
- psBrokenDownTime_t *t,
- const char *string, size_t time_string_len,
- unsigned int opts);
+ psBrokenDownTime_t *t,
+ const char *string, size_t time_string_len,
+ unsigned int opts);
PSPUBLIC int psBrokenDownTimeCmp(const psBrokenDownTime_t *t1,
- const psBrokenDownTime_t *t2);
+ const psBrokenDownTime_t *t2);
/******************************************************************************/
/*
- Public interface to OS-dependant core functionality
+ Public interface to OS-dependant core functionality
- OS/osdep.c must implement the below functions
-*/
-PSPUBLIC int32 psGetEntropy(unsigned char *bytes, uint32 size,
- void *userPtr);
+ OS/osdep.c must implement the below functions
+ */
+PSPUBLIC int32 psGetEntropy(unsigned char *bytes, uint32 size,
+ void *userPtr);
-PSPUBLIC int32 psGetTime(psTime_t *t, void *userPtr);
-PSPUBLIC int32 psDiffMsecs(psTime_t then, psTime_t now, void *userPtr);
+PSPUBLIC int32 psGetTime(psTime_t *t, void *userPtr);
+PSPUBLIC int32 psDiffMsecs(psTime_t then, psTime_t now, void *userPtr);
/* psCompareTime is no longer used */
-PSPUBLIC int32 psCompareTime(psTime_t a, psTime_t b, void *userPtr);
+PSPUBLIC int32 psCompareTime(psTime_t a, psTime_t b, void *userPtr);
-#ifdef MATRIX_USE_FILE_SYSTEM
-PSPUBLIC int32 psGetFileBuf(psPool_t *pool, const char *fileName,
- unsigned char **buf, int32 *bufLen);
-#endif /* MATRIX_USE_FILE_SYSTEM */
+# ifdef MATRIX_USE_FILE_SYSTEM
+# ifdef USE_POSIX
+PSPUBLIC int32 psGetFileBufFp(psPool_t *pool, FILE *fp,
+ unsigned char **buf, int32 *bufLen);
+# endif /* USE_POSIX */
+PSPUBLIC int32 psGetFileBuf(psPool_t *pool, const char *fileName,
+ unsigned char **buf, int32 *bufLen);
+# endif /* MATRIX_USE_FILE_SYSTEM */
-#ifdef USE_MULTITHREADING
-#define PS_SHARED 0x1
-PSPUBLIC int32_t psCreateMutex(psMutex_t *mutex, uint32_t flags);
-PSPUBLIC void psLockMutex(psMutex_t *mutex);
-PSPUBLIC void psUnlockMutex(psMutex_t *mutex);
-PSPUBLIC void psDestroyMutex(psMutex_t *mutex);
-#else
+# ifdef USE_MULTITHREADING
+# define PS_SHARED 0x1
+PSPUBLIC int32_t psCreateMutex(psMutex_t *mutex, uint32_t flags);
+PSPUBLIC void psLockMutex(psMutex_t *mutex);
+PSPUBLIC void psUnlockMutex(psMutex_t *mutex);
+PSPUBLIC void psDestroyMutex(psMutex_t *mutex);
+# else
/** @note These are defines rather than inline functions because it allows
-the caller to not allocate a mutex that will never be used. */
-#define psCreateMutex(A, B) (PS_SUCCESS)
-#define psLockMutex(A) do { } while(0)
-#define psUnlockMutex(A) do { } while(0)
-#define psDestroyMutex(A)
-#endif /* USE_MULTITHREADING */
+ the caller to not allocate a mutex that will never be used. */
+# define psCreateMutex(A, B) (PS_SUCCESS)
+# define psLockMutex(A) do { } while (0)
+# define psUnlockMutex(A) do { } while (0)
+# define psDestroyMutex(A)
+# endif /* USE_MULTITHREADING */
/******************************************************************************/
/*
- Internal list helpers
-*/
+ Internal list helpers
+ */
extern int32 psParseList(psPool_t *pool, char *list, const char separator,
- psList_t **items);
+ psList_t **items);
extern void psFreeList(psList_t *list, psPool_t *pool);
/* Identifiers to describe type of string contained in char or
unsigned char array. */
-typedef enum {
- /* Note: The values intentionally match ASN.1 BER/DER string type tags. */
- PS_STRING_UTF8_STRING = 12,
- PS_STRING_NUMERIC_STRING = 18,
- PS_STRING_PRINTABLE_STRING = 19,
- PS_STRING_TELETEX_STRING = 20,
- PS_STRING_VIDEOTEX_STRING = 21,
- PS_STRING_IA5_STRING = 22,
- PS_STRING_GRAPHIC_STRING = 25,
- PS_STRING_VISIBLE_STRING = 26,
- PS_STRING_GENERAL_STRING = 27,
- PS_STRING_UNIVERSAL_STRING = 28,
- PS_STRING_CHARACTER_STRING = 29,
- PS_STRING_BMP_STRING = 30,
- PS_STRING_CHAR_STRING = 256, /* Input is represented as C string. */
- PS_STRING_WCHAR_STRING = 257, /* Input is represented as wchar_t string. */
+typedef enum
+{
+ /* Note: The values intentionally match ASN.1 BER/DER string type tags. */
+ PS_STRING_UTF8_STRING = 12,
+ PS_STRING_NUMERIC_STRING = 18,
+ PS_STRING_PRINTABLE_STRING = 19,
+ PS_STRING_TELETEX_STRING = 20,
+ PS_STRING_VIDEOTEX_STRING = 21,
+ PS_STRING_IA5_STRING = 22,
+ PS_STRING_GRAPHIC_STRING = 25,
+ PS_STRING_VISIBLE_STRING = 26,
+ PS_STRING_GENERAL_STRING = 27,
+ PS_STRING_UNIVERSAL_STRING = 28,
+ PS_STRING_CHARACTER_STRING = 29,
+ PS_STRING_BMP_STRING = 30,
+ PS_STRING_CHAR_STRING = 256, /* Input is represented as C string. */
+ PS_STRING_WCHAR_STRING = 257, /* Input is represented as wchar_t string. */
} psStringType_t;
/* Option for strictly checking input to UTF8 String.
The option is not currently implemented, and the function
psGetUtf8String() will always fail if you attempt to use the option. */
-#define PS_STRING_STRICT 1
+# define PS_STRING_STRICT 1
/* Uses sequence \0\0 as terminator for string. */
-#define PS_STRING_DUAL_NIL 2
+# define PS_STRING_DUAL_NIL 2
/******************************************************************************/
/*
- Helper function for usual string conversions.
- The current version allows conversion of
+ Helper function for usual string conversions.
+ The current version allows conversion of
PS_STRING_NUMERIC_STRING, PS_STRING_PRINTABLE_STRING, PS_STRING_BMP_STRING
- to UTF-8. In case conversion succeeds with PS_SUCCESS, *output will
- point to a newly allocated string. The allocated string needs to be freed
- with psFree(). The string will have terminating \0.
- *output_len will be written string length not counting terminating \0.
- output_len can be provided as NULL if user wants to use functions like
- strlen() to obtain length of the string instead.
-*/
+ to UTF-8. In case conversion succeeds with PS_SUCCESS, *output will
+ point to a newly allocated string. The allocated string needs to be freed
+ with psFree(). The string will have terminating \0.
+ * output_len will be written string length not counting terminating \0.
+ output_len can be provided as NULL if user wants to use functions like
+ strlen() to obtain length of the string instead.
+ */
PSPUBLIC int32 psToUtf8String(psPool_t *pool,
- const unsigned char *input, size_t input_len,
- psStringType_t input_type,
- unsigned char **output, size_t *output_len,
- int opts);
+ const unsigned char *input, size_t input_len,
+ psStringType_t input_type,
+ unsigned char **output, size_t *output_len,
+ int opts);
/******************************************************************************/
/*
- Statistics helpers
-*/
+ Statistics helpers
+ */
/** Number of samples to store take for running average. */
-#define STAT_AVG_SAMPLES 32
+# define STAT_AVG_SAMPLES 32
-typedef struct {
- uint32_t h; /**< High water */
- uint32_t a[STAT_AVG_SAMPLES]; /**< Values */
- uint32_t atot; /**< Running total of a[] values */
- uint16_t ai; /**< Most recent index into a[] */
- uint16_t an; /**< Current number of valid entries in a[] */
+typedef struct
+{
+ uint32_t h; /**< High water */
+ uint32_t a[STAT_AVG_SAMPLES]; /**< Values */
+ uint32_t atot; /**< Running total of a[] values */
+ uint16_t ai; /**< Most recent index into a[] */
+ uint16_t an; /**< Current number of valid entries in a[] */
} psAvgStat_t;
__inline static void STAT_INC_AVG(psAvgStat_t *s, uint32_t val)
{
- /* Update high water */
- if (val > s->h) {
- s->h = val;
- }
- if (s->an < STAT_AVG_SAMPLES) {
- /* Update total number of stats, if not at max */
- s->an++;
- } else {
- /* Subtract the oldest value from the running total, if we're replacing */
- s->atot -= s->a[s->ai];
- }
- /* Point to next entry, replace it and increment running total */
- s->ai = (s->ai + 1) % STAT_AVG_SAMPLES;
- s->a[s->ai] = val;
- s->atot += val;
+ /* Update high water */
+ if (val > s->h)
+ {
+ s->h = val;
+ }
+ if (s->an < STAT_AVG_SAMPLES)
+ {
+ /* Update total number of stats, if not at max */
+ s->an++;
+ }
+ else
+ {
+ /* Subtract the oldest value from the running total, if we're replacing */
+ s->atot -= s->a[s->ai];
+ }
+ /* Point to next entry, replace it and increment running total */
+ s->ai = (s->ai + 1) % STAT_AVG_SAMPLES;
+ s->a[s->ai] = val;
+ s->atot += val;
}
__inline static uint32_t STAT_AVG(psAvgStat_t *s)
{
- return (s->atot / s->an);
+ return s->atot / s->an;
}
__inline static uint32_t STAT_HIGH(psAvgStat_t *s)
{
- return s->h;
+ return s->h;
}
-#ifdef __cplusplus
+# ifdef __cplusplus
}
-#endif
+# endif
#endif /* _h_PS_COREAPI */
/******************************************************************************/
diff --git a/core/coreConfig.h b/core/coreConfig.h
deleted file mode 100644
index 1dc1ecf..0000000
--- a/core/coreConfig.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * @file coreConfig.h
- * @version $Format:%h%d$
- *
- * Configuration settings for Matrix core module.
- */
-/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
- *
- * The latest version of this code is available at http://www.matrixssl.org
- *
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
- *
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
- */
-/******************************************************************************/
-
-#ifndef _h_PS_CORECONFIG
-#define _h_PS_CORECONFIG
-
-
-/******************************************************************************/
-/* Configurable features */
-/******************************************************************************/
-/**
- Enable various levels of trace.
- When these option is turned off, messages are silently
- discarded and their text does not take space in the binary image.
-*/
-//#define USE_CORE_TRACE
-#ifndef NO_CORE_ERROR
- #define USE_CORE_ERROR
-#endif
-#ifndef NO_CORE_ASSERT
- #define USE_CORE_ASSERT
-#endif
-
-/**
- If enabled, calls to the psError set of APIs will perform a platform
- abort on the exeutable to aid in debugging.
-*/
-#ifdef DEBUG
-//#define HALT_ON_PS_ERROR /* NOT RECOMMENDED FOR PRODUCTION BUILDS */
-#endif
-
-/**
- Include the psCoreOsdepMutex family of APIs
-
- @note If intending to compile crypto-cl, then this flag should
- always be set.
-*/
-#ifndef NO_MULTITHREADING
-#define USE_MULTITHREADING
-#endif /* NO_MULTITHREADING */
-
-/**
- Include the psNetwork family of APIs
-
- These APIs allow simple high-level socket api.
- */
-#define USE_PS_NETWORKING
-
-#endif /* _h_PS_CORECONFIG */
-
-/******************************************************************************/
-
diff --git a/core/corelib.c b/core/corelib.c
index d648a15..c23e1da 100644
--- a/core/corelib.c
+++ b/core/corelib.c
@@ -1,38 +1,40 @@
/**
- * @file corelib.c
- * @version $Format:%h%d$
+ * @file corelib.c
+ * @version $Format:%h%d$
*
- * Open and Close APIs and utilities for Matrix core library.
+ * Open and Close APIs and utilities for Matrix core library.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#include "coreApi.h"
+#include "osdep.h"
+#include "psUtil.h"
#ifdef USE_MULTITHREADING
/* A mutex for concurrency control of functions implemented in this file.
@@ -42,766 +44,900 @@ static psMutex_t corelibMutex;
/******************************************************************************/
/*
- Open (initialize) the Core module
- The config param should always be passed as:
- PSCORE_CONFIG
-*/
+ Open (initialize) the Core module
+ The config param should always be passed as:
+ PSCORE_CONFIG
+ */
static char g_config[32] = "N";
/******************************************************************************/
int32 psCoreOpen(const char *config)
{
- if (*g_config == 'Y') {
- return PS_CORE_IS_OPEN;
- }
- strncpy(g_config, PSCORE_CONFIG, sizeof(g_config) - 1);
- if (strncmp(g_config, config, strlen(PSCORE_CONFIG)) != 0) {
- psErrorStr( "Core config mismatch.\n" \
- "Library: " PSCORE_CONFIG\
- "\nCurrent: %s\n", config);
- return -1;
- }
+ if (*g_config == 'Y')
+ {
+ return PS_CORE_IS_OPEN;
+ }
+ strncpy(g_config, PSCORE_CONFIG, sizeof(g_config) - 1);
+ if (strncmp(g_config, config, strlen(PSCORE_CONFIG)) != 0)
+ {
+ psErrorStr( "Core config mismatch.\n" \
+ "Library: " PSCORE_CONFIG \
+ "\nCurrent: %s\n", config);
+ return -1;
+ }
- if (osdepTimeOpen() < 0) {
- psTraceCore("osdepTimeOpen failed\n");
- return PS_FAILURE;
- }
- if (osdepEntropyOpen() < 0) {
- psTraceCore("osdepEntropyOpen failed\n");
- osdepTimeClose();
- return PS_FAILURE;
- }
+ if (osdepTimeOpen() < 0)
+ {
+ psTraceCore("osdepTimeOpen failed\n");
+ return PS_FAILURE;
+ }
+ if (osdepEntropyOpen() < 0)
+ {
+ psTraceCore("osdepEntropyOpen failed\n");
+ osdepTimeClose();
+ return PS_FAILURE;
+ }
#ifdef USE_MULTITHREADING
- if (osdepMutexOpen() < 0) {
- psTraceCore("osdepMutexOpen failed\n");
- osdepEntropyClose();
- osdepTimeClose();
- return PS_FAILURE;
- }
- if (psCreateMutex(&corelibMutex, 0) < 0) {
- psTraceCore("psCreateMutex failed\n");
- osdepMutexClose();
- osdepEntropyClose();
- osdepTimeClose();
- return PS_FAILURE;
- }
+ if (osdepMutexOpen() < 0)
+ {
+ psTraceCore("osdepMutexOpen failed\n");
+ osdepEntropyClose();
+ osdepTimeClose();
+ return PS_FAILURE;
+ }
+ if (psCreateMutex(&corelibMutex, 0) < 0)
+ {
+ psTraceCore("psCreateMutex failed\n");
+ osdepMutexClose();
+ osdepEntropyClose();
+ osdepTimeClose();
+ return PS_FAILURE;
+ }
#endif /* USE_MULTITHREADING */
- return PS_SUCCESS;
+ return PS_SUCCESS;
}
/******************************************************************************/
void psCoreClose(void)
{
- if (*g_config == 'Y') {
- *g_config = 'N';
+ if (*g_config == 'Y')
+ {
+ *g_config = 'N';
#ifdef USE_MULTITHREADING
- psDestroyMutex(&corelibMutex);
- osdepMutexClose();
-#endif /* USE_MULTITHREADING */
+ psDestroyMutex(&corelibMutex);
+ osdepMutexClose();
+#endif /* USE_MULTITHREADING */
- osdepEntropyClose();
+ osdepEntropyClose();
- osdepTimeClose();
- }
+ osdepTimeClose();
+ }
}
/******************************************************************************/
/**
- Constant time memory comparison - like memcmp but w/o data dependent branch.
- @security SECURITY - Should be used when comparing values that use or have
- been derived or have been decrypted/encrypted/signed from secret information.
+ Constant time memory comparison - like memcmp but w/o data dependent branch.
+ @security SECURITY - Should be used when comparing values that use or have
+ been derived or have been decrypted/encrypted/signed from secret information.
- @param[in] s1 Pointer to first buffer to compare
- @param[in] s2 Pointer to first buffer to compare
- @param[in] len number of bytes to compare in s1 and s2
- @return 0 on successful match, nonzero on failure.
-*/
+ @param[in] s1 Pointer to first buffer to compare
+ @param[in] s2 Pointer to first buffer to compare
+ @param[in] len number of bytes to compare in s1 and s2
+ @return 0 on successful match, nonzero on failure.
+ */
int32 memcmpct(const void *s1, const void *s2, size_t len)
{
- int xor = 0;
+ int xor = 0;
- while(len > 0) {
- len--;
- xor |= ((unsigned char *)s1)[len] ^ ((unsigned char *)s2)[len];
- }
- return xor;
+ while (len > 0)
+ {
+ len--;
+ xor |= ((unsigned char *) s1)[len] ^ ((unsigned char *) s2)[len];
+ }
+ return xor;
}
/******************************************************************************/
/*
- ERROR FUNCTIONS
- Tap into platform trace and break execution if DEBUG compile
+ ERROR FUNCTIONS
+ Tap into platform trace and break execution if DEBUG compile
- Modules should tie themselves to these low levels
- with compile-time defines
-*/
+ Modules should tie themselves to these low levels
+ with compile-time defines
+ */
void _psError(const char *msg)
{
- _psTrace(msg);
- _psTrace("\n");
+ _psTrace(msg);
+ _psTrace("\n");
#ifdef HALT_ON_PS_ERROR
- osdepBreak();
+ osdepBreak();
#endif
}
void _psErrorInt(const char *msg, int32 val)
{
- _psTraceInt(msg, val);
- _psTrace("\n");
+ _psTraceInt(msg, val);
+ _psTrace("\n");
#ifdef HALT_ON_PS_ERROR
- osdepBreak();
+ osdepBreak();
#endif
}
void _psErrorStr(const char *msg, const char *val)
{
- _psTraceStr(msg, val);
- _psTrace("\n");
+ _psTraceStr(msg, val);
+ _psTrace("\n");
#ifdef HALT_ON_PS_ERROR
- osdepBreak();
+ osdepBreak();
#endif
}
/*
- copy 'len' bytes from 'b' to 's', converting all to printable characters
-*/
+ copy 'len' bytes from 'b' to 's', converting all to printable characters
+ */
static void mem2str(char *s, const unsigned char *b, uint32 len)
{
- for (; len > 0; len--) {
- if (*b > 31 && *b < 127) {
- *s = *b;
- } else {
- *s = '.';
- }
- b++;
- s++;
- }
+ for (; len > 0; len--)
+ {
+ if (*b > 31 && *b < 127)
+ {
+ *s = *b;
+ }
+ else
+ {
+ *s = '.';
+ }
+ b++;
+ s++;
+ }
}
void psTraceBytes(const char *tag, const unsigned char *p, int l)
{
- char s[17];
- int i;
+ char s[17];
+ int i;
- s[16] = '\0';
- if (tag) {
- _psTraceStr("psTraceBytes(%s, ", tag);
- _psTraceInt("%d);", l);
- } else {
- _psTrace("\"");
- }
- for (i = 0; i < l; i++) {
- if (!(i & 0xF)) {
- if (tag) {
- if (i != 0) {
- mem2str(s, p - 16, 16);
- _psTraceStr(" %s", s);
- }
+ s[16] = '\0';
+ if (tag)
+ {
+ _psTraceStr("psTraceBytes(%s, ", tag);
+ _psTraceInt("%d);", l);
+ }
+ else
+ {
+ _psTrace("\"");
+ }
+ for (i = 0; i < l; i++)
+ {
+ if (!(i & 0xF))
+ {
+ if (tag)
+ {
+ if (i != 0)
+ {
+ mem2str(s, p - 16, 16);
+ _psTraceStr(" %s", s);
+ }
#ifdef _LP64
- _psTraceInt("\n0x%08x:", (int64)p);
+ _psTraceInt("\n0x%08x:", (int64) p);
#else
- _psTraceInt("\n0x%04x:", (int32)p);
+ _psTraceInt("\n0x%04x:", (int32) p);
#endif
- } else {
- _psTrace("\"\n\"");
- }
- }
- if (tag) {
- _psTraceInt("%02x ", *p++);
- } else {
- _psTraceInt("\\x%02x", *p++);
- }
- }
- if (tag) {
- memset(s, 0x0, 16);
- i = l & 0xF;
- mem2str(s, p - i, (unsigned int)i);
- for (;i < 16; i++) {
- _psTrace(" ");
- }
- _psTraceStr(" %s", s);
- _psTrace("\n");
- } else {
- _psTrace("\"\n");
- }
+ }
+ else
+ {
+ _psTrace("\"\n\"");
+ }
+ }
+ if (tag)
+ {
+ _psTraceInt("%02x ", *p++);
+ }
+ else
+ {
+ _psTraceInt("\\x%02x", *p++);
+ }
+ }
+ if (tag)
+ {
+ memset(s, 0x0, 16);
+ i = l & 0xF;
+ mem2str(s, p - i, (unsigned int) i);
+ for (; i < 16; i++)
+ {
+ _psTrace(" ");
+ }
+ _psTraceStr(" %s", s);
+ _psTrace("\n");
+ }
+ else
+ {
+ _psTrace("\"\n");
+ }
}
/******************************************************************************/
/*
- Creates a simple linked list from a given stream and separator char
+ Creates a simple linked list from a given stream and separator char
- Memory info:
- Callers do not have to free 'items' on function failure.
-*/
+ Memory info:
+ Callers do not have to free 'items' on function failure.
+ */
int32 psParseList(psPool_t *pool, char *list, const char separator,
- psList_t **items)
+ psList_t **items)
{
- psList_t *litems, *start, *prev;
- uint32 itemLen, listLen;
- char *tmp;
+ psList_t *litems, *start, *prev;
+ uint32 itemLen, listLen;
+ char *tmp;
- *items = NULL;
- prev = NULL;
+ *items = NULL;
+ prev = NULL;
- listLen = (int32)strlen(list) + 1;
- if (listLen == 1) {
- return PS_ARG_FAIL;
- }
- start = litems = psMalloc(pool, sizeof(psList_t));
- if (litems == NULL) {
- return PS_MEM_FAIL;
- }
- memset(litems, 0, sizeof(psList_t));
+ listLen = (int32) strlen(list) + 1;
+ if (listLen == 1)
+ {
+ return PS_ARG_FAIL;
+ }
+ start = litems = psMalloc(pool, sizeof(psList_t));
+ if (litems == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ memset(litems, 0, sizeof(psList_t));
- while (listLen > 0) {
- itemLen = 0;
- tmp = list;
- if (litems == NULL) {
- litems = psMalloc(pool, sizeof(psList_t));
- if (litems == NULL) {
- psFreeList(start, pool);
- return PS_MEM_FAIL;
- }
- memset(litems, 0, sizeof(psList_t));
- prev->next = litems;
+ while (listLen > 0)
+ {
+ itemLen = 0;
+ tmp = list;
+ if (litems == NULL)
+ {
+ litems = psMalloc(pool, sizeof(psList_t));
+ if (litems == NULL)
+ {
+ psFreeList(start, pool);
+ return PS_MEM_FAIL;
+ }
+ memset(litems, 0, sizeof(psList_t));
+ prev->next = litems;
- }
- while (*list != separator && *list != '\0') {
- itemLen++;
- listLen--;
- list++;
- }
- litems->item = psMalloc(pool, itemLen + 1);
- if (litems->item == NULL) {
- psFreeList(start, pool);
- return PS_MEM_FAIL;
- }
- litems->len = itemLen;
- memset(litems->item, 0x0, itemLen + 1);
- memcpy(litems->item, tmp, itemLen);
- list++;
- listLen--;
- prev = litems;
- litems = litems->next;
- }
- *items = start;
- return PS_SUCCESS;
+ }
+ while (*list != separator && *list != '\0')
+ {
+ itemLen++;
+ listLen--;
+ list++;
+ }
+ litems->item = psMalloc(pool, itemLen + 1);
+ if (litems->item == NULL)
+ {
+ psFreeList(start, pool);
+ return PS_MEM_FAIL;
+ }
+ litems->len = itemLen;
+ memset(litems->item, 0x0, itemLen + 1);
+ memcpy(litems->item, tmp, itemLen);
+ list++;
+ listLen--;
+ prev = litems;
+ litems = litems->next;
+ }
+ *items = start;
+ return PS_SUCCESS;
}
void psFreeList(psList_t *list, psPool_t *pool)
{
- psList_t *next, *current;
+ psList_t *next, *current;
- if (list == NULL) {
- return;
- }
- current = list;
- while (current) {
- next = current->next;
- if (current->item) {
- psFree(current->item, pool);
- }
- psFree(current, pool);
- current = next;
- }
+ if (list == NULL)
+ {
+ return;
+ }
+ current = list;
+ while (current)
+ {
+ next = current->next;
+ if (current->item)
+ {
+ psFree(current->item, pool);
+ }
+ psFree(current, pool);
+ current = next;
+ }
}
/******************************************************************************/
/*
- Clear the stack deeper than the caller to erase any potential secrets
- or keys.
-*/
+ Clear the stack deeper than the caller to erase any potential secrets
+ or keys.
+ */
void psBurnStack(uint32 len)
{
- unsigned char buf[32];
+ unsigned char buf[32];
- memset_s(buf, sizeof(buf), 0x0, sizeof(buf));
- if (len > (uint32)sizeof(buf)) {
- psBurnStack(len - sizeof(buf));
- }
+ memset_s(buf, sizeof(buf), 0x0, sizeof(buf));
+ if (len > (uint32) sizeof(buf))
+ {
+ psBurnStack(len - sizeof(buf));
+ }
}
/******************************************************************************/
/*
- Free pointed memory and clear the pointer to avoid accidental
- double free.
-*/
+ Free pointed memory and clear the pointer to avoid accidental
+ double free.
+ */
void psFreeAndClear(void *ptrptr, psPool_t *pool)
{
- void *ptr;
+ void *ptr;
- if (ptrptr != NULL) {
- ptr = *(void **)ptrptr;
- psFree(ptr, pool);
- *(void **)ptrptr = NULL;
- PS_PARAMETER_UNUSED(pool); /* Parameter can be unused. */
- }
+ if (ptrptr != NULL)
+ {
+ ptr = *(void **) ptrptr;
+ psFree(ptr, pool);
+ *(void **) ptrptr = NULL;
+ PS_PARAMETER_UNUSED(pool); /* Parameter can be unused. */
+ }
}
#if defined __unix__ || defined __unix || (defined (__APPLE__) && defined (__MACH__))
-#include /* Possibly provides _POSIX_VERSION. */
+# include /* Possibly provides _POSIX_VERSION. */
/* 32-bit Unix machines may need workaround for Year 2038.
64-bit Unix machines generally use large enough time_t. */
-#if !defined __LP64__ && !defined __ILP64__
-#define USE_UNIX_Y2038_WORKAROUND 1
-#endif
+# if !defined __LP64__ && !defined __ILP64__
+# define USE_UNIX_Y2038_WORKAROUND 1
+# endif
#endif /* __unix__ */
#ifdef _POSIX_VERSION
-#define USE_GMTIME_R /* On posix systems, we use gmtime_r() */
+# define USE_GMTIME_R /* On posix systems, we use gmtime_r() */
#endif /* _POSIX_VERSION */
/******************************************************************************/
/*
- Get broken-down time, similar to time returned by gmtime(), but avoiding
+ Get broken-down time, similar to time returned by gmtime(), but avoiding
the race condition. The function only applies offset if it does not cause
- overflow.
-*/
+ overflow.
+ */
PSPUBLIC int32 psBrokenDownTimeImportSeconds(psBrokenDownTime_t *t,
- psTimeSeconds_t s)
+ psTimeSeconds_t s)
{
- int32 ret = PS_FAILURE;
- struct tm *tm;
- time_t time = s;
+ int32 ret = PS_FAILURE;
+ struct tm *tm;
+ time_t time = s;
#ifdef USE_GMTIME_R
- /* Note: This command assumes psBrokenDownTime_t and struct tm use
- exactly the same representation. If you optimize storage space of
- psBrokenDownTime_t, then transfer each field separately. */
- tm = gmtime_r(&time, t);
- if (tm != NULL) {
- ret = PS_SUCCESS;
- }
+ /* Note: This command assumes psBrokenDownTime_t and struct tm use
+ exactly the same representation. If you optimize storage space of
+ psBrokenDownTime_t, then transfer each field separately. */
+ tm = gmtime_r(&time, t);
+ if (tm != NULL)
+ {
+ ret = PS_SUCCESS;
+ }
#else
- /* Use mutex to lock. */
- psLockMutex(&corelibMutex);
- tm = gmtime(&time);
- if (tm) {
- /* Note: This command assumes psBrokenDownTime_t and struct tm use
- exactly the same representation. If you optimize storage space of
- psBrokenDownTime_t, then transfer each field separately. */
- memcpy(t, tm, sizeof(*t));
- ret = PS_SUCCESS;
- }
- psUnlockMutex(&corelibMutex);
+ /* Use mutex to lock. */
+ psLockMutex(&corelibMutex);
+ tm = gmtime(&time);
+ if (tm)
+ {
+ /* Note: This command assumes psBrokenDownTime_t and struct tm use
+ exactly the same representation. If you optimize storage space of
+ psBrokenDownTime_t, then transfer each field separately. */
+ memcpy(t, tm, sizeof(*t));
+ ret = PS_SUCCESS;
+ }
+ psUnlockMutex(&corelibMutex);
#endif
#ifdef USE_UNIX_Y2038_WORKAROUND
- /* Workaround for time_t overflow in 2038 on 32-bit Linux/Unix: */
- if (time < 0 && t->tm_year < 70) {
- /* Overflow of dat has occurred. Fix the date, using
- psBrokenDownTimeAdd(). This may possibly result in an estimate
- because the computation here does not know of details like
- leap seconds assigned in future. The result should be precise to
- few seconds. */
- /* Note: Adjustment in three parts, because adjustment is too large
- to be processed at once.
- Note: 0x100000000 == 883612800 * 4 + 760516096. */
- (void)psBrokenDownTimeAdd(t, 883612800 * 2);
- (void)psBrokenDownTimeAdd(t, 883612800 * 2);
- (void)psBrokenDownTimeAdd(t, 760516096);
- }
+ /* Workaround for time_t overflow in 2038 on 32-bit Linux/Unix: */
+ if (time < 0 && t->tm_year < 70)
+ {
+ /* Overflow of dat has occurred. Fix the date, using
+ psBrokenDownTimeAdd(). This may possibly result in an estimate
+ because the computation here does not know of details like
+ leap seconds assigned in future. The result should be precise to
+ few seconds. */
+ /* Note: Adjustment in three parts, because adjustment is too large
+ to be processed at once.
+ Note: 0x100000000 == 883612800 * 4 + 760516096. */
+ (void) psBrokenDownTimeAdd(t, 883612800 * 2);
+ (void) psBrokenDownTimeAdd(t, 883612800 * 2);
+ (void) psBrokenDownTimeAdd(t, 760516096);
+ }
#endif /* USE_UNIX_Y2038_WORKAROUND */
- return ret;
+ return ret;
}
/*
- Get broken-down time, similar to time returned by gmtime(), but avoiding
+ Get broken-down time, similar to time returned by gmtime(), but avoiding
the race condition. The function only applies offset if it does not cause
- overflow.
-*/
+ overflow.
+ */
PSPUBLIC int32 psGetBrokenDownGMTime(psBrokenDownTime_t *t, int offset)
{
- int32 ret;
+ int32 ret;
time_t current_time;
- psTimeSeconds_t offseted_time;
+ psTimeSeconds_t offseted_time;
- current_time = time(NULL);
- if (current_time == ((time_t) -1)) {
- return PS_FAILURE;
- }
+ current_time = time(NULL);
+ if (current_time == ((time_t) -1))
+ {
+ return PS_FAILURE;
+ }
- /* Handle negative offsets here. */
- offseted_time = ((psTimeSeconds_t) current_time) + offset;
- /* In case of overflow or positive offset, use time without offset. */
- if ((offset < 0 && offseted_time > current_time) || (offset > 0)) {
- offseted_time = current_time;
- }
+ /* Handle negative offsets here. */
+ offseted_time = ((psTimeSeconds_t) current_time) + offset;
+ /* In case of overflow or positive offset, use time without offset. */
+ if ((offset < 0 && offseted_time > current_time) || (offset > 0))
+ {
+ offseted_time = current_time;
+ }
- ret = psBrokenDownTimeImportSeconds(t, offseted_time);
- /* Handle positive offsets here. */
- if (ret == PS_SUCCESS && offset > 0) {
- ret = psBrokenDownTimeAdd(t, offset);
- }
- return ret;
+ ret = psBrokenDownTimeImportSeconds(t, offseted_time);
+ /* Handle positive offsets here. */
+ if (ret == PS_SUCCESS && offset > 0)
+ {
+ ret = psBrokenDownTimeAdd(t, offset);
+ }
+ return ret;
}
/* Compute number of days in month. */
static int mdays(const psBrokenDownTime_t *t)
{
- static unsigned char days_tab[] = {
- /* Jan */ 31, /* Most Feb */ 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- };
- unsigned char days;
+ static unsigned char days_tab[] = {
+ /* Jan */ 31, /* Most Feb */ 28,31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+ };
+ unsigned char days;
- if (t->tm_mon > 11)
- return -1;
- days = days_tab[t->tm_mon];
- if (days == 28) {
- /* Note: This computation does not consider possible corrections once
- every 3200 years. */
- int year = t->tm_year + 1900;
- int is_leap_year = (year % 4) == 0 &&
- ((year % 100) != 0 || (year % 400) == 0);
- days += is_leap_year;
- }
- return days;
+ if (t->tm_mon > 11)
+ {
+ return -1;
+ }
+ days = days_tab[t->tm_mon];
+ if (days == 28)
+ {
+ /* Note: This computation does not consider possible corrections once
+ every 3200 years. */
+ int year = t->tm_year + 1900;
+ int is_leap_year = (year % 4) == 0 &&
+ ((year % 100) != 0 || (year % 400) == 0);
+ days += is_leap_year;
+ }
+ return days;
}
/******************************************************************************/
/*
Compute broken-down time, with specified offset. The initial broken
- down time t must have been previously initialized. This function only
- needs to support positive offset (including 0).
-*/
+ down time t must have been previously initialized. This function only
+ needs to support positive offset (including 0).
+ */
PSPUBLIC int32 psBrokenDownTimeAdd(psBrokenDownTime_t *res, int32 offset)
{
- if (offset < 0)
- return PS_FAILURE;
+ if (offset < 0)
+ {
+ return PS_FAILURE;
+ }
- /* Quick path for multiples of 28 years. */
- while(offset > 883612800) {
- /* Quick addition of exactly 28 years (the cycle of Gregorian calendar,
- 7 * 4 * 365.25 * 24 * 60 * 60 seconds). */
- offset -= 883612800;
- res->tm_year += 28;
- }
+ /* Quick path for multiples of 28 years. */
+ while (offset > 883612800)
+ {
+ /* Quick addition of exactly 28 years (the cycle of Gregorian calendar,
+ 7 * 4 * 365.25 * 24 * 60 * 60 seconds). */
+ offset -= 883612800;
+ res->tm_year += 28;
+ }
- if (offset == 0)
- return PS_SUCCESS;
+ if (offset == 0)
+ {
+ return PS_SUCCESS;
+ }
- /* Note: this function is approximate in presence of leap seconds. */
- res->tm_sec += offset;
- if (res->tm_sec >= 60) {
- res->tm_min += res->tm_sec / 60;
- res->tm_sec %= 60;
- }
- if (res->tm_min >= 60) {
- res->tm_hour += res->tm_min / 60;
- res->tm_min %= 60;
- }
- if (res->tm_hour >= 24) {
- res->tm_mday += res->tm_hour / 24;
- res->tm_wday += res->tm_hour / 24;
- res->tm_wday %= 7;
- res->tm_hour %= 24;
- }
- /* Do month days, months & years as a loop. */
- while (res->tm_mday > mdays(res)) {
- res->tm_mday -= mdays(res);
- res->tm_mon += 1;
- if (res->tm_mon > 11) {
- res->tm_mon -= 12;
- res->tm_year ++;
- }
- /* Note: tm_yday is not updated. */
- res->tm_hour %= 60;
- }
- return PS_SUCCESS;
+ /* Note: this function is approximate in presence of leap seconds. */
+ res->tm_sec += offset;
+ if (res->tm_sec >= 60)
+ {
+ res->tm_min += res->tm_sec / 60;
+ res->tm_sec %= 60;
+ }
+ if (res->tm_min >= 60)
+ {
+ res->tm_hour += res->tm_min / 60;
+ res->tm_min %= 60;
+ }
+ if (res->tm_hour >= 24)
+ {
+ res->tm_mday += res->tm_hour / 24;
+ res->tm_wday += res->tm_hour / 24;
+ res->tm_wday %= 7;
+ res->tm_hour %= 24;
+ }
+ /* Do month days, months & years as a loop. */
+ while (res->tm_mday > mdays(res))
+ {
+ res->tm_mday -= mdays(res);
+ res->tm_mon += 1;
+ if (res->tm_mon > 11)
+ {
+ res->tm_mon -= 12;
+ res->tm_year++;
+ }
+ /* Note: tm_yday is not updated. */
+ res->tm_hour %= 60;
+ }
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
Format BrokenDown Time String with 4 digit year.
- The string format will be "YYYYMMDDHHMMSSZ". Z and NIL are included.
-*/
+ The string format will be "YYYYMMDDHHMMSSZ". Z and NIL are included.
+ */
PSPUBLIC int32 psBrokenDownTimeStr(const psBrokenDownTime_t *t,
- char (*string)[PS_BROKENDOWN_TIME_STR_LEN])
+ char (*string)[PS_BROKENDOWN_TIME_STR_LEN])
{
- size_t len = strftime(*string, PS_BROKENDOWN_TIME_STR_LEN,
- "%Y%m%d%H%M%SZ", t);
- return len == PS_BROKENDOWN_TIME_STR_LEN - 1 ? PS_SUCCESS : PS_FAILURE;
+ size_t len = strftime(*string, PS_BROKENDOWN_TIME_STR_LEN,
+ "%Y%m%d%H%M%SZ", t);
+
+ return len == PS_BROKENDOWN_TIME_STR_LEN - 1 ? PS_SUCCESS : PS_FAILURE;
}
/* Helper function to read specified amount of digits.
The number read shall be within boundaries. On parse errors function returns
(unsigned) -1, otherwise the parsed number. */
static unsigned parse_digits(
- const unsigned char **c_p,
- unsigned digits, unsigned minimum, unsigned maximum)
+ const unsigned char **c_p,
+ unsigned digits, unsigned minimum, unsigned maximum)
{
- const unsigned char *c = *c_p;
- unsigned result = 0;
+ const unsigned char *c = *c_p;
+ unsigned result = 0;
- while(digits) {
- if (*c < '0' || *c > '9')
- return (unsigned) -1;
- result *= 10;
- result += *c - '0';
- c++;
- digits--;
- }
+ while (digits)
+ {
+ if (*c < '0' || *c > '9')
+ {
+ return (unsigned) -1;
+ }
+ result *= 10;
+ result += *c - '0';
+ c++;
+ digits--;
+ }
- *c_p = c;
+ *c_p = c;
- if (result < minimum || result > maximum)
- return (unsigned) -1;
+ if (result < minimum || result > maximum)
+ {
+ return (unsigned) -1;
+ }
- return result;
+ return result;
}
/******************************************************************************/
/**
- Verify a string has nearly valid date range format and length,
+ Verify a string has nearly valid date range format and length,
and return it in broken-down time format.
*/
static unsigned char parsedate_zulu(const unsigned char *p,
- unsigned int time_len,
- unsigned int year_len,
- psBrokenDownTime_t *target,
- int strict)
+ unsigned int time_len,
+ unsigned int year_len,
+ psBrokenDownTime_t *target,
+ int strict)
{
- unsigned year, month, mday, hour, min, sec;
- const unsigned char *c = p;
- psBrokenDownTime_t check_only;
+ unsigned year, month, mday, hour, min, sec;
+ const unsigned char *c = p;
+ psBrokenDownTime_t check_only;
- if (!target)
- /* Use check_only as target. */
- target = &check_only;
+ if (!target)
+ {
+ /* Use check_only as target. */
+ target = &check_only;
+ }
- /* Zeroize all fields as some systems have extra fields
- in struct tm. */
- memset(target, 0, sizeof(*target));
+ /* Zeroize all fields as some systems have extra fields
+ in struct tm. */
+ memset(target, 0, sizeof(*target));
- if (year_len == 4) {
- /* Format shall be YYYYMMDDHHMMSSZ (according to RFC 5280). */
- if (time_len != 15 && strict)
- return 0;
- /* Flexible: allow Z to be replaced with anything. */
- if (time_len < 14 && !strict)
- return 0;
- year = parse_digits(&c, 4, 1900, 2999);
- } else if (year_len == 2) {
- /* Format shall be YYMMDDHHMMSSZ (according to RFC 5280). */
- if (time_len != 13 && strict)
- return 0;
- if (time_len < 12 && !strict)
- return 0;
- year = parse_digits(&c, 2, 0, 99);
- } else {
- return 0;
- }
+ if (year_len == 4)
+ {
+ /* Format shall be YYYYMMDDHHMMSSZ (according to RFC 5280). */
+ if (time_len != 15 && strict)
+ {
+ return 0;
+ }
+ /* Flexible: allow Z to be replaced with anything. */
+ if (time_len < 14 && !strict)
+ {
+ return 0;
+ }
+ year = parse_digits(&c, 4, 1900, 2999);
+ }
+ else if (year_len == 2)
+ {
+ /* Format shall be YYMMDDHHMMSSZ (according to RFC 5280). */
+ if (time_len != 13 && strict)
+ {
+ return 0;
+ }
+ if (time_len < 12 && !strict)
+ {
+ return 0;
+ }
+ year = parse_digits(&c, 2, 0, 99);
+ }
+ else
+ {
+ return 0;
+ }
- if (year == (unsigned) -1)
- return 0;
+ if (year == (unsigned) -1)
+ {
+ return 0;
+ }
- month = parse_digits(&c, 2, 1, 12);
- if (month == (unsigned) -1)
- return 0;
+ month = parse_digits(&c, 2, 1, 12);
+ if (month == (unsigned) -1)
+ {
+ return 0;
+ }
- mday = parse_digits(&c, 2, 1, 31);
- if (mday == (unsigned) -1)
- return 0;
+ mday = parse_digits(&c, 2, 1, 31);
+ if (mday == (unsigned) -1)
+ {
+ return 0;
+ }
- hour = parse_digits(&c, 2, 0, 23);
- if (hour == (unsigned) -1)
- return 0;
+ hour = parse_digits(&c, 2, 0, 23);
+ if (hour == (unsigned) -1)
+ {
+ return 0;
+ }
- min = parse_digits(&c, 2, 0, 59);
- if (min == (unsigned) -1)
- return 0;
+ min = parse_digits(&c, 2, 0, 59);
+ if (min == (unsigned) -1)
+ {
+ return 0;
+ }
- /* This allows up-to 1 leap second.
- (Note: could check that leap second only occurs at 23:59:60 on
- end of Jun 30 or Dec 31 (such as on 31 Dec 2016 23:59:60), but
- rules for insertion of leap seconds may change. */
- sec = parse_digits(&c, 2, 0, 60);
- if (sec == (unsigned) -1)
- return 0;
+ /* This allows up-to 1 leap second.
+ (Note: could check that leap second only occurs at 23:59:60 on
+ end of Jun 30 or Dec 31 (such as on 31 Dec 2016 23:59:60), but
+ rules for insertion of leap seconds may change. */
+ sec = parse_digits(&c, 2, 0, 60);
+ if (sec == (unsigned) -1)
+ {
+ return 0;
+ }
- /* Require all times in X.509 materials to be Zulu time, as is correct
- according to RFC 5280. */
- if (strict && *c != 'Z')
- return 0;
- else {
- /* Ignore time zone. The time zone shall be Zulu according to RFC 5280,
- for X.509 certificates, CRL, OCSP etc. These times will be matched
- exactly. However, some old systems may use certificates with some
- other time zone. When handling those, the times will not be handled
- exactly, but the inaccuracy will be within a day. */
- }
+ /* Require all times in X.509 materials to be Zulu time, as is correct
+ according to RFC 5280. */
+ if (strict && *c != 'Z')
+ {
+ return 0;
+ }
+ else
+ {
+ /* Ignore time zone. The time zone shall be Zulu according to RFC 5280,
+ for X.509 certificates, CRL, OCSP etc. These times will be matched
+ exactly. However, some old systems may use certificates with some
+ other time zone. When handling those, the times will not be handled
+ exactly, but the inaccuracy will be within a day. */
+ }
- /* Convert 2 or 4 digit year to tm format (year after 1900).
- Two digit years are interpreted according to RFC 5280. */
- if (year < 50)
- year += 100;
- else if (year >= 1900)
- year -= 1900;
- else if (year >= 100)
- /* years 100-1900 cannot be represented in psBrokenDownTime_t. */
- return 0;
- else {
- /* Two digit year 50-99 is already correct. */
- }
+ /* Convert 2 or 4 digit year to tm format (year after 1900).
+ Two digit years are interpreted according to RFC 5280. */
+ if (year < 50)
+ {
+ year += 100;
+ }
+ else if (year >= 1900)
+ {
+ year -= 1900;
+ }
+ else if (year >= 100)
+ {
+ /* years 100-1900 cannot be represented in psBrokenDownTime_t. */
+ return 0;
+ }
+ else
+ {
+ /* Two digit year 50-99 is already correct. */
+ }
- target->tm_year = (int) year;
- target->tm_mon = (int) month - 1;
- target->tm_mday = (int) mday;
- target->tm_hour = (int) hour;
- target->tm_min = (int) min;
- target->tm_sec = (int) sec;
- /* Note: target->tm_wday and target->tm_yday are not set. */
- if (target->tm_mday > mdays(target)) {
- /* No such day in this month. */
- memset(target, 0, sizeof(*target));
- return 0;
- }
- return 1;
+ target->tm_year = (int) year;
+ target->tm_mon = (int) month - 1;
+ target->tm_mday = (int) mday;
+ target->tm_hour = (int) hour;
+ target->tm_min = (int) min;
+ target->tm_sec = (int) sec;
+ /* Note: target->tm_wday and target->tm_yday are not set. */
+ if (target->tm_mday > mdays(target))
+ {
+ /* No such day in this month. */
+ memset(target, 0, sizeof(*target));
+ return 0;
+ }
+ return 1;
}
/******************************************************************************/
/*
Import BrokenDown Time from String format. Number of digits in year
- can be provided via an option. The string format recommended is
- "YYYYMMDDHHMMSSZ".
- This function only supports Zulu time, any other time zone will be ignored.
-*/
+ can be provided via an option. The string format recommended is
+ "YYYYMMDDHHMMSSZ".
+ This function only supports Zulu time, any other time zone will be ignored.
+ */
PSPUBLIC int32 psBrokenDownTimeImport(
- psBrokenDownTime_t *t,
- const char *string, size_t time_string_len,
- unsigned int opts)
+ psBrokenDownTime_t *t,
+ const char *string, size_t time_string_len,
+ unsigned int opts)
{
- unsigned char res;
- /* Reject very long strings as illegal. */
- if (time_string_len > 255)
- return PS_FAILURE;
+ unsigned char res;
- res = parsedate_zulu((const unsigned char *)string,
- (unsigned int) time_string_len,
- (opts & PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR) ?
- 2 : 4, t,
- (opts & PS_BROKENDOWN_TIME_IMPORT_STRICT_ZULU));
+ /* Reject very long strings as illegal. */
+ if (time_string_len > 255)
+ {
+ return PS_FAILURE;
+ }
- return res ? PS_SUCCESS : PS_FAILURE;
+ res = parsedate_zulu((const unsigned char *) string,
+ (unsigned int) time_string_len,
+ (opts & PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR) ?
+ 2 : 4, t,
+ (opts & PS_BROKENDOWN_TIME_IMPORT_STRICT_ZULU));
+
+ return res ? PS_SUCCESS : PS_FAILURE;
}
/******************************************************************************/
/*
Compute broken-down times, returning <0, 0 or >0 according to t1 being
- smaller, equal or greater than t2.
-*/
+ smaller, equal or greater than t2.
+ */
PSPUBLIC int psBrokenDownTimeCmp(const psBrokenDownTime_t *t1,
- const psBrokenDownTime_t *t2)
+ const psBrokenDownTime_t *t2)
{
- char s1[PS_BROKENDOWN_TIME_STR_LEN] = { '!', 0 };
- char s2[PS_BROKENDOWN_TIME_STR_LEN] = { 0 };
+ char s1[PS_BROKENDOWN_TIME_STR_LEN] = { '!', 0 };
+ char s2[PS_BROKENDOWN_TIME_STR_LEN] = { 0 };
- /* The dates are represented using YYYYMMDDHHMMSSZ for comparison.
- I.e. comparison ignores tm_wday, tm_yday, and tm_isdst. */
- (void) psBrokenDownTimeStr(t1, &s1);
- (void) psBrokenDownTimeStr(t2, &s2);
- /* If you wish to debug time comparisons, you can enable next lines. */
- /* _psTraceStr("Comparing t1: %s against ", s1); */
- /* _psTraceStr("t2: %s ", s2); */
- /* _psTraceInt("got: %d\n", memcmp(s1, s2, sizeof(s1))); */
- return memcmp(s1, s2, sizeof(s1));
+ /* The dates are represented using YYYYMMDDHHMMSSZ for comparison.
+ I.e. comparison ignores tm_wday, tm_yday, and tm_isdst. */
+ (void) psBrokenDownTimeStr(t1, &s1);
+ (void) psBrokenDownTimeStr(t2, &s2);
+ /* If you wish to debug time comparisons, you can enable next lines. */
+ /* _psTraceStr("Comparing t1: %s against ", s1); */
+ /* _psTraceStr("t2: %s ", s2); */
+ /* _psTraceInt("got: %d\n", memcmp(s1, s2, sizeof(s1))); */
+ return memcmp(s1, s2, sizeof(s1));
}
/******************************************************************************/
/*
- Helper function for String conversion.
-*/
+ Helper function for String conversion.
+ */
PSPUBLIC int32 psToUtf8String(psPool_t *pool,
- const unsigned char *input, size_t input_len,
- psStringType_t input_type,
- unsigned char **output, size_t *output_len,
- int opts)
+ const unsigned char *input, size_t input_len,
+ psStringType_t input_type,
+ unsigned char **output, size_t *output_len,
+ int opts)
{
- int32 err;
- psParseBuf_t in;
- psDynBuf_t out;
- size_t ignored_size;
- int clen = 1;
+ int32 err;
+ psParseBuf_t in;
+ psDynBuf_t out;
+ size_t ignored_size;
+ int clen = 1;
- if ((opts & ~PS_STRING_DUAL_NIL) != 0)
- return PS_UNSUPPORTED_FAIL;
+ if ((opts & ~PS_STRING_DUAL_NIL) != 0)
+ {
+ return PS_UNSUPPORTED_FAIL;
+ }
- switch(input_type) {
- case PS_STRING_NUMERIC_STRING:
- case PS_STRING_PRINTABLE_STRING:
- /* These are subsets of ASCII. */
- break;
- case PS_STRING_BMP_STRING:
- /* UCS2 characters. */
- clen = 2;
- break;
- default:
- return PS_UNSUPPORTED_FAIL;
- }
+ switch (input_type)
+ {
+ case PS_STRING_NUMERIC_STRING:
+ case PS_STRING_PRINTABLE_STRING:
+ /* These are subsets of ASCII. */
+ break;
+ case PS_STRING_BMP_STRING:
+ /* UCS2 characters. */
+ clen = 2;
+ break;
+ default:
+ return PS_UNSUPPORTED_FAIL;
+ }
- /* Sequence of 16-bit characters has to have even length. */
- if (clen == 2 && (input_len & 1) > 0) {
- return PS_FAILURE;
- }
+ /* Sequence of 16-bit characters has to have even length. */
+ if (clen == 2 && (input_len & 1) > 0)
+ {
+ return PS_FAILURE;
+ }
- err = psParseBufFromStaticData(&in, input, input_len);
- if (err != PS_SUCCESS)
- return err;
+ err = psParseBufFromStaticData(&in, input, input_len);
+ if (err != PS_SUCCESS)
+ {
+ return err;
+ }
- /* Create dynamic buffer with initial size estimate being the same
- than input + termination character(s). */
- err = psDynBufInit(pool, &out, input_len + 2) ? PS_SUCCESS : PS_MEM_FAIL;
- if (err != PS_SUCCESS)
- return err;
+ /* Create dynamic buffer with initial size estimate being the same
+ than input + termination character(s). */
+ err = psDynBufInit(pool, &out, input_len + 2) ? PS_SUCCESS : PS_MEM_FAIL;
+ if (err != PS_SUCCESS)
+ {
+ return err;
+ }
- if (clen == 1) {
- while(psParseCanRead(&in, 1)) {
- int8_t chr = (int8_t) *in.buf.start;
- if (chr >= 1) {
- (void)psDynBufAppendChar(&out, (char) chr);
- } else {
- /* non-ASCII character (eight bit set) or \0. */
- err = PS_LIMIT_FAIL;
- }
- psParseBufSkipBytes(&in, (unsigned char *) &chr, 1);
- }
- } else /* clen == 2 */ {
- while(psParseCanRead(&in, 2)) {
- unsigned char a[2];
- uint16_t chr;
- memcpy(a, in.buf.start, 2);
- chr = a[0];
- chr <<= 8;
- chr |= a[1];
- if (chr != 0 && (chr < 0xd800 || chr > 0xdfff)) {
- /* ASCII */
- (void)psDynBufAppendUtf8(&out, chr);
- } else {
- /* surrogate pair or \0. These are invalid code points BMP. */
- err = PS_LIMIT_FAIL;
- }
- psParseBufSkipBytes(&in, a, 2);
- }
- }
+ if (clen == 1)
+ {
+ while (psParseCanRead(&in, 1))
+ {
+ int8_t chr = (int8_t) *in.buf.start;
+ if (chr >= 1)
+ {
+ (void) psDynBufAppendChar(&out, (char) chr);
+ }
+ else
+ {
+ /* non-ASCII character (eight bit set) or \0. */
+ err = PS_LIMIT_FAIL;
+ }
+ psParseBufSkipBytes(&in, (unsigned char *) &chr, 1);
+ }
+ }
+ else /* clen == 2 */
+ {
+ while (psParseCanRead(&in, 2))
+ {
+ unsigned char a[2];
+ uint16_t chr;
+ memcpy(a, in.buf.start, 2);
+ chr = a[0];
+ chr <<= 8;
+ chr |= a[1];
+ if (chr != 0 && (chr < 0xd800 || chr > 0xdfff))
+ {
+ /* ASCII */
+ (void) psDynBufAppendUtf8(&out, chr);
+ }
+ else
+ {
+ /* surrogate pair or \0. These are invalid code points BMP. */
+ err = PS_LIMIT_FAIL;
+ }
+ psParseBufSkipBytes(&in, a, 2);
+ }
+ }
- if (output_len == NULL)
- output_len = &ignored_size;
+ if (output_len == NULL)
+ {
+ output_len = &ignored_size;
+ }
- /* Append terminating \0 or \0\0. */
- psDynBufAppendChar(&out, 0);
- if ((opts & PS_STRING_DUAL_NIL) != 0)
- psDynBufAppendChar(&out, 0);
+ /* Append terminating \0 or \0\0. */
+ psDynBufAppendChar(&out, 0);
+ if ((opts & PS_STRING_DUAL_NIL) != 0)
+ {
+ psDynBufAppendChar(&out, 0);
+ }
- if (err == PS_SUCCESS) {
- *output = psDynBufDetach(&out, output_len);
- *output_len -= (opts & PS_STRING_DUAL_NIL) ? 2 : 1;
- if (*output == NULL)
- return PS_MEM_FAIL;
- } else {
- psDynBufUninit(&out);
- }
- return err;
+ if (err == PS_SUCCESS)
+ {
+ *output = psDynBufDetach(&out, output_len);
+ *output_len -= (opts & PS_STRING_DUAL_NIL) ? 2 : 1;
+ if (*output == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ }
+ else
+ {
+ psDynBufUninit(&out);
+ }
+ return err;
}
/******************************************************************************/
diff --git a/core/list.h b/core/list.h
index a41e031..bcca563 100644
--- a/core/list.h
+++ b/core/list.h
@@ -1,50 +1,50 @@
/**
- * @file list.h
- * @version $Format:%h%d$
+ * @file list.h
+ * @version $Format:%h%d$
*
- * List utilities.
+ * List utilities.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_COREUTIL
-#define _h_PS_COREUTIL
+# define _h_PS_COREUTIL
/********************************** Defines ***********************************/
/*
- * Fast circular doubly-linked list and branchless macro-functions.
- * Provides a struct-independent way to have a small head and hang a list
- * of structs off of it. Examples of use:
+ * Fast circular doubly-linked list and branchless macro-functions.
+ * Provides a struct-independent way to have a small head and hang a list
+ * of structs off of it. Examples of use:
*
- * typedef struct {
- * int bar;
- * DLListEntry List;
- * } foo;
+ * typedef struct {
+ * int bar;
+ * DLListEntry List;
+ * } foo;
*
* Define foo list head:
* DLListEntry FooListHead;
@@ -52,10 +52,10 @@
* Init for list head:
* DLListInit(&FooListHead);
*
- * Define and init list head:
- * DEFINE_DLLIST(FooListHead);
- * or
- * static DEFINE_DLLIST(FooListHead);
+ * Define and init list head:
+ * DEFINE_DLLIST(FooListHead);
+ * or
+ * static DEFINE_DLLIST(FooListHead);
*
* Insert *pMyFoo after the head:
* foo *pMyFoo;
@@ -91,76 +91,78 @@
* free(pMyFoo);
* }
*/
-typedef struct _DLListEntry {
- struct _DLListEntry *pNext, *pPrev;
+typedef struct _DLListEntry
+{
+ struct _DLListEntry *pNext, *pPrev;
} DLListEntry;
-#define DEFINE_DLLIST(x) DLListEntry x = { .pNext = &x, .pPrev = &x };
+# define DEFINE_DLLIST(x) DLListEntry x = { .pNext = &x, .pPrev = &x };
-#define DLListInit(__pList) \
-(__pList)->pNext = (__pList)->pPrev = (__pList)
+# define DLListInit(__pList) \
+ (__pList)->pNext = (__pList)->pPrev = (__pList)
/* Inserts an item as the first item of the list */
-#define DLListInsertHead(__pHead, __pNode) { \
-psAssert((__pHead) != (__pNode)); \
-(__pNode)->pNext = (__pHead)->pNext; \
-(__pNode)->pPrev = (__pHead); \
-(__pHead)->pNext->pPrev = (__pNode); \
-(__pHead)->pNext = (__pNode); \
+# define DLListInsertHead(__pHead, __pNode) { \
+ psAssert((__pHead) != (__pNode)); \
+ (__pNode)->pNext = (__pHead)->pNext; \
+ (__pNode)->pPrev = (__pHead); \
+ (__pHead)->pNext->pPrev = (__pNode); \
+ (__pHead)->pNext = (__pNode); \
}
/* Inserts an item as the last in the list */
-#define DLListInsertTail(__pHead, __pNode) { \
-psAssert((__pHead) != (__pNode)); \
-(__pNode)->pNext = (__pHead); \
-(__pNode)->pPrev = (__pHead)->pPrev; \
-(__pHead)->pPrev->pNext = (__pNode); \
-(__pHead)->pPrev = (__pNode); \
+# define DLListInsertTail(__pHead, __pNode) { \
+ psAssert((__pHead) != (__pNode)); \
+ (__pNode)->pNext = (__pHead); \
+ (__pNode)->pPrev = (__pHead)->pPrev; \
+ (__pHead)->pPrev->pNext = (__pNode); \
+ (__pHead)->pPrev = (__pNode); \
}
/* Detaches node from current position in the list. */
-#define DLListRemove(__pNode) { \
-(__pNode)->pNext->pPrev = (__pNode)->pPrev; \
-(__pNode)->pPrev->pNext = (__pNode)->pNext; \
+# define DLListRemove(__pNode) { \
+ (__pNode)->pNext->pPrev = (__pNode)->pPrev; \
+ (__pNode)->pPrev->pNext = (__pNode)->pNext; \
}
-#define DLListIsEmpty(__pHead) ((__pHead)->pNext == (__pHead))
+# define DLListIsEmpty(__pHead) ((__pHead)->pNext == (__pHead))
/*
- Gets the pointer to the containing object given the DLList pointer,
- the type name of the struct, and the name of the DLList field within
- the struct.
+ Gets the pointer to the containing object given the DLList pointer,
+ the type name of the struct, and the name of the DLList field within
+ the struct.
*/
-#define DLListGetContainer(__pDLList, __ContainerType, __DLListFieldName) \
-((__ContainerType *)((char *)(__pDLList) - \
-(long)(&((__ContainerType *)0)->__DLListFieldName)))
+# define DLListGetContainer(__pDLList, __ContainerType, __DLListFieldName) \
+ ((__ContainerType *) ((char *) (__pDLList) - \
+ (long) (&((__ContainerType *) 0)->__DLListFieldName)))
/*
- Detaches first list item after the head and returns a pointer to it.
- List must not be empty.
+ Detaches first list item after the head and returns a pointer to it.
+ List must not be empty.
*/
-#define DLListGetHead(__pHead) \
-(__pHead)->pNext; \
-(__pHead)->pNext->pNext->pPrev = (__pHead); \
-(__pHead)->pNext = (__pHead)->pNext->pNext;
+# define DLListGetHead(__pHead) \
+ (__pHead)->pNext; \
+ (__pHead)->pNext->pNext->pPrev = (__pHead); \
+ (__pHead)->pNext = (__pHead)->pNext->pNext;
/*
- Detaches list list item before the head and returns a pointer to it.
- List must not be empty.
+ Detaches list list item before the head and returns a pointer to it.
+ List must not be empty.
*/
-#define DLListGetTail(__pHead) \
-(__pHead)->pPrev; \
-(__pHead)->pPrev->pPrev->pNext = (__pHead); \
-(__pHead)->pPrev = (__pHead)->pPrev->pPrev;
+# define DLListGetTail(__pHead) \
+ (__pHead)->pPrev; \
+ (__pHead)->pPrev->pPrev->pNext = (__pHead); \
+ (__pHead)->pPrev = (__pHead)->pPrev->pPrev;
/******************************************************************************/
/*
- Simpler, single linked list
-*/
-typedef struct psList {
- unsigned char *item;
- struct psList *next;
- uint16_t len;
+ Simpler, single linked list
+ */
+typedef struct psList
+{
+ unsigned char *item;
+ struct psList *next;
+ psSize_t len;
} psList_t;
#endif /* _h_PS_COREUTIL */
diff --git a/core/memset_s.c b/core/memset_s.c
index 8cb9fc5..e311cd2 100644
--- a/core/memset_s.c
+++ b/core/memset_s.c
@@ -1,89 +1,90 @@
/**
- * @file memset_s.c
- * @version $Format:%h%d$
+ * @file memset_s.c
+ * @version $Format:%h%d$
*
- * Secure memset api that will not be optimized out by compiler.
+ * Secure memset api that will not be optimized out by compiler.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
/**
- Implementation of C11 API for platforms that do not have it.
+ Implementation of C11 API for platforms that do not have it.
- In contrast to the memset(3) function, calls to memset_s() will never be
- "optimised away" by a compiler. This property is required by the follow-
- ing sentences in section K.3.7.4.1 of ISO/IEC 9899:2011 ("ISO C11"):
- Unlike memset(), any call to the memset_s() function shall be evalu-
- ated strictly according to the rules of the abstract machine as
- described in (5.1.2.3). That is, any call to the memset_s() function
- shall assume that the memory indicated by s and n may be accessible
- in the future and thus must contain the values indicated by c.
-
- On Mac OS X, this api is natively implemented.
- On Windows, this api is mapped to SecureZeroMemory()
-*/
+ In contrast to the memset(3) function, calls to memset_s() will never be
+ "optimised away" by a compiler. This property is required by the follow-
+ ing sentences in section K.3.7.4.1 of ISO/IEC 9899:2011 ("ISO C11"):
+ Unlike memset(), any call to the memset_s() function shall be evalu-
+ ated strictly according to the rules of the abstract machine as
+ described in (5.1.2.3). That is, any call to the memset_s() function
+ shall assume that the memory indicated by s and n may be accessible
+ in the future and thus must contain the values indicated by c.
+
+ On Mac OS X, this api is natively implemented.
+ On Windows, this api is mapped to SecureZeroMemory()
+ */
#if !defined(_WIN32) && !defined(__APPLE__)
-#ifdef __OPTIMIZE__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wpragmas"
-#pragma GCC push_options
-#pragma GCC optimize("O0")
-#ifdef __clang__
-#define NO_OPTIM \
- __attribute__((__noinline__)) __attribute__((__optnone__))
-#else
-#define NO_OPTIM \
- __attribute__((__noinline__)) __attribute__((__optimize__("O0")))
-#endif
-#else
-#define NO_OPTIM /* Unrecognized compiler or not optimizing. */
-#endif
+# ifdef __OPTIMIZE__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wpragmas"
+# pragma GCC push_options
+# pragma GCC optimize("O0")
+# ifdef __clang__
+# define NO_OPTIM \
+ __attribute__((__noinline__)) __attribute__((__optnone__))
+# else
+# define NO_OPTIM \
+ __attribute__((__noinline__)) __attribute__((__optimize__("O0")))
+# endif
+# else
+# define NO_OPTIM /* Unrecognized compiler or not optimizing. */
+# endif
-#include
+# include
typedef size_t rsize_t;
typedef int errno_t;
errno_t NO_OPTIM memset_s(void *s, rsize_t smax, int c, rsize_t n)
{
- if (n > smax) {
- n = smax;
- }
- memset(s, c, n);
- return ((unsigned char volatile *)s)[0];
+ if (n > smax)
+ {
+ n = smax;
+ }
+ memset(s, c, n);
+ return ((unsigned char volatile *) s)[0];
}
-#ifdef __OPTIMIZE__
-#pragma GCC pop_options
-#pragma GCC diagnostic pop
-#endif
-#undef NO_OPTIM
+# ifdef __OPTIMIZE__
+# pragma GCC pop_options
+# pragma GCC diagnostic pop
+# endif
+# undef NO_OPTIM
#endif /* !WIN && ! APPLE */
diff --git a/core/osdep-types.h b/core/osdep-types.h
new file mode 100644
index 0000000..15370b6
--- /dev/null
+++ b/core/osdep-types.h
@@ -0,0 +1,376 @@
+/**
+ * @file osdep-types.h
+ * @version $Format:%h%d$
+ *
+ * Operating System and Hardware Abstraction Layer: type definitions.
+ */
+/*
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#ifndef _h_PS_PLATFORM_TYPES
+# define _h_PS_PLATFORM_TYPES
+
+/******************************************************************************/
+/*
+ Platform detection based on compiler settings
+ @see http://sourceforge.net/p/predef/wiki/Home/
+ */
+/* Determine the operating system (if any) */
+# if defined(__linux__) /* Linux and Android */
+# define POSIX
+# define LINUX
+# define MATRIX_USE_FILE_SYSTEM
+# elif defined(__APPLE__) && defined(__MACH__) /* Mac OS X */
+# define POSIX
+# define OSX
+# define HAVE_NATIVE_INT64
+# define MATRIX_USE_FILE_SYSTEM
+# elif defined(_WIN32) /* Windows */
+# ifndef WIN32
+# define WIN32
+# endif
+# define HAVE_NATIVE_INT64
+# define MATRIX_USE_FILE_SYSTEM
+# endif
+/* For others such as FREERTOS, define in build system */
+
+/* Use packed attribute on compilers that support it */
+# if defined(__GNUC__) || defined(__clang__)
+# define PACKED __attribute__((__packed__))
+# else
+# define PACKED
+# endif
+
+/* Determine which assembly language optimizations we can use */
+# if defined(__GNUC__) || defined(__clang__) /* Only supporting gcc-like */
+# if defined(__x86_64__)
+# define PSTM_X86_64
+# define PSTM_64BIT /* Supported by architecture */
+# elif defined(__i386__)
+# define PSTM_X86
+# elif defined(__arm__)
+# define PSTM_ARM
+/* __aarch64__ / * 64 bit arm * / */
+/* __thumb__ / * Thumb mode * / */
+# elif defined(__mips__)
+# if defined(__mips64)
+# define PSTM_64BIT
+# else
+# define PSTM_MIPS /* MIPS assembly supported on 32 bit only */
+# endif
+# elif defined(__aarch64__)
+# define PSTM_64BIT /* Supported by architecture */
+# endif
+# endif /* GNUC/CLANG */
+
+/* Try to determine if the compiler/platform supports 64 bit integer ops */
+# if !defined(HAVE_NATIVE_INT64) && defined(__SIZEOF_LONG_LONG__)
+# define HAVE_NATIVE_INT64 /* Supported by compiler */
+# endif
+
+/* Detect endian based on platform */
+# if (defined __LITTLE_ENDIAN__ || defined __i386__ || defined __x86_64__ || \
+ defined _M_X64 || defined _M_IX86 || \
+ defined __ARMEL__ || defined __MIPSEL__)
+# define __ORDER_LITTLE_ENDIAN__ 1234
+# define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+# elif (defined __BIG_ENDIAN__ || defined __MIPSEB__)
+# define __ORDER_BIG_ENDIAN__ 4321
+# define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
+# endif
+
+# ifdef __BYTE_ORDER__ /* Newer GCC and LLVM */
+# if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+# define ENDIAN_LITTLE
+# else
+# define ENDIAN_BIG
+# endif
+# ifdef PSTM_64BIT
+# define ENDIAN_64BITWORD
+# else
+# define ENDIAN_32BITWORD
+# endif
+# else
+# if (defined(_MSC_VER) && defined(WIN32)) || \
+ (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || \
+ defined(__MINGW32__) || defined(__i386__)))
+# define ENDIAN_LITTLE
+# define ENDIAN_32BITWORD
+# else
+# warning "Cannot determine endianness, using neutral"
+# endif
+/* #define ENDIAN_LITTLE */
+/* #define ENDIAN_BIG */
+
+/* #define ENDIAN_32BITWORD */
+/* #define ENDIAN_64BITWORD */
+# endif
+
+# if (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && \
+ !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD))
+# error You must specify a word size as well as endianness
+# endif
+
+# if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE))
+# define ENDIAN_NEUTRAL
+# endif
+
+/******************************************************************************/
+/*
+ APIs that must be implemented on every platform
+ */
+
+# ifdef WIN32
+# ifdef _LIB /* Static library */
+# define PSPUBLIC extern
+# else
+# ifdef _USRDLL /* DLL */
+# define PSPUBLIC extern __declspec(dllexport)
+# else
+# define PSPUBLIC extern __declspec(dllimport)
+# endif
+# endif
+# else
+# define PSPUBLIC extern
+# endif /* !WIN32 */
+
+/******************************************************************************/
+/*
+ If the Makefile specifies that MatrixSSL does not currently have
+ a layer for the given OS, or the port is to "bare metal" hardware,
+ do basic defines here and include externally provided file "matrixos.h".
+ In addition, if building for such a platform, a C file defining the above
+ functions must be linked with the final executable.
+ */
+# ifdef PS_UNSUPPORTED_OS
+# include "matrixos.h"
+# else
+
+# ifndef POSIX
+# if defined(LINUX) || defined(OSX)
+# define POSIX
+# endif
+# endif
+
+# if defined(POSIX) || (defined(WIN32) && _MSC_VER >= 1600 /*MSVC2010*/)
+# if defined(WIN32)
+# include
+# define strcasecmp lstrcmpiA
+# define snprintf _snprintf
+# endif
+# include
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int16_t int16;
+typedef uint16_t uint16;
+typedef uint8_t uint8;
+# ifdef HAVE_NATIVE_INT64
+typedef int64_t int64;
+typedef uint64_t uint64;
+# endif
+# elif defined(WIN32)
+# include
+# define strcasecmp lstrcmpiA
+# define snprintf _snprintf
+typedef signed long int32;
+typedef unsigned long uint32;
+typedef signed short int16;
+typedef unsigned short uint16;
+typedef unsigned char uint8;
+typedef signed long int32_t;
+typedef unsigned long uint32_t;
+typedef signed short int16_t;
+typedef unsigned short uint16_t;
+typedef unsigned char uint8_t;
+typedef signed char int8_t;
+# ifdef HAVE_NATIVE_INT64
+typedef unsigned long long uint64;
+typedef signed long long int64;
+typedef unsigned long long uint64_t;
+typedef signed long long int64_t;
+# endif
+# elif defined(METAL)
+# include
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int16_t int16;
+typedef uint16_t uint16;
+typedef uint8_t uint8;
+# ifdef HAVE_NATIVE_INT64
+typedef int64_t int64;
+typedef uint64_t uint64;
+# endif
+# elif defined (NUCLEUS)
+# include
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int16_t int16;
+typedef uint16_t uint16;
+typedef uint8_t uint8;
+# ifdef HAVE_NATIVE_INT64
+typedef int64_t int64;
+typedef uint64_t uint64;
+# endif
+# endif
+
+/******************************************************************************/
+/*
+ OS-specific psTime_t types
+
+ Make psTime_t an opaque time value.
+ */
+
+# if defined(__x86_64__)
+# define USE_HIGHRES_TIME
+# endif
+
+# if defined(POSIX)
+# ifndef USE_HIGHRES_TIME
+# include
+# include
+typedef struct timeval psTime_t;
+# else
+# if defined(__APPLE__) || defined(__tile__)
+typedef uint64_t psTime_t;
+# else
+# include
+typedef struct timespec psTime_t;
+# endif
+extern int64_t psDiffUsecs(psTime_t then, psTime_t now);
+# endif
+# elif defined(WIN32)
+typedef LARGE_INTEGER psTime_t;
+# elif defined(METAL)
+typedef unsigned int psTime_t;
+# elif defined(NUCLEUS)
+typedef uint64_t psTime_t;
+# elif defined(VXWORKS)
+typedef struct
+{
+ long sec;
+ long usec;
+} psTime_t;
+# endif
+
+/******************************************************************************/
+/*
+ Defines of other derived types
+ */
+
+/* Size type commonly used by MatrixSSL. This is currently 16-bit to keep
+ data structures small. In future the type can be larger. */
+typedef uint16_t psSize_t;
+
+/* At least 32-bit size for large inputs.
+ On some platforms the type can be larger than 32 bits. */
+typedef uint32_t psSize32_t;
+
+/* An alias for largest possible object size on the target.
+ Currently the same than size_t. */
+typedef size_t psSizeL_t;
+
+/* 16-bit identifier for cipher. This can be used in TLS protocol. */
+typedef uint16_t psCipher16_t;
+
+/* 16-bit identifier for curve. This can be used in cryptography protocol. */
+typedef uint16_t psCurve16_t;
+
+/* Result code of ps functions returning negative value for error and
+ a positive value for success. The purpose of positive values
+ returned is documented for each function. */
+typedef int32_t psRes32_t;
+
+/* Result code of ps functions returning negative value for error and
+ a positive value for success. The positive value is size of operation
+ or area returned.
+ The full documentation of positive values returned is documented for
+ each function. */
+typedef int32_t psResSize_t;
+
+/* Result code of ps functions, returning PS_SUCCESS for success and
+ a negative value for failure. */
+typedef int32_t psRes_t;
+
+/* An integer with boolean value PS_TRUE or PS_FALSE.
+ The actual datatype used varies according to platform.
+ On C99 or later stdbool.h is used, otherwise integer. */
+# ifdef __STDC_VERSION__
+# if __STDC_VERSION__ >= 199901L
+# include
+typedef bool psBool_t;
+# else
+typedef int psBool_t;
+# endif
+# else
+typedef int psBool_t;
+# endif
+
+/******************************************************************************/
+/*
+ Limitations for the data types.
+ */
+
+# define PS_SIZE_MIN ((psSize_t) 0)
+# define PS_SIZE_MAX (~(psSize_t) 0)
+# define PS_SIZE32_MIN ((psSize32_t) 0)
+# define PS_SIZE32_MAX (~(psSize32_t) 0)
+# define PS_SIZEL_MIN ((psSizeL_t) 0)
+# define PS_SIZEL_MAX (~(psSizeL_t) 0)
+# define PS_RES_OK_MIN ((psRes_t) 0)
+# define PS_RES_OK_MAX ((psRes_t) 0)
+# define PS_RES_SIZE_OK_MIN ((psResSize_t) 0)
+# define PS_RES_SIZE_OK_MAX ((psResSize_t) 0x7FFFFFFFUL)
+# define PS_BOOL_MIN ((psBool_t) PS_FALSE)
+# define PS_BOOL_MAX ((psBool_t) PS_TRUE)
+
+/******************************************************************************/
+/*
+ Defines to make library multithreading safe
+ */
+# ifdef USE_MULTITHREADING
+
+extern int32_t osdepMutexOpen(void);
+extern void osdepMutexClose(void);
+
+# if defined(WIN32)
+typedef CRITICAL_SECTION psMutex_t;
+# elif defined(POSIX)
+# include
+# include
+typedef pthread_mutex_t psMutex_t;
+# elif defined(VXWORKS)
+# include "semLib.h"
+typedef SEM_ID psMutex_t;
+# else
+# error psMutex_t must be defined
+# endif /* OS specific mutex */
+# endif /* USE_MULTITHREADING */
+
+# endif /* !PS_UNSUPPORTED_OS */
+#endif /* _h_PS_PLATFORM_TYPES */
+
diff --git a/core/osdep.h b/core/osdep.h
index 9de9ad1..f3873ef 100644
--- a/core/osdep.h
+++ b/core/osdep.h
@@ -1,341 +1,103 @@
/**
- * @file osdep.h
- * @version $Format:%h%d$
+ * @file osdep.h
+ * @version $Format:%h%d$
*
- * Operating System and Hardware Abstraction Layer.
+ * Operating System and Hardware Abstraction Layer.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
+/* This file depends on osdependent type definitions for osdep-types.h */
+#include "osdep-types.h"
+
#ifndef _h_PS_PLATFORM
-#define _h_PS_PLATFORM
+# define _h_PS_PLATFORM
+
+extern int osdepTraceOpen(void);
+extern void osdepTraceClose(void);
+extern int osdepTimeOpen(void);
+extern void osdepTimeClose(void);
+extern int osdepEntropyOpen(void);
+extern void osdepEntropyClose(void);
+# ifdef HALT_ON_PS_ERROR
+extern void osdepBreak(void);
+# endif
+
+/* Note: This macro has been deprecated. Macro PS_MIN should be used instead. */
+# ifndef min
+# define min(a, b) (((a) < (b)) ? (a) : (b))
+# endif /* min */
+
+# ifdef PS_UNSUPPORTED_OS
+/* Unsupported platforms, everything below needs to be defined in
+ a platform specific manner. */
+# else
+/* On supported platforms we can use ANSI C or C99 hosted APIs. */
+# include
/******************************************************************************/
/*
- Platform detection based on compiler settings
- @see http://sourceforge.net/p/predef/wiki/Home/
-*/
-/* Determine the operating system (if any) */
-#if defined(__linux__) /* Linux and Android */
- #define POSIX
- #define LINUX
- #define MATRIX_USE_FILE_SYSTEM
-#elif defined(__APPLE__) && defined(__MACH__) /* Mac OS X */
- #define POSIX
- #define OSX
- #define HAVE_NATIVE_INT64
- #define MATRIX_USE_FILE_SYSTEM
-#elif defined(_WIN32) /* Windows */
- #ifndef WIN32
- #define WIN32
- #endif
- #define HAVE_NATIVE_INT64
- #define MATRIX_USE_FILE_SYSTEM
-#endif
-/* For others such as FREERTOS, define in build system */
-
-/* Use packed attribute on compilers that support it */
-#if defined(__GNUC__) || defined(__clang__)
- #define PACKED __attribute__((__packed__))
-#else
- #define PACKED
-#endif
-
-/* Determine which assembly language optimizations we can use */
-#if defined(__GNUC__) || defined(__clang__) /* Only supporting gcc-like */
-#if defined(__x86_64__)
- #define PSTM_X86_64
- #define PSTM_64BIT /* Supported by architecture */
-#elif defined(__i386__)
- #define PSTM_X86
-#elif defined(__arm__)
- #define PSTM_ARM
- //__aarch64__ /* 64 bit arm */
- //__thumb__ /* Thumb mode */
-#elif defined(__mips__)
- #if defined(__mips64)
- #define PSTM_64BIT
- #else
- #define PSTM_MIPS /* MIPS assembly supported on 32 bit only */
- #endif
-#elif defined(__aarch64__)
- #define PSTM_64BIT /* Supported by architecture */
-#endif
-#endif /* GNUC/CLANG */
-
-/* Try to determine if the compiler/platform supports 64 bit integer ops */
-#if !defined(HAVE_NATIVE_INT64) && defined(__SIZEOF_LONG_LONG__)
- #define HAVE_NATIVE_INT64 /* Supported by compiler */
-#endif
-
-/* Detect endian based on platform */
-#if (defined __LITTLE_ENDIAN__ || defined __i386__ || defined __x86_64__ || \
- defined _M_X64 || defined _M_IX86 || \
- defined __ARMEL__ || defined __MIPSEL__)
- #define __ORDER_LITTLE_ENDIAN__ 1234
- #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
-#elif (defined __BIG_ENDIAN__ || defined __MIPSEB__)
- #define __ORDER_BIG_ENDIAN__ 4321
- #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
-#endif
-
-#ifdef __BYTE_ORDER__ /* Newer GCC and LLVM */
- #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
- #define ENDIAN_LITTLE
- #else
- #define ENDIAN_BIG
- #endif
- #ifdef PSTM_64BIT
- #define ENDIAN_64BITWORD
- #else
- #define ENDIAN_32BITWORD
- #endif
-#else
- #if (defined(_MSC_VER) && defined(WIN32)) || \
- (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || \
- defined(__MINGW32__) || defined(__i386__)))
- #define ENDIAN_LITTLE
- #define ENDIAN_32BITWORD
- #else
- #warning "Cannot determine endianness, using neutral"
- #endif
-/* #define ENDIAN_LITTLE */
-/* #define ENDIAN_BIG */
-
-/* #define ENDIAN_32BITWORD */
-/* #define ENDIAN_64BITWORD */
-#endif
-
-#if (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && \
- !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD))
- #error You must specify a word size as well as endianness
-#endif
-
-#if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE))
- #define ENDIAN_NEUTRAL
-#endif
-
-/******************************************************************************/
-/*
- APIs that must be implemented on every platform
-*/
-
-#ifdef WIN32
- #ifdef _LIB /* Static library */
- #define PSPUBLIC extern
- #else
- #ifdef _USRDLL /* DLL */
- #define PSPUBLIC extern __declspec(dllexport)
- #else
- #define PSPUBLIC extern __declspec(dllimport)
- #endif
- #endif
-#else
- #define PSPUBLIC extern
-#endif /* !WIN32 */
-
-extern int osdepTraceOpen(void);
-extern void osdepTraceClose(void);
-extern int osdepTimeOpen(void);
-extern void osdepTimeClose(void);
-extern int osdepEntropyOpen(void);
-extern void osdepEntropyClose(void);
-#ifdef HALT_ON_PS_ERROR
- extern void osdepBreak(void);
-#endif
-
-#ifndef min
- #define min(a,b) (((a) < (b)) ? (a) : (b))
-#endif /* min */
-
-/******************************************************************************/
-/*
- If the Makefile specifies that MatrixSSL does not currently have
- a layer for the given OS, or the port is to "bare metal" hardware,
- do basic defines here and include externally provided file "matrixos.h".
- In addition, if building for such a platform, a C file defining the above
- functions must be linked with the final executable.
-*/
-#ifdef PS_UNSUPPORTED_OS
- #include "matrixos.h"
-#else
-/******************************************************************************/
-/*
- Supported Platforms below. The implementations of the apis are in
- platform specific directories, such as core/POSIX and core/ECOS
-
- POSIX define is used for Linux and Mac OS X
-*/
-#include
-
-#ifndef POSIX
- #if defined(LINUX) || defined(OSX)
- #define POSIX
- #endif
-#endif
-
-#if defined(POSIX) || (defined(WIN32) && _MSC_VER >= 1600/*MSVC2010*/)
- #if defined(WIN32)
- #include
- #define strcasecmp lstrcmpiA
- #define snprintf _snprintf
- #endif
- #include
- typedef int32_t int32;
- typedef uint32_t uint32;
- typedef int16_t int16;
- typedef uint16_t uint16;
- typedef uint8_t uint8;
- #ifdef HAVE_NATIVE_INT64
- typedef int64_t int64;
- typedef uint64_t uint64;
- #endif
-#elif defined(WIN32)
- #include
- #define strcasecmp lstrcmpiA
- #define snprintf _snprintf
- typedef signed long int32;
- typedef unsigned long uint32;
- typedef signed short int16;
- typedef unsigned short uint16;
- typedef unsigned char uint8;
- typedef signed long int32_t;
- typedef unsigned long uint32_t;
- typedef signed short int16_t;
- typedef unsigned short uint16_t;
- typedef unsigned char uint8_t;
- typedef signed char int8_t;
- #ifdef HAVE_NATIVE_INT64
- typedef unsigned long long uint64;
- typedef signed long long int64;
- typedef unsigned long long uint64_t;
- typedef signed long long int64_t;
- #endif
-#elif defined(METAL)
- #include
- typedef int32_t int32;
- typedef uint32_t uint32;
- typedef int16_t int16;
- typedef uint16_t uint16;
- typedef uint8_t uint8;
- #ifdef HAVE_NATIVE_INT64
- typedef int64_t int64;
- typedef uint64_t uint64;
- #endif
-#elif defined (NUCLEUS)
- #include
- typedef int32_t int32;
- typedef uint32_t uint32;
- typedef int16_t int16;
- typedef uint16_t uint16;
- typedef uint8_t uint8;
- #ifdef HAVE_NATIVE_INT64
- typedef int64_t int64;
- typedef uint64_t uint64;
- #endif
-#endif
-
-/******************************************************************************/
-/*
- Secure memset/memzero
-*/
-#if defined(WIN32)
- #undef memset_s
- #define memset_s(A,B,C,D) SecureZeroMemory(A,D)
-#elif defined(OSX)
- #define __STDC_WANT_LIB_EXT1__ 1
- #include
-#else
- #include
+ Secure memset/memzero
+ */
+# if defined(WIN32)
+# undef memset_s
+# define memset_s(A, B, C, D) SecureZeroMemory(A, D)
+# elif defined(OSX)
+# define __STDC_WANT_LIB_EXT1__ 1
+# include
+# else
+# include
typedef size_t rsize_t;
typedef int errno_t;
extern errno_t memset_s(void *s, rsize_t smax, int c, rsize_t n);
-#endif
+# endif
-#define memzero_s(S,N) memset_s(S, N, 0x0, N)
+# define memzero_s(S, N) memset_s(S, N, 0x0, N)
/******************************************************************************/
/*
- Hardware Abstraction Layer
-*/
+ Hardware Abstraction Layer
+ */
/* Hardware Abstraction Layer - define functions in HAL directory */
-#if defined(POSIX) || defined(WIN32) || defined(ECOS) || defined(FREERTOS) || defined(NUCLEUS)
- #define halOpen() 0
- #define halClose()
- #define halAlert()
-#else
- extern int halOpen(void);
- extern void halAlert(void);
- extern void halClose(void);
-#endif /* HAL */
+# if defined(POSIX) || defined(WIN32) || defined(ECOS) || defined(FREERTOS) || defined(NUCLEUS)
+# define halOpen() 0
+# define halClose()
+# define halAlert()
+# else
+extern int halOpen(void);
+extern void halAlert(void);
+extern void halClose(void);
+# endif /* HAL */
/******************************************************************************/
/*
- OS-specific psTime_t types
-
- Make psTime_t an opaque time value.
-*/
-
-#if defined(__x86_64__)
- #define USE_HIGHRES_TIME
-#endif
-
-#if defined(POSIX)
- #ifndef USE_HIGHRES_TIME
- #include
- #include
- typedef struct timeval psTime_t;
- #else
- #if defined(__APPLE__) || defined(__tile__)
- typedef uint64_t psTime_t;
- #else
- #include
- typedef struct timespec psTime_t;
- #endif
- extern int64_t psDiffUsecs(psTime_t then, psTime_t now);
- #endif
-#elif defined(WIN32)
- typedef LARGE_INTEGER psTime_t;
-#elif defined(METAL)
- typedef unsigned int psTime_t;
-#elif defined(NUCLEUS)
- typedef uint64_t psTime_t;
-#elif defined(VXWORKS)
- typedef struct {
- long sec;
- long usec;
- } psTime_t;
-#endif
-
-/******************************************************************************/
-/*
- Raw trace and error
-*/
+ Raw trace and error
+ */
PSPUBLIC void _psTrace(const char *msg);
PSPUBLIC void _psTraceInt(const char *msg, int32 val);
PSPUBLIC void _psTraceStr(const char *msg, const char *val);
@@ -346,88 +108,71 @@ PSPUBLIC void _psError(const char *msg);
PSPUBLIC void _psErrorInt(const char *msg, int32 val);
PSPUBLIC void _psErrorStr(const char *msg, const char *val);
-/******************************************************************************/
-/*
- Core trace
-*/
-#ifndef USE_CORE_TRACE
- #define psTraceCore(x)
- #define psTraceStrCore(x, y)
- #define psTraceIntCore(x, y)
- #define psTracePtrCore(x, y)
-#else
- #define psTraceCore(x) _psTrace(x)
- #define psTraceStrCore(x, y) _psTraceStr(x, y)
- #define psTraceIntCore(x, y) _psTraceInt(x, y)
- #define psTracePtrCore(x, y) _psTracePtr(x, y)
-#endif /* USE_CORE_TRACE */
+/* Generic trace and debug macros. */
+# define psTrace(x) _psTrace(x)
+# define psTraceInt(x, i) _psTraceInt(x, i)
+# define psTraceStr(x, s) _psTraceStr(x, s)
+# define psTracePtr(x, p) _psTracePtr(x, p)
/******************************************************************************/
/*
- HALT_ON_PS_ERROR define at compile-time determines whether to halt on
- psAssert and psError calls
-*/
-#ifdef USE_CORE_ASSERT
-#define psAssert(C) if (C) ; else \
- {halAlert();_psTraceStr("psAssert %s", __FILE__);_psTraceInt(":%d ", __LINE__);\
- _psError(#C);}
-#else
-#define psAssert(C) if (C) ; else do { /* assert ignored. */} while (0)
-#endif
-
-#ifdef USE_CORE_ERROR
-#define psError(a) \
- halAlert();_psTraceStr("psError %s", __FILE__);_psTraceInt(":%d ", __LINE__); \
- _psError(a);
-
-#define psErrorStr(a,b) \
- halAlert();_psTraceStr("psError %s", __FILE__);_psTraceInt(":%d ", __LINE__); \
- _psErrorStr(a,b)
-
-#define psErrorInt(a,b) \
- halAlert();_psTraceStr("psError %s", __FILE__);_psTraceInt(":%d ", __LINE__); \
- _psErrorInt(a,b)
-#else
-#define psError(a) do { /* error ignored. */} while (0)
-#define psErrorStr(a,b) do { /* error ignored. */} while (0)
-#define psErrorInt(a,b) do { /* error ignored. */} while (0)
-#endif
+ Core trace
+ */
+# ifndef USE_CORE_TRACE
+# define psTraceCore(x)
+# define psTraceStrCore(x, y)
+# define psTraceIntCore(x, y)
+# define psTracePtrCore(x, y)
+# else
+# define psTraceCore(x) _psTrace(x)
+# define psTraceStrCore(x, y) _psTraceStr(x, y)
+# define psTraceIntCore(x, y) _psTraceInt(x, y)
+# define psTracePtrCore(x, y) _psTracePtr(x, y)
+# endif /* USE_CORE_TRACE */
/******************************************************************************/
/*
- OS specific file system apis
-*/
-#ifdef MATRIX_USE_FILE_SYSTEM
- #ifdef POSIX
- #include
- #endif /* POSIX */
-#endif /* MATRIX_USE_FILE_SYSTEM */
+ HALT_ON_PS_ERROR define at compile-time determines whether to halt on
+ psAssert and psError calls
+ */
+# ifdef USE_CORE_ASSERT
+# define psAssert(C) if (C) {; } else \
+ { halAlert(); _psTraceStr("psAssert %s", __FILE__); _psTraceInt(":%d ", __LINE__); \
+ _psError(#C); }
+# else
+# define psAssert(C) if (C) {; } else do { /* assert ignored. */ } while (0)
+# endif
+
+# ifdef USE_CORE_ERROR
+# define psError(a) \
+ halAlert(); _psTraceStr("psError %s", __FILE__); _psTraceInt(":%d ", __LINE__); \
+ _psError(a);
+
+# define psErrorStr(a, b) \
+ halAlert(); _psTraceStr("psError %s", __FILE__); _psTraceInt(":%d ", __LINE__); \
+ _psErrorStr(a, b)
+
+# define psErrorInt(a, b) \
+ halAlert(); _psTraceStr("psError %s", __FILE__); _psTraceInt(":%d ", __LINE__); \
+ _psErrorInt(a, b)
+# else
+# define psError(a) do { /* error ignored. */ } while (0)
+# define psErrorStr(a, b) do { /* error ignored. */ } while (0)
+# define psErrorInt(a, b) do { /* error ignored. */ } while (0)
+# endif
/******************************************************************************/
/*
- Defines to make library multithreading safe
-*/
-#ifdef USE_MULTITHREADING
-
-extern int32_t osdepMutexOpen(void);
-extern void osdepMutexClose(void);
-
-#if defined(WIN32)
- typedef CRITICAL_SECTION psMutex_t;
-#elif defined(POSIX)
- #include
- #include
- typedef pthread_mutex_t psMutex_t;
-#elif defined(VXWORKS)
- #include "semLib.h"
- typedef SEM_ID psMutex_t;
-#else
- #error psMutex_t must be defined
-#endif /* OS specific mutex */
-#endif /* USE_MULTITHREADING */
+ OS specific file system apis
+ */
+# ifdef MATRIX_USE_FILE_SYSTEM
+# ifdef POSIX
+# include
+# endif /* POSIX */
+# endif /* MATRIX_USE_FILE_SYSTEM */
/******************************************************************************/
-#endif /* !PS_UNSUPPORTED_OS */
-#endif /* _h_PS_PLATFORM */
+# endif /* !PS_UNSUPPORTED_OS */
+#endif /* _h_PS_PLATFORM */
diff --git a/core/psUtil.c b/core/psUtil.c
new file mode 100644
index 0000000..14b694b
--- /dev/null
+++ b/core/psUtil.c
@@ -0,0 +1,136 @@
+/**
+ * @file psUtil.c
+ * @version $Format:%h%d$
+ *
+ * Useful utility macros and functions. These macros and functions
+ * are intended to allow easier use of common idioms and to provide
+ * simple extensions to functions provided by C language standard.
+ *
+ * These macros and functions can be used in programs using SafeZone
+ * and MatrixSSL software or related software components.
+ */
+/*
+ * Copyright (c) 2017 INSIDE Secure Corporation
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#include "osdep.h"
+#include "psUtil.h"
+
+/* Initialize memory with specified value.
+ This call is never optimized out by the compiler. */
+void *psMemsetSR(void *s, int c, psSizeL_t n)
+{
+ if (s)
+ {
+ memset_s(s, n, c, n);
+ }
+ return s;
+}
+
+/* Initialize memory with zero value.
+ This call is never optimized out by the compiler. */
+void *psMemzeroSR(void *s, psSizeL_t n)
+{
+ if (s)
+ {
+ memset_s(s, n, 0x00, n);
+ }
+ return s;
+}
+
+/* Initialize memory with specified value.
+ This call is never optimized out by the compiler. */
+void psMemsetS(void *s, int c, psSizeL_t n)
+{
+ if (s)
+ {
+ memset_s(s, n, c, n);
+ }
+}
+
+/* Initialize memory with zero value.
+ This call is never optimized out by the compiler. */
+void psMemzeroS(void *s, psSizeL_t n)
+{
+ if (s)
+ {
+ memset_s(s, n, 0x00, n);
+ }
+}
+
+/* Initialize memory with specified value.
+ This call is never optimized out by the compiler. */
+void *psMemsetSRR(void *s, int c, psSizeL_t n, void *ret)
+{
+ if (s)
+ {
+ memset_s(s, n, c, n);
+ }
+ return ret;
+}
+
+/* Initialize memory with zero value.
+ This call is never optimized out by the compiler. */
+void *psMemzeroSRR(void *s, psSizeL_t n, void *ret)
+{
+ if (s)
+ {
+ memset_s(s, n, 0x00, n);
+ }
+ return ret;
+}
+
+char *psStrdupN(const char *string)
+{
+ size_t len;
+ char *new_str;
+
+ if (string == NULL)
+ {
+ return NULL;
+ }
+ len = psStrlen(string) + 1;
+ new_str = psMallocN(len);
+ if (new_str)
+ {
+ psMemcpy(new_str, string, len);
+ }
+ return new_str;
+}
+
+void psFreeN(void *ptr)
+{
+ psFreeNoPool(ptr);
+}
+
+/* Call free function and return specified return value. */
+void *psFreeFRR(void (*free_func)(void *ptr), void *ptr, void *ret)
+{
+ free_func(ptr);
+ return ret;
+}
+
+/* end of file psUtil.c */
diff --git a/core/psUtil.h b/core/psUtil.h
new file mode 100644
index 0000000..ea9cf78
--- /dev/null
+++ b/core/psUtil.h
@@ -0,0 +1,306 @@
+/**
+ * @file psUtil.h
+ * @version $Format:%h%d$
+ *
+ * Useful utility macros and functions. These macros and functions
+ * are intended to allow easier use of common idioms and to provide
+ * simple extensions to functions provided by C language standard.
+ *
+ * These macros and functions can be used in programs using SafeZone
+ * and MatrixSSL software or related software components.
+ */
+/*
+ * Copyright (c) 2017 INSIDE Secure Corporation
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#ifndef _h_PS_UTIL
+# define _h_PS_UTIL
+
+/******************************************************************************/
+/*
+ psCore helper macros: for communicating with compiler
+ These macros allow to remove spurious warnings or to compile with C++
+ compiler.
+ */
+
+/* Produce specified output only on C++ compilers.
+ This macro is intended to help with small differences between C and C++. */
+# ifdef __cplusplus
+# define PS_CPLUSPLUS_ONLY(text) text
+# else
+# define PS_CPLUSPLUS_ONLY(text_ignored) /* nothing */
+# endif /* __cplusplus */
+
+/* Additional typecast which is only needed on C++ code. */
+# define PS_CPLUSPLUS_CAST(target_type) PS_CPLUSPLUS_ONLY((target_type))
+
+/* Special versions of PS_CPLUSPLUS_ONLY allowing balancing of braces. */
+# define PS_CPLUSPLUS_ONLY_FIRST(text, ignored) PS_CPLUSPLUS_ONLY(text)
+# define PS_CPLUSPLUS_ONLY_LAST(ignored, text) PS_CPLUSPLUS_ONLY(text)
+
+/* Begin "C" definitions. */
+# define PS_EXTERN_C_BEGIN PS_CPLUSPLUS_ONLY_FIRST(extern "C" {, })
+
+/* End "C" definitions. */
+# define PS_EXTERN_C_END PS_CPLUSPLUS_ONLY_LAST({, })
+
+/* Select output: C99_or_older_C */
+# define PS_C99_OR_OLDER(text_c99, text_pre99) text_pre99
+# ifdef __STDC_VERSION__
+# if __STDC_VERSION__ >= 199901L
+/* C99 available. */
+# undef PS_C99_OR_OLDER
+# define PS_C99_OR_OLDER(text_c99, text_pre99) text_c99
+# endif /* __STDC_VERSION__ >= 199901L */
+# endif /* __STDC_VERSION__ */
+
+/* Tell compiler a variable is intended that it can be set, but not used.
+ (The variable is for debugging, future extension or used in some
+ conditionally disabled/unifdeffed branches of execution). */
+# define PS_VARIABLE_SET_BUT_UNUSED(x) do { (void) (x); } while (0)
+
+/* Tell compiler a variable is intended that it can be unused.
+ This is for compilers which detect variables that are not set.
+ (The variable is for debugging, future extension or used in some
+ conditionally disabled/unifdeffed branches of execution). */
+# define PS_VARIABLE_UNUSED(x) do { (void) (x); } while (0)
+
+/* Tell compiler a function parameter is intended that it can be unused.
+ This is for compilers which detect parameters that are not used.
+ (The parameter is for debugging, future extension or used in some
+ conditionally disabled/unifdeffed branches of execution). */
+# define PS_PARAMETER_UNUSED(x) do { (void) (x); } while (0)
+
+
+/******************************************************************************/
+/*
+ Generic helper macros.
+ */
+
+/* Get smaller of two values. */
+# define PS_MIN(m_a, m_b) (((m_a) < (m_b)) ? (m_a) : (m_b))
+
+/* Get larger of two values. */
+# define PS_MAX(m_a, m_b) (((m_a) > (m_b)) ? (m_a) : (m_b))
+
+/* Provide alias for assertions.
+ Note: This macro is also defined in osdep.h.
+ The definition in osdep.h is intended for implementation of MatrixSSL
+ software components, and the definition here is provided as convenience for
+ software using matrixssl. */
+# ifndef psAssert
+# include
+# define psAssert(x) assert(x)
+# endif /* psAssert already defined */
+
+/* produce debug output: This output is directed to standard output.
+ Note: This macro is also defined in osdep.h.
+ The definition in osdep.h is intended for implementation of MatrixSSL
+ software components, and the definition here is provided as convenience for
+ software using matrixssl. */
+# ifndef psTrace
+# include
+# define psPrint(x) printf("%s", (x))
+# define psPrintInt(x, i) printf(x, (i))
+# define psPrintStr(x, s) printf(x, (s))
+# define psPrintPtr(x, p) printf(x, (p))
+# define psTrace(x) printf("%s", (x))
+# define psTraceInt(x, i) printf(x, (i))
+# define psTraceStr(x, s) printf(x, (s))
+# define psTracePtr(x, p) printf(x, (p))
+# define psError(x) fprintf(stderr, "%s", (x))
+# define psErrorInt(x, i) fprintf(stderr, x, (i))
+# define psErrorStr(x, s) fprintf(stderr, (s))
+# define psErrorPtr(x, p) fprintf(stderr, (p))
+# define psPrintf(...) printf(__VA_ARGS__)
+# define psTracef(...) printf(__VA_ARGS__)
+# define psErrorf(...) fprintf(stderr, __VA_ARGS__)
+# endif
+
+/* Equivalent to sizeof, but returns result in psSize_t type. */
+# define PS_SIZEOF(x) ((psSize_t) sizeof(x))
+
+/* Equivalent to sizeof, but returns result in psSize32_t type. */
+# define PS_SIZEOF32(x) ((psSize32_t) sizeof(x))
+
+/******************************************************************************/
+/*
+ Temporary memory allocation for small and medium sized temporaries.
+ These macros allow compile time decision between preferring stack or
+ dynamic memory allocation for storage.
+ */
+
+/* Allocate array from stack or heap. */
+# define PS_TEMP_ARRAYZ(type, ptr_name, constant_length) \
+ PS_TEMP_DEF_ARRAY(type, ptr_name, constant_length) = \
+ PS_TEMP_ALLOC_ARRAYZ(type, ptr_name, constant_length)
+
+/* Check allocation was successful. */
+# define PS_TEMP_IS_OK(ptr_name) \
+ ((ptr_name) != NULL)
+
+/* Free array allocated temporary. */
+# define PS_TEMP_FINISH(ptr_name) PS_TEMP_FREE_ARRAYZ(ptr_name)
+
+/* Free array first creating a duplicate (for returning).
+ Currently uses statement expressions. */
+# define PS_TEMP_RETURN_DUP(ptr_name, dupfunc) /* Defined below. */
+
+/* Zeroize and free array: internals. */
+# define PS_TEMP_FREE_ARRAYZ(ptr_name) /* see end of this file for definition */
+# define PS_TEMP_ALLOC_ARRAYZ(type, ptr_name, constant_length) /* -"- */
+
+/* Temporary allocation internals: */
+# define PS_TEMP_DEF_ARRAY(type, ptr_name, constant_length) \
+ type(ptr_name)[constant_length]
+
+/* Allocate specified sized zero initialized item from stack. */
+# define PS_TEMP_ALLOC_ARRAYZ_STACK(type, ptr_name, constant_length) \
+ PS_C99_OR_OLDER(& ((type [constant_length]) { 0 }), \
+ psMemzeroSR(alloca(sizeof(ptr_name)), sizeof(ptr_name)))
+
+# include
+
+/* Allocate specified sized zero initialized item dynamically. */
+# define PS_TEMP_ALLOC_ARRAYZ_DYNAMIC(type, ptr_name, constant_length) \
+ PS_CPLUSPLUS_CAST(type(*)[constant_length]) calloc(sizeof(ptr_name), 1)
+
+/* Allocate specified sized zero initialized item from stack. */
+# define PS_TEMP_FREE_ARRAYZ_STACK(ptr_name) \
+ psMemzeroS(ptr_name, sizeof(ptr_name))
+
+/* Allocate specified sized zero initialized item from stack. */
+# define PS_TEMP_FREE_ARRAYZ_DYNAMIC(ptr_name) \
+ free(psMemzeroSR(ptr_name, sizeof(ptr_name)))
+
+/* Return specified type. */
+# define PS_TEMP_RETURN_DUP_STACK(ptr_name, dupfunc) \
+ psMemzeroSRR(ptr_name, sizeof(ptr_name), dupfunc(ptr_name))
+
+/* Return specified type. */
+# define PS_TEMP_RETURN_DUP_DYNAMIC(ptr_name, dupfunc) \
+ psFreeFRR(free, ptr_name, dupfunc(ptr_name))
+
+/******************************************************************************/
+/*
+ Helper utility functions.
+ Beware: Some of these may be implemented via function like macros or
+ compiler intrinsics.
+ */
+
+PS_EXTERN_C_BEGIN
+
+/* Initialize memory with specified value.
+ The effect of the function is never optimized out by the compiler.
+ If pointer is NULL, no memory bytes are written.
+ Returns the value passed in as input. */
+void *psMemsetSR(void *s, int c, psSizeL_t n);
+
+/* Initialize memory with zero value.
+ The effect of the function is never optimized out by the compiler.
+ If pointer is NULL, no memory is zeroized.
+ Returns the value passed in as input. */
+void *psMemzeroSR(void *s, psSizeL_t n);
+
+/* Initialize memory with specified value.
+ The effect of the function is never optimized out by the compiler.
+ If pointer is NULL, no memory bytes are written. */
+void psMemsetS(void *s, int c, psSizeL_t n);
+
+/* Initialize memory with zero value.
+ The effect of the function is never optimized out by the compiler.
+ If pointer is NULL, no memory is zeroized. */
+void psMemzeroS(void *s, psSizeL_t n);
+
+/* Initialize memory with specified value.
+ The effect of the function is never optimized out by the compiler.
+ If pointer is NULL, no memory bytes are written.
+ Returns the value passed in as return value input. */
+void *psMemsetSRR(void *s, int c, psSizeL_t n, void *ret);
+
+/* Initialize memory with zero value.
+ The effect of the function is never optimized out by the compiler.
+ If pointer is NULL, no memory is zeroized.
+ Returns the value passed in as return value input. */
+void *psMemzeroSRR(void *s, psSizeL_t n, void *ret);
+
+/* Free memory using specified free function.
+ Then return specified return value. */
+void *psFreeFRR(void (*free_func)(void *ptr), void *ptr, void *ret);
+
+/* Allocate copy of specified string (psMalloc). */
+char *psStrdupN(const char *string);
+
+/* Free (no pool specified): This must be a real function. */
+void psFreeN(void *ptr);
+
+/* These are implemented as macros, to allow compiler intrinsics to be
+ used. */
+# include
+
+/* Simple C string functions.
+ Some of the APIs use them via these macros. */
+# define psMemcpy memcpy
+# define psMemmove memmove
+# define psMemset memset
+# define psStrcmp strcmp
+# define psStrncmp strncmp
+# define psStrlen strlen
+
+PS_EXTERN_C_END
+
+/* Include memory allocation capabilities: They are currently separate
+ file than psUtil.h. psmalloc.h is included after _h_PS_UTIL to allow
+ it to make use of macros defined above. */
+# include "psmalloc.h"
+
+#endif /* _h_PS_UTIL */
+
+/* The remaining part is intentionally outside the _h_PS_UTIL.
+ It is possible to multiply include the header and change
+ PS_TEMP_IS_DYNAMIC between inclusions. */
+
+/* Temporary allocation internals: switch PS_TEMP_IS_DYNAMIC */
+#undef PS_TEMP_ALLOC_ARRAYZ
+#undef PS_TEMP_FREE_ARRAYZ
+#undef PS_TEMP_RETURN_DUP
+#ifdef PS_TEMP_IS_DYNAMIC
+# define PS_TEMP_ALLOC_ARRAYZ(type, ptr_name, constant_length) \
+ PS_TEMP_ALLOC_ARRAYZ_DYNAMIC(type, ptr_name, constant_length)
+# define PS_TEMP_FREE_ARRAYZ(ptr_name) \
+ PS_TEMP_FREE_ARRAYZ_DYNAMIC(ptr_name)
+# define PS_TEMP_RETURN_DUP(ptr_name, dupfunc) \
+ PS_TEMP_RETURN_DUP_DYNAMIC(ptr_name, dupfunc)
+#else
+# define PS_TEMP_ALLOC_ARRAYZ(type, ptr_name, constant_length) \
+ PS_TEMP_ALLOC_ARRAYZ_STACK(type, ptr_name, constant_length)
+# define PS_TEMP_FREE_ARRAYZ(ptr_name) \
+ PS_TEMP_FREE_ARRAYZ_STACK(ptr_name)
+# define PS_TEMP_RETURN_DUP(ptr_name, dupfunc) \
+ PS_TEMP_RETURN_DUP_STACK(ptr_name, dupfunc)
+#endif /* PS_TEMP_IS_DYNAMIC */
+
+/* end of psUtil.h */
diff --git a/core/psbuf.c b/core/psbuf.c
index 6f22fb7..88e85dc 100644
--- a/core/psbuf.c
+++ b/core/psbuf.c
@@ -1,33 +1,33 @@
/**
- * @file psbuf.c
- * @version $Format:%h%d$
+ * @file psbuf.c
+ * @version $Format:%h%d$
*
* Implementation of API for handling buffers containing binary data.
*/
/*
- * Copyright (c) 2016 INSIDE Secure Corporation
- * All Rights Reserved
+ * Copyright (c) 2017 INSIDE Secure Corporation
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
@@ -37,502 +37,684 @@
#include
#include
#include "coreApi.h"
+#include "osdep.h"
/* Omit debug printouts. */
-#define debugf(...) do { } while(0)
+#define debugf(...) do { } while (0)
/* This address is indicator for static allocations pool, and does not
need to point to any valid pool. The pool cannot be NULL, because
NULL is reserved for "default memory pool". */
psPool_t * const psStaticAllocationsPool =
- (psPool_t *)&psStaticAllocationsPool;
+ (psPool_t *) &psStaticAllocationsPool;
void *psBufInit(psPool_t *pool, psBuf_t *buf, size_t capacity)
{
- buf->buf = psMalloc(pool, capacity);
- buf->start = buf->buf;
- buf->end = buf->start;
- buf->size = buf->buf ? capacity : 0;
- return buf->buf;
+ buf->buf = psMalloc(pool, capacity);
+ buf->start = buf->buf;
+ buf->end = buf->start;
+ buf->size = buf->buf ? capacity : 0;
+ return buf->buf;
}
-void psBufUninit(psPool_t *pool, psBuf_t *buf) {
- if (pool != psStaticAllocationsPool)
- psFree(buf->buf, pool);
- buf->buf = NULL;
- buf->start = NULL;
- buf->end = NULL;
- buf->size = 0;
+void psBufUninit(psPool_t *pool, psBuf_t *buf)
+{
+ if (pool != psStaticAllocationsPool)
+ {
+ psFree(buf->buf, pool);
+ }
+ buf->buf = NULL;
+ buf->start = NULL;
+ buf->end = NULL;
+ buf->size = 0;
}
-void *psBufDetach(psPool_t *pool, psBuf_t *buf, size_t *len_p) {
- void * new;
- size_t len = buf->end - buf->start;
- new = psMalloc(pool, len ? len : 1);
- if (new) {
- memcpy(new, buf->start, len);
- *len_p = len;
- }
- psBufUninit(pool, buf);
- return new;
+void *psBufDetach(psPool_t *pool, psBuf_t *buf, size_t *len_p)
+{
+ void *new;
+ size_t len = buf->end - buf->start;
+
+ new = psMalloc(pool, len ? len : 1);
+ if (new)
+ {
+ memcpy(new, buf->start, len);
+ *len_p = len;
+ }
+ psBufUninit(pool, buf);
+ return new;
}
int32_t psBufFromData(psPool_t *pool, psBuf_t *buf, const void *data, size_t len)
{
- void *new = NULL;
- buf->buf = buf->start = buf->end = NULL;
- buf->size = 0;
+ void *new = NULL;
- if (data != NULL) {
- new = psMalloc(pool, len ? len : 1);
- if (new != NULL) {
- buf->buf = buf->start = buf->end = new;
- buf->size = len;
- buf->end += len;
- memcpy(new, data, len);
- }
- }
- return new ? PS_SUCCESS : PS_MEM_FAIL;
+ buf->buf = buf->start = buf->end = NULL;
+ buf->size = 0;
+
+ if (data != NULL)
+ {
+ new = psMalloc(pool, len ? len : 1);
+ if (new != NULL)
+ {
+ buf->buf = buf->start = buf->end = new;
+ buf->size = len;
+ buf->end += len;
+ memcpy(new, data, len);
+ }
+ }
+ return new ? PS_SUCCESS : PS_MEM_FAIL;
}
-static int32_t psBufFromStaticData(psBuf_t *buf, const void *data, size_t len)
+int32_t psBufFromStaticData(psBuf_t *buf, const void *data, size_t len)
{
- if (!data)
- len = 0;
- buf->buf = buf->start = buf->end = (void *) data;
- buf->size = len;
- buf->end += len;
- return data ? PS_SUCCESS : PS_ARG_FAIL;
+ if (!data)
+ {
+ len = 0;
+ }
+ buf->buf = buf->start = buf->end = (void *) data;
+ buf->size = len;
+ buf->end += len;
+ return data ? PS_SUCCESS : PS_ARG_FAIL;
+}
+
+int32_t psBufEmptyFromPointerSize(psBuf_t *buf, void *data, size_t len)
+{
+ if (!data)
+ {
+ len = 0;
+ }
+ buf->buf = buf->start = buf->end = (void *) data;
+ buf->size = len;
+ return data ? PS_SUCCESS : PS_ARG_FAIL;
}
char *psBufAsHex(psPool_t *pool, const psBuf_t *buf)
{
- char * hexstr;
- size_t len = buf->end - buf->start;
- hexstr = psMalloc(pool, len * 2 + 1);
- if (hexstr) {
- size_t i;
- hexstr[0] = 0;
- for(i = 0; i < len; i++)
- sprintf(hexstr + i * 2, "%02x", buf->start[i]);
- }
- return hexstr;
+ char *hexstr;
+ size_t len = buf->end - buf->start;
+
+ hexstr = psMalloc(pool, len * 2 + 1);
+ if (hexstr)
+ {
+ size_t i;
+ hexstr[0] = 0;
+ for (i = 0; i < len; i++)
+ {
+ sprintf(hexstr + i * 2, "%02x", buf->start[i]);
+ }
+ }
+ return hexstr;
+}
+
+size_t psBufGetMaxAppendSize(const psBuf_t *buf)
+{
+ const unsigned char *loc = buf->end;
+ const unsigned char *bufend = buf->buf + buf->size;
+
+ return bufend - loc;
}
void *psBufAppendSize(psBuf_t *buf, size_t sz)
{
- unsigned char *loc = buf->end;
- unsigned char *bufend = buf->buf + buf->size;
- if (loc + sz <= bufend) {
- buf->end += sz;
- } else {
- loc = NULL;
- }
- return loc;
+ unsigned char *loc = buf->end;
+ unsigned char *bufend = buf->buf + buf->size;
+
+ if (loc + sz <= bufend)
+ {
+ buf->end += sz;
+ }
+ else
+ {
+ loc = NULL;
+ }
+ return loc;
}
void psBufReservePrepend(psBuf_t *buf, size_t sz)
{
- unsigned char *bufend = buf->buf + buf->size;
- unsigned char *loc = buf->end;
+ unsigned char *bufend = buf->buf + buf->size;
+ unsigned char *loc = buf->end;
- assert(buf->start == buf->end); /* Must be done at the beginning. */
+ assert(buf->start == buf->end); /* Must be done at the beginning. */
- if (loc + sz <= bufend) {
- buf->start += sz;
- buf->end += sz;
- }
+ if (loc + sz <= bufend)
+ {
+ buf->start += sz;
+ buf->end += sz;
+ }
+}
+
+size_t psBufGetMaxPrependSize(const psBuf_t *buf)
+{
+ return buf->start - buf->buf;
+}
+
+void *psBufGetData(psBuf_t *buf)
+{
+ return buf->start;
+}
+
+size_t psBufGetDataSize(const psBuf_t *buf)
+{
+ return buf->end - buf->start;
}
void *psBufPrependSize(psBuf_t *buf, size_t sz)
{
- if (buf->buf <= buf->start && buf->buf + sz <= buf->start) {
- buf->start -= sz;
- return buf->start;
- }
+ if (buf->buf <= buf->start && buf->buf + sz <= buf->start)
+ {
+ buf->start -= sz;
+ return buf->start;
+ }
- return NULL;
+ return NULL;
+}
+
+void psBufNormalize(psBuf_t *buf)
+{
+ size_t sz = psBufGetMaxPrependSize(buf);
+
+ if (sz > 0)
+ {
+ /* There is some prepend size. Delete it via memmove() that
+ moves data to the beginning of the buffer. */
+ memmove(buf->buf, buf->start, buf->end - buf->start);
+ buf->start = buf->buf;
+ buf->end -= sz;
+ }
+}
+
+int32_t psBufCopyDataN(psBuf_t *buf, size_t reqLen,
+ unsigned char *target, size_t *targetlen)
+{
+ size_t len;
+
+ /* Compute actual processing size (the smaller of [data avail, reqLen]) */
+ len = psBufGetDataSize(buf);
+ if (reqLen < len)
+ {
+ len = reqLen;
+ }
+
+ /* Check there will be no overflow. */
+ if (len > *targetlen)
+ {
+ *targetlen = len;
+ return PS_OUTPUT_LENGTH;
+ }
+
+ /* Process copy operation + move buffer pointer. */
+ memcpy(target, psBufGetData(buf), len);
+ buf->start += len;
+ *targetlen = len;
+ return PS_SUCCESS;
}
void *psDynBufInit(psPool_t *pool, psDynBuf_t *db, size_t capacity)
{
- void *mem = psBufInit(pool, &db->buf, capacity);
- db->pool = pool;
- db->err = (mem == NULL);
- db->master = NULL;
- return mem;
+ void *mem = psBufInit(pool, &db->buf, capacity);
+
+ db->pool = pool;
+ db->err = (mem == NULL);
+ db->master = NULL;
+ return mem;
}
void psDynBufUninit(psDynBuf_t *db)
{
- psBufUninit(db->pool, &db->buf);
- db->err = 0;
- db->pool = NULL;
- db->master = NULL;
+ psBufUninit(db->pool, &db->buf);
+ db->err = 0;
+ db->pool = NULL;
+ db->master = NULL;
}
void *psDynBufDetach(psDynBuf_t *db, size_t *len_p)
{
- void *new;
+ void *new;
- if (db->err) {
- psDynBufUninit(db);
- return NULL;
- }
+ if (db->err)
+ {
+ psDynBufUninit(db);
+ return NULL;
+ }
- new = psBufDetach(db->pool, &db->buf, len_p);
- db->pool = NULL;
- return new;
+ new = psBufDetach(db->pool, &db->buf, len_p);
+ db->pool = NULL;
+ return new;
}
+static
void assert_subbuf(psDynBuf_t *sub)
{
- const psDynBuf_t *db;
- /* Has master. */
- assert(sub->master != NULL);
+ const psDynBuf_t *db;
- db = sub->master;
+ /* Has master. */
+ assert(sub->master != NULL);
- /* Does not have pool */
- assert(sub->pool == NULL);
+ db = sub->master;
- /* The buf begin and is within master allocated data area. */
- assert(sub->buf.buf >= db->buf.start && sub->buf.buf <= db->buf.end);
- assert(sub->buf.buf + sub->buf.size >= db->buf.start &&
- sub->buf.buf + sub->buf.size <= db->buf.end);
+ /* Does not have pool */
+ assert(sub->pool == NULL);
- /* For debugging: Mark head and tail visually. */
- memset(sub->buf.buf, '(', sub->buf.start - sub->buf.buf);
- memset(sub->buf.end, ')', sub->buf.buf + sub->buf.size - sub->buf.end);
+ /* The buf begin and is within master allocated data area. */
+ assert(sub->buf.buf >= db->buf.start && sub->buf.buf <= db->buf.end);
+ assert(sub->buf.buf + sub->buf.size >= db->buf.start &&
+ sub->buf.buf + sub->buf.size <= db->buf.end);
+
+ /* For debugging: Mark head and tail visually. */
+ memset(sub->buf.buf, '(', sub->buf.start - sub->buf.buf);
+ memset(sub->buf.end, ')', sub->buf.buf + sub->buf.size - sub->buf.end);
}
static void *psDynBufGrow(psDynBuf_t *db, size_t head_sz, size_t tail_sz)
{
- void *alloc;
- void *loc;
- psBuf_t new;
- size_t headroom = db->buf.start - db->buf.buf;
- size_t tailroom = (db->buf.buf + db->buf.size) - db->buf.end;
- size_t filled = db->buf.end - db->buf.start;
- size_t offset;
- size_t offset_tail;
+ void *alloc;
+ void *loc;
+ psBuf_t new;
+ size_t headroom = db->buf.start - db->buf.buf;
+ size_t tailroom = (db->buf.buf + db->buf.size) - db->buf.end;
+ size_t filled = db->buf.end - db->buf.start;
+ size_t offset;
+ size_t offset_tail;
- if (db->err)
- return NULL;
+ if (db->err)
+ {
+ return NULL;
+ }
- if (head_sz != 0 && head_sz < PS_DYNBUF_GROW)
- head_sz = PS_DYNBUF_GROW;
- if (tail_sz < PS_DYNBUF_GROW)
- tail_sz = PS_DYNBUF_GROW;
+ if (head_sz != 0 && head_sz < PS_DYNBUF_GROW)
+ {
+ head_sz = PS_DYNBUF_GROW;
+ }
+ if (tail_sz < PS_DYNBUF_GROW)
+ {
+ tail_sz = PS_DYNBUF_GROW;
+ }
- if (db->master) {
- offset = db->buf.buf - db->master->buf.start;
- offset_tail = db->master->buf.end - (db->buf.buf + db->buf.size);
- debugf("Sub Grow: %zu+%zu+%zu => %zu+%zu+%zu; sub @ pos=%zd...-%zd\n",
- headroom, filled, tailroom, headroom + head_sz, filled, tailroom + tail_sz, offset, offset_tail);
- assert_subbuf(db);
+ if (db->master)
+ {
+ offset = db->buf.buf - db->master->buf.start;
+ offset_tail = db->master->buf.end - (db->buf.buf + db->buf.size);
+ debugf("Sub Grow: %zu+%zu+%zu => %zu+%zu+%zu; sub @ pos=%zd...-%zd\n",
+ headroom, filled, tailroom, headroom + head_sz, filled, tailroom + tail_sz, offset, offset_tail);
+ assert_subbuf(db);
- /* For debugging: */
- memset(db->buf.buf, '{', headroom);
- memset(db->buf.end, '}', tailroom);
+ /* For debugging: */
+ memset(db->buf.buf, '{', headroom);
+ memset(db->buf.end, '}', tailroom);
- loc = psDynBufGrow(db->master, 0, head_sz + tail_sz);
- if (loc) {
- db->master->buf.end += head_sz + tail_sz;
- if (offset_tail)
- memmove(db->master->buf.end - offset_tail,
- db->master->buf.end - offset_tail - head_sz - tail_sz,
- offset_tail);
+ loc = psDynBufGrow(db->master, 0, head_sz + tail_sz);
+ if (loc)
+ {
+ db->master->buf.end += head_sz + tail_sz;
+ if (offset_tail)
+ {
+ memmove(db->master->buf.end - offset_tail,
+ db->master->buf.end - offset_tail - head_sz - tail_sz,
+ offset_tail);
+ }
- db->buf.buf = db->master->buf.start + offset;
- db->buf.start = db->buf.buf + headroom + head_sz;
- if (head_sz > 0)
- memmove(db->buf.start,
- db->buf.start - head_sz,
- filled);
- db->buf.end = db->buf.start + filled;
- db->buf.size = head_sz + headroom + filled +
- tailroom + tail_sz;
+ db->buf.buf = db->master->buf.start + offset;
+ db->buf.start = db->buf.buf + headroom + head_sz;
+ if (head_sz > 0)
+ {
+ memmove(db->buf.start,
+ db->buf.start - head_sz,
+ filled);
+ }
+ db->buf.end = db->buf.start + filled;
+ db->buf.size = head_sz + headroom + filled +
+ tailroom + tail_sz;
- debugf("Sub Grown: sub @ pos=%d, %zd bytes (%zd+%zd+%zd)\n",
- (int) (db->buf.buf - db->master->buf.start),
- db->buf.size, db->buf.start - db->buf.buf,
- db->buf.end - db->buf.start, db->buf.buf + db->buf.size - db->buf.end);
+ debugf("Sub Grown: sub @ pos=%d, %zd bytes (%zd+%zd+%zd)\n",
+ (int) (db->buf.buf - db->master->buf.start),
+ db->buf.size, db->buf.start - db->buf.buf,
+ db->buf.end - db->buf.start, db->buf.buf + db->buf.size - db->buf.end);
- /* For debugging: */
- memset(db->buf.buf, '<', head_sz + headroom);
- memset(db->buf.end, '>', tail_sz + tailroom);
- } else {
- db->err++;
- }
- assert_subbuf(db);
+ /* For debugging: */
+ memset(db->buf.buf, '<', head_sz + headroom);
+ memset(db->buf.end, '>', tail_sz + tailroom);
+ }
+ else
+ {
+ db->err++;
+ }
+ assert_subbuf(db);
- return loc;
- }
+ return loc;
+ }
- head_sz += headroom;
- tail_sz += tailroom;
+ head_sz += headroom;
+ tail_sz += tailroom;
- debugf("Grow: %zu+%zu+%zu => %zu+%zu+%zu\n",
- headroom, filled, tailroom, head_sz, filled, tail_sz);
+ debugf("Grow: %zu+%zu+%zu => %zu+%zu+%zu\n",
+ headroom, filled, tailroom, head_sz, filled, tail_sz);
- alloc = psBufInit(db->pool, &new, head_sz + filled + tail_sz);
- if (alloc) {
- psBufReservePrepend(&new, head_sz);
- loc = psBufAppendSize(&new, filled);
- /* Just allocated so there is space. */
- assert(loc != NULL);
- memcpy(loc, db->buf.start, filled);
- psBufUninit(db->pool, &db->buf);
- db->buf.buf = new.buf;
- db->buf.start = new.start;
- db->buf.end = new.end;
- db->buf.size = new.size;
- } else {
- db->err++;
- loc = NULL;
- }
+ alloc = psBufInit(db->pool, &new, head_sz + filled + tail_sz);
+ if (alloc)
+ {
+ psBufReservePrepend(&new, head_sz);
+ loc = psBufAppendSize(&new, filled);
+ /* Just allocated so there is space. */
+ assert(loc != NULL);
+ memcpy(loc, db->buf.start, filled);
+ psBufUninit(db->pool, &db->buf);
+ db->buf.buf = new.buf;
+ db->buf.start = new.start;
+ db->buf.end = new.end;
+ db->buf.size = new.size;
+ }
+ else
+ {
+ db->err++;
+ loc = NULL;
+ }
- return loc;
+ return loc;
}
void *psDynBufAppendSize(psDynBuf_t *db, size_t sz)
{
- unsigned char *loc = psBufAppendSize(&db->buf, sz);
- if (loc == NULL)
- if (psDynBufGrow(db, 0, sz)) {
- loc = psBufAppendSize(&db->buf, sz);
- assert(loc != NULL);
- }
- return loc;
+ unsigned char *loc = psBufAppendSize(&db->buf, sz);
+
+ if (loc == NULL)
+ {
+ if (psDynBufGrow(db, 0, sz))
+ {
+ loc = psBufAppendSize(&db->buf, sz);
+ assert(loc != NULL);
+ }
+ }
+ return loc;
}
void *psDynBufAppendUtf8(psDynBuf_t *db, int chr)
{
- unsigned char *enc;
- unsigned int ch = (unsigned int) chr;
- /* Do not encode characters outside valid UTF-8 range. */
- if (ch > 0x1FFFF) {
- db->err++;
- return NULL;
- }
- if (ch < 128) {
- enc = psDynBufAppendSize(db, 1);
- if (enc)
- *enc = (unsigned char) ch;
- } else if (ch <= 0x7FF) {
- /* Two byte encoding. */
- enc = psDynBufAppendSize(db, 2);
- if (enc) {
- enc[0] = (unsigned char) (0xC0 | (ch >> 6));
- enc[1] = (unsigned char) (0x80 | (ch & 63));
- }
- } else if (ch <= 0xffff) {
- /* Three byte encoding. */
- enc = psDynBufAppendSize(db, 3);
- if (enc) {
- enc[0] = (unsigned char) (0xE0 | (ch >> 12));
- enc[1] = (unsigned char) (0x80 | ((ch >> 6) & 63));
- enc[2] = (unsigned char) (0x80 | (ch & 63));
- }
- } else {
- /* Four byte encoding. */
- enc = psDynBufAppendSize(db, 4);
- if (enc) {
- enc[0] = (unsigned char) (0xF0 | (ch >> 18));
- enc[1] = (unsigned char) (0x80 | ((ch >> 12) & 63));
- enc[2] = (unsigned char) (0x80 | ((ch >> 6) & 63));
- enc[3] = (unsigned char) (0x80 | (ch & 63));
- }
- }
- return enc;
+ unsigned char *enc;
+ unsigned int ch = (unsigned int) chr;
+
+ /* Do not encode characters outside valid UTF-8 range. */
+ if (ch > 0x1FFFF)
+ {
+ db->err++;
+ return NULL;
+ }
+ if (ch < 128)
+ {
+ enc = psDynBufAppendSize(db, 1);
+ if (enc)
+ {
+ *enc = (unsigned char) ch;
+ }
+ }
+ else if (ch <= 0x7FF)
+ {
+ /* Two byte encoding. */
+ enc = psDynBufAppendSize(db, 2);
+ if (enc)
+ {
+ enc[0] = (unsigned char) (0xC0 | (ch >> 6));
+ enc[1] = (unsigned char) (0x80 | (ch & 63));
+ }
+ }
+ else if (ch <= 0xffff)
+ {
+ /* Three byte encoding. */
+ enc = psDynBufAppendSize(db, 3);
+ if (enc)
+ {
+ enc[0] = (unsigned char) (0xE0 | (ch >> 12));
+ enc[1] = (unsigned char) (0x80 | ((ch >> 6) & 63));
+ enc[2] = (unsigned char) (0x80 | (ch & 63));
+ }
+ }
+ else
+ {
+ /* Four byte encoding. */
+ enc = psDynBufAppendSize(db, 4);
+ if (enc)
+ {
+ enc[0] = (unsigned char) (0xF0 | (ch >> 18));
+ enc[1] = (unsigned char) (0x80 | ((ch >> 12) & 63));
+ enc[2] = (unsigned char) (0x80 | ((ch >> 6) & 63));
+ enc[3] = (unsigned char) (0x80 | (ch & 63));
+ }
+ }
+ return enc;
}
void psDynBufReservePrepend(psDynBuf_t *db, size_t sz)
{
- /* This function only performs action if nothing has been pushed.
- The logic for prepending will make sure prepend succeeds even
- if there is no head room. */
- if (db->buf.start == db->buf.end)
- psBufReservePrepend(&db->buf, sz);
+ /* This function only performs action if nothing has been pushed.
+ The logic for prepending will make sure prepend succeeds even
+ if there is no head room. */
+ if (db->buf.start == db->buf.end)
+ {
+ psBufReservePrepend(&db->buf, sz);
+ }
}
void *psDynBufPrependSize(psDynBuf_t *db, size_t sz)
{
- unsigned char *loc = psBufPrependSize(&db->buf, sz);
- if (loc == NULL)
- if (psDynBufGrow(db, sz, 0)) {
- loc = psBufPrependSize(&db->buf, sz);
- assert(loc != NULL);
- }
- return loc;
+ unsigned char *loc = psBufPrependSize(&db->buf, sz);
+
+ if (loc == NULL)
+ {
+ if (psDynBufGrow(db, sz, 0))
+ {
+ loc = psBufPrependSize(&db->buf, sz);
+ assert(loc != NULL);
+ }
+ }
+ return loc;
}
void *psDynBufSubInit(psDynBuf_t *db, psDynBuf_t *sub, size_t capacity)
{
- void *mem = psDynBufAppendSize(db, capacity);
- if (mem) {
- sub->buf.buf = db->buf.end - capacity;
- sub->buf.start = sub->buf.buf;
- sub->buf.end = sub->buf.buf;
- sub->buf.size = capacity;
- sub->pool = NULL;
- sub->master = db;
- sub->err = 0;
- memset(sub->buf.buf, '#', capacity);
- assert_subbuf(sub);
- } else {
- sub->buf.buf = sub->buf.start = sub->buf.end = NULL;
- sub->buf.size = 0;
- sub->pool = NULL;
- sub->err = 1;
- db->err++;
- sub->master = db;
- }
+ void *mem = psDynBufAppendSize(db, capacity);
- return mem;
+ if (mem)
+ {
+ sub->buf.buf = db->buf.end - capacity;
+ sub->buf.start = sub->buf.buf;
+ sub->buf.end = sub->buf.buf;
+ sub->buf.size = capacity;
+ sub->pool = NULL;
+ sub->master = db;
+ sub->err = 0;
+ memset(sub->buf.buf, '#', capacity);
+ assert_subbuf(sub);
+ }
+ else
+ {
+ sub->buf.buf = sub->buf.start = sub->buf.end = NULL;
+ sub->buf.size = 0;
+ sub->pool = NULL;
+ sub->err = 1;
+ db->err++;
+ sub->master = db;
+ }
+
+ return mem;
}
void *psDynBufSubInitAt(psDynBuf_t *db, psDynBuf_t *sub, size_t at,
- size_t length)
+ size_t length)
{
- size_t len = db->buf.end - db->buf.start;
- if (db->err == 0 && at + length <= len) {
- sub->buf.buf = db->buf.start + at;
- sub->buf.start = sub->buf.buf;
- sub->buf.end = sub->buf.buf;
- sub->buf.size = length;
- sub->pool = NULL;
- sub->master = db;
- sub->err = 0;
- memset(sub->buf.buf, '#', length);
- assert_subbuf(sub);
- } else {
- sub->buf.buf = sub->buf.start = sub->buf.end = NULL;
- sub->buf.size = 0;
- sub->pool = NULL;
- sub->err++;
- db->err++;
- sub->master = db;
- }
+ size_t len = db->buf.end - db->buf.start;
- return sub->buf.buf;
+ if (db->err == 0 && at + length <= len)
+ {
+ sub->buf.buf = db->buf.start + at;
+ sub->buf.start = sub->buf.buf;
+ sub->buf.end = sub->buf.buf;
+ sub->buf.size = length;
+ sub->pool = NULL;
+ sub->master = db;
+ sub->err = 0;
+ memset(sub->buf.buf, '#', length);
+ assert_subbuf(sub);
+ }
+ else
+ {
+ sub->buf.buf = sub->buf.start = sub->buf.end = NULL;
+ sub->buf.size = 0;
+ sub->pool = NULL;
+ sub->err++;
+ db->err++;
+ sub->master = db;
+ }
+
+ return sub->buf.buf;
}
void *psDynBufSubFinish(psDynBuf_t *sub)
{
- void *loc = NULL;
- psDynBuf_t *db = sub->master;
- if (sub->err) {
- db->err += sub->err;
- } else {
- size_t total = sub->buf.size;
- size_t filled = sub->buf.end - sub->buf.start;
- size_t offset_tail;
+ void *loc = NULL;
+ psDynBuf_t *db = sub->master;
- offset_tail = db->buf.end - (sub->buf.buf + sub->buf.size);
+ if (sub->err)
+ {
+ db->err += sub->err;
+ }
+ else
+ {
+ size_t total = sub->buf.size;
+ size_t filled = sub->buf.end - sub->buf.start;
+ size_t offset_tail;
- assert_subbuf(sub);
- if (sub->buf.buf != sub->buf.start && filled > 0) {
- memmove(sub->buf.buf, sub->buf.start, filled);
- }
- if (offset_tail > 0) {
- memmove(db->buf.end - total + filled - offset_tail,
- db->buf.end - offset_tail, offset_tail);
- }
- db->buf.end -= total;
- db->buf.end += filled;
- loc = sub->buf.buf;
- }
- sub->buf.buf = NULL;
- psDynBufUninit(sub);
- return loc;
+ offset_tail = db->buf.end - (sub->buf.buf + sub->buf.size);
+
+ assert_subbuf(sub);
+ if (sub->buf.buf != sub->buf.start && filled > 0)
+ {
+ memmove(sub->buf.buf, sub->buf.start, filled);
+ }
+ if (offset_tail > 0)
+ {
+ memmove(db->buf.end - total + filled - offset_tail,
+ db->buf.end - offset_tail, offset_tail);
+ }
+ db->buf.end -= total;
+ db->buf.end += filled;
+ loc = sub->buf.buf;
+ }
+ sub->buf.buf = NULL;
+ psDynBufUninit(sub);
+ return loc;
}
static size_t len_of_tag_and_len(size_t len)
{
- size_t lentaglen;
- if (len < 128)
- lentaglen = 2;
- else if (len < 256)
- lentaglen = 3;
- else if (len < 65536)
- lentaglen = 4;
- else if (len < 16777216)
- lentaglen = 5;
- else
- lentaglen = 6; /* Supports up-to 32-bit sizes. */
- return lentaglen;
+ size_t lentaglen;
+
+ if (len < 128)
+ {
+ lentaglen = 2;
+ }
+ else if (len < 256)
+ {
+ lentaglen = 3;
+ }
+ else if (len < 65536)
+ {
+ lentaglen = 4;
+ }
+ else if (len < 16777216)
+ {
+ lentaglen = 5;
+ }
+ else
+ {
+ lentaglen = 6; /* Supports up-to 32-bit sizes. */
+ }
+ return lentaglen;
}
static void output_len(size_t len, unsigned char *target)
{
- if (len < 128)
- target[1] = (unsigned char) len;
- else if (len < 256) {
- target[1] = 0x81;
- target[2] = (unsigned char) len;
- } else if (len < 65536) {
- target[1] = 0x82;
- target[2] = (unsigned char) (len >> 8);
- target[3] = (unsigned char) len;
- } else if (len < 16777216) {
- target[1] = 0x83;
- target[2] = (unsigned char) (len >> 16);
- target[3] = (unsigned char) (len >> 8);
- target[4] = (unsigned char) len;
- } else {
- target[1] = 0x84;
- target[2] = (unsigned char) (len >> 24);
- target[3] = (unsigned char) (len >> 16);
- target[4] = (unsigned char) (len >> 8);
- target[5] = (unsigned char) len;
- }
+ if (len < 128)
+ {
+ target[1] = (unsigned char) len;
+ }
+ else if (len < 256)
+ {
+ target[1] = 0x81;
+ target[2] = (unsigned char) len;
+ }
+ else if (len < 65536)
+ {
+ target[1] = 0x82;
+ target[2] = (unsigned char) (len >> 8);
+ target[3] = (unsigned char) len;
+ }
+ else if (len < 16777216)
+ {
+ target[1] = 0x83;
+ target[2] = (unsigned char) (len >> 16);
+ target[3] = (unsigned char) (len >> 8);
+ target[4] = (unsigned char) len;
+ }
+ else
+ {
+ target[1] = 0x84;
+ target[2] = (unsigned char) (len >> 24);
+ target[3] = (unsigned char) (len >> 16);
+ target[4] = (unsigned char) (len >> 8);
+ target[5] = (unsigned char) len;
+ }
}
char *psDynBufAppendAsn1TagGen(psDynBuf_t *db, unsigned char tag,
- const unsigned char *bytes, size_t len)
+ const unsigned char *bytes, size_t len)
{
- size_t extralen = len_of_tag_and_len(len);
- unsigned char *target = psDynBufAppendSize(db, len + extralen);
- if (target) {
- target[0] = tag;
- output_len(len, target);
- memcpy(target + extralen, bytes, len);
- }
- return (char *)target;
+ size_t extralen = len_of_tag_and_len(len);
+ unsigned char *target = psDynBufAppendSize(db, len + extralen);
+
+ if (target)
+ {
+ target[0] = tag;
+ output_len(len, target);
+ memcpy(target + extralen, bytes, len);
+ }
+ return (char *) target;
}
char *psDynBufBeginConstructedTag(psDynBuf_t *db, psDynBuf_t *sub)
{
- char *target = psDynBufSubInit(db, sub, 20);
- if (target) {
- psDynBufReservePrepend(sub, 4);
- }
- return target;
+ char *target = psDynBufSubInit(db, sub, 20);
+
+ if (target)
+ {
+ psDynBufReservePrepend(sub, 4);
+ }
+ return target;
}
char *psDynBufEndConstructedTag(psDynBuf_t *sub, unsigned char tag)
{
- size_t len = sub->buf.end - sub->buf.start;
- size_t extralen = len_of_tag_and_len(len);
- unsigned char *target = psDynBufPrependSize(sub, extralen);
- if (target) {
- target[0] = tag;
- output_len(len, target);
- }
- psDynBufSubFinish(sub);
- return (char*)target;
+ size_t len = sub->buf.end - sub->buf.start;
+ size_t extralen = len_of_tag_and_len(len);
+ unsigned char *target = psDynBufPrependSize(sub, extralen);
+
+ if (target)
+ {
+ target[0] = tag;
+ output_len(len, target);
+ }
+ psDynBufSubFinish(sub);
+ return (char *) target;
}
int32_t psParseBufFromStaticData(psParseBuf_t *pb, const void *data, size_t len)
{
- int32_t rc = psBufFromStaticData(&pb->buf, data, len);
- pb->pool = psStaticAllocationsPool;
- pb->err = rc != PS_SUCCESS;
- pb->master = NULL;
- return rc;
+ int32_t rc = psBufFromStaticData(&pb->buf, data, len);
+
+ pb->pool = psStaticAllocationsPool;
+ pb->err = rc != PS_SUCCESS;
+ pb->master = NULL;
+ return rc;
}
/* The maximum supported PS_PARSE_MAXIMUM_TAG_CONTENT: */
@@ -540,245 +722,359 @@ int32_t psParseBufFromStaticData(psParseBuf_t *pb, const void *data, size_t len)
/* Note: If the value needs to be extended, the limit for function
psParseBufGetTagLen() on 32-bit hosts is 0xFFFFFFFFU - 5. */
size_t psParseBufGetTagLen(const psParseBuf_t *pb,
- unsigned char tag,
- size_t *hdrLen_p)
+ unsigned char tag,
+ size_t *hdrLen_p)
{
- unsigned char lenlen;
- size_t len_at = 1;
- size_t len_hdr = 2;
- size_t len_content;
- size_t len_out;
- const unsigned char *ptr = pb->buf.start;
- size_t bytes = pb->buf.end - pb->buf.start;
+ unsigned char lenlen;
+ size_t len_at = 1;
+ size_t len_hdr = 2;
+ size_t len_content;
+ size_t len_out;
+ const unsigned char *ptr = pb->buf.start;
+ size_t bytes = pb->buf.end - pb->buf.start;
- if (bytes < 2)
- return 0;
- if (tag != 0 && ptr[0] != tag)
- return 0;
+ if (bytes < 2)
+ {
+ return 0;
+ }
+ if (tag != 0 && ptr[0] != tag)
+ {
+ return 0;
+ }
- /* Check size tag: long input lengths. */
- lenlen = ptr[1]; /* Use lenlen temporarily to parse length field. */
- if (lenlen >= 0x80) {
- if (bytes < 0x83)
- return 0;
+ /* Check size tag: long input lengths. */
+ lenlen = ptr[1]; /* Use lenlen temporarily to parse length field. */
+ if (lenlen >= 0x80)
+ {
+ if (bytes < 0x83)
+ {
+ return 0;
+ }
- if (lenlen == 0x81 && ptr[2] < 0x80)
- return 0;
+ if (lenlen == 0x81 && ptr[2] < 0x80)
+ {
+ return 0;
+ }
- if (lenlen == 0x82 && ptr[2] == 0x00)
- return 0;
+ if (lenlen == 0x82 && ptr[2] == 0x00)
+ {
+ return 0;
+ }
- if (lenlen == 0x83 && ptr[2] == 0x00)
- return 0;
+ if (lenlen == 0x83 && ptr[2] == 0x00)
+ {
+ return 0;
+ }
- if (lenlen == 0x84 && ptr[2] == 0x00)
- return 0;
+ if (lenlen == 0x84 && ptr[2] == 0x00)
+ {
+ return 0;
+ }
- if (lenlen == 0x80 || lenlen > 0x84)
- return 0; /* Too large or indefinite len. */
- len_at++;
- lenlen -= 0x80;
- len_hdr += lenlen;
- } else {
- lenlen = 1;
- }
+ if (lenlen == 0x80 || lenlen > 0x84)
+ {
+ return 0; /* Too large or indefinite len. */
+ }
+ len_at++;
+ lenlen -= 0x80;
+ len_hdr += lenlen;
+ }
+ else
+ {
+ lenlen = 1;
+ }
- /* len_at and lenlen now express length and of the len. */
- /* additionally, its known that all the length bytes are accessible. */
- len_content = 0;
- while(lenlen) {
- len_content <<= 8;
- len_content += ptr[len_at];
- len_at++;
- lenlen--;
- }
+ /* len_at and lenlen now express length and of the len. */
+ /* additionally, its known that all the length bytes are accessible. */
+ len_content = 0;
+ while (lenlen)
+ {
+ len_content <<= 8;
+ len_content += ptr[len_at];
+ len_at++;
+ lenlen--;
+ }
- if (len_content > PS_PARSE_MAXIMUM_TAG_CONTENT)
- return 0;
+ if (len_content > PS_PARSE_MAXIMUM_TAG_CONTENT)
+ {
+ return 0;
+ }
- len_out = len_content + len_hdr;
+ len_out = len_content + len_hdr;
- if (len_out > bytes)
- return 0;
+ if (len_out > bytes)
+ {
+ return 0;
+ }
- if (hdrLen_p)
- *hdrLen_p = len_hdr;
+ if (hdrLen_p)
+ {
+ *hdrLen_p = len_hdr;
+ }
- return len_out;
+ return len_out;
}
int psParseBufCanGetTag(const psParseBuf_t *pb, unsigned char tag)
{
- return psParseBufGetTagLen(pb, tag, NULL) > 0;
+ return psParseBufGetTagLen(pb, tag, NULL) > 0;
}
size_t psParseBufTrySkipBytes(psParseBuf_t *pb,
- const unsigned char *bytes,
- size_t numbytes)
+ const unsigned char *bytes,
+ size_t numbytes)
{
- size_t skip_bytes = 0;
- if (psParseCanRead(pb, numbytes) &&
- memcmp(bytes, pb->buf.start, numbytes) == 0)
- skip_bytes = numbytes;
- pb->buf.start += skip_bytes;
- return skip_bytes;
+ size_t skip_bytes = 0;
+
+ if (psParseCanRead(pb, numbytes) &&
+ memcmp(bytes, pb->buf.start, numbytes) == 0)
+ {
+ skip_bytes = numbytes;
+ }
+ pb->buf.start += skip_bytes;
+ return skip_bytes;
}
size_t psParseBufSkipBytes(psParseBuf_t *pb, const unsigned char *bytes,
- size_t numbytes)
+ size_t numbytes)
{
- size_t sz = psParseBufTrySkipBytes(pb, bytes, numbytes);
- if (sz == 0)
- pb->err ++;
- return sz;
+ size_t sz = psParseBufTrySkipBytes(pb, bytes, numbytes);
+
+ if (sz == 0)
+ {
+ pb->err++;
+ }
+ return sz;
}
size_t psParseBufTryReadTagSub(const psParseBuf_t *pb,
- psParseBuf_t *content, unsigned char tag)
+ psParseBuf_t *content, unsigned char tag)
{
- size_t hdrlen;
- size_t len = psParseBufGetTagLen(pb, tag, &hdrlen);
- size_t len_content;
- psParseBuf_t content_tmp; /* Allows calling the function with
- content == NULL to skip the tag. */
+ size_t hdrlen;
+ size_t len = psParseBufGetTagLen(pb, tag, &hdrlen);
+ size_t len_content;
+ psParseBuf_t content_tmp; /* Allows calling the function with
+ content == NULL to skip the tag. */
- if (!content)
- content = & content_tmp;
- if (!len) {
- content->buf.buf = content->buf.start = content->buf.end = NULL;
- content->buf.size = 0;
- content->pool = NULL;
- /* Mark state of content as error. */
- content->err = 1;
- /* Do not raise error status of main pb. */
- content->master = (psParseBuf_t *)pb;
- return 0;
- }
+ if (!content)
+ {
+ content = &content_tmp;
+ }
+ if (!len)
+ {
+ content->buf.buf = content->buf.start = content->buf.end = NULL;
+ content->buf.size = 0;
+ content->pool = NULL;
+ /* Mark state of content as error. */
+ content->err = 1;
+ /* Do not raise error status of main pb. */
+ content->master = (psParseBuf_t *) pb;
+ return 0;
+ }
- len_content = len - hdrlen;
- content->buf.start = content->buf.buf = pb->buf.start + hdrlen;
- content->buf.size = len_content;
- content->buf.end = content->buf.start + len_content;
- content->pool = NULL;
- content->master = (psParseBuf_t *)pb;
- content->err = 0;
+ len_content = len - hdrlen;
+ content->buf.start = content->buf.buf = pb->buf.start + hdrlen;
+ content->buf.size = len_content;
+ content->buf.end = content->buf.start + len_content;
+ content->pool = NULL;
+ content->master = (psParseBuf_t *) pb;
+ content->err = 0;
- return len;
+ return len;
}
size_t psParseBufReadTagSub(psParseBuf_t *pb,
- psParseBuf_t *content, unsigned char tag)
+ psParseBuf_t *content, unsigned char tag)
{
- size_t len = psParseBufTryReadTagSub(pb, content, tag);
- if (len == 0) {
- /* Mark this also as an error in main parse buffer. */
- pb->err++;
+ size_t len = psParseBufTryReadTagSub(pb, content, tag);
- /* Initialize sub as the same memory than main parse buffer,
- to allow parsing using it (typically unsuccessfully)
- in following parsing operations. */
- memcpy(&(content->buf), &(pb->buf), sizeof content->buf);
- }
- return len;
+ if (len == 0)
+ {
+ /* Mark this also as an error in main parse buffer. */
+ pb->err++;
+
+ /* Initialize sub as the same memory than main parse buffer,
+ to allow parsing using it (typically unsuccessfully)
+ in following parsing operations. */
+ memcpy(&(content->buf), &(pb->buf), sizeof content->buf);
+ }
+ return len;
}
size_t psParseBufReadTagRef(psParseBuf_t *pb,
- psBuf_t *ref, unsigned char tag)
+ psBuf_t *ref, unsigned char tag)
{
- psParseBuf_t content;
- size_t len = psParseBufReadTagSub(pb, &content, tag);
- if (len) {
- memcpy(ref, &content.buf, sizeof(psBuf_t));
- pb->buf.start += len;
- }
- return len;
+ psParseBuf_t content;
+ size_t len = psParseBufReadTagSub(pb, &content, tag);
+
+ if (len)
+ {
+ memcpy(ref, &content.buf, sizeof(psBuf_t));
+ pb->buf.start += len;
+ }
+ return len;
}
size_t psParseBufTrySkipTag(psParseBuf_t *pb, unsigned char tag)
{
- psParseBuf_t sub;
- size_t sz = psParseBufTryReadTagSub(pb, &sub, tag);
- if (sz)
- (void) psParseBufFinish(&sub);
- return sz;
+ psParseBuf_t sub;
+ size_t sz = psParseBufTryReadTagSub(pb, &sub, tag);
+
+ if (sz)
+ {
+ (void) psParseBufFinish(&sub);
+ }
+ return sz;
}
size_t psParseBufSkipTag(psParseBuf_t *pb, unsigned char tag)
{
- psParseBuf_t sub;
- size_t sz = psParseBufReadTagSub(pb, &sub, tag);
- if (sz)
- (void) psParseBufFinish(&sub);
- return sz;
+ psParseBuf_t sub;
+ size_t sz = psParseBufReadTagSub(pb, &sub, tag);
+
+ if (sz)
+ {
+ (void) psParseBufFinish(&sub);
+ }
+ return sz;
}
int32_t psParseBufCopyAll(const psParseBuf_t *pb, unsigned char *target,
- size_t *targetlen)
+ size_t *targetlen)
{
- size_t len = pb->buf.end - pb->buf.start;
+ size_t len = pb->buf.end - pb->buf.start;
- if (pb->err != 0)
- return PS_FAILURE;
+ if (pb->err != 0)
+ {
+ return PS_FAILURE;
+ }
- if (target == NULL) {
- *targetlen = len;
- return PS_OUTPUT_LENGTH;
- }
+ if (target == NULL)
+ {
+ *targetlen = len;
+ return PS_OUTPUT_LENGTH;
+ }
- if (len > *targetlen) {
- *targetlen = len;
- return PS_OUTPUT_LENGTH;
- }
+ if (len > *targetlen)
+ {
+ *targetlen = len;
+ return PS_OUTPUT_LENGTH;
+ }
- memcpy(target, pb->buf.start, len);
- return PS_SUCCESS;
+ memcpy(target, pb->buf.start, len);
+ *targetlen = len;
+ return PS_SUCCESS;
+}
+
+int32_t psParseBufCopyN(const psParseBuf_t *pb, size_t reqLen,
+ unsigned char *target, size_t *targetlen)
+{
+ size_t len = pb->buf.end - pb->buf.start;
+
+ if (pb->err != 0)
+ {
+ return PS_FAILURE;
+ }
+
+ if (reqLen > len)
+ {
+ reqLen = len;
+ }
+
+ if (target == NULL)
+ {
+ *targetlen = reqLen;
+ return PS_OUTPUT_LENGTH;
+ }
+
+ if (reqLen > *targetlen)
+ {
+ *targetlen = reqLen;
+ return PS_OUTPUT_LENGTH;
+ }
+
+ memcpy(target, pb->buf.start, reqLen);
+ *targetlen = reqLen;
+ return PS_SUCCESS;
+}
+
+int32_t psParseBufCopyUntilByte(psParseBuf_t *pb, unsigned char stopbyte,
+ unsigned char *target, size_t *targetlen)
+{
+ const unsigned char *end;
+ size_t len;
+
+ if (pb->err != 0)
+ {
+ return PS_FAILURE;
+ }
+
+ end = memchr(pb->buf.start, stopbyte, pb->buf.end - pb->buf.start);
+
+ if (end == NULL)
+ {
+ return PS_FAILURE;
+ }
+
+ len = (end - pb->buf.start) + 1;
+ return psParseBufCopyN(pb, len, target, targetlen);
}
int psParseBufEq(const psParseBuf_t *pb1, const psParseBuf_t *pb2)
{
- if (pb1->err || pb2->err)
- return 0;
+ if (pb1->err || pb2->err)
+ {
+ return 0;
+ }
- return psBufEq(&pb1->buf, &pb2->buf);
+ return psBufEq(&pb1->buf, &pb2->buf);
}
int32_t psParseBufCheckState(const psParseBuf_t *pb)
{
- return pb->err == 0 ? PS_SUCCESS : PS_FAILURE;
+ return pb->err == 0 ? PS_SUCCESS : PS_FAILURE;
}
int32_t psParseBufFinish(psParseBuf_t *pb)
{
- int32_t rc;
- if (pb->master) {
- if (pb->err)
- /* Signal master on error. */
- pb->master->err++;
- else
- /* Advance master. */
- pb->master->buf.start = pb->buf.buf + pb->buf.size;
+ int32_t rc;
- pb->buf.buf = NULL; /* Do not free any data. */
- }
+ if (pb->master)
+ {
+ if (pb->err)
+ {
+ /* Signal master on error. */
+ pb->master->err++;
+ }
+ else
+ {
+ /* Advance master. */
+ pb->master->buf.start = pb->buf.buf + pb->buf.size;
+ }
- /* Free state. */
- rc = psParseBufCheckState(pb);
- psBufUninit(pb->pool, &pb->buf);
- pb->master = NULL;
- pb->err = 0;
- pb->pool = NULL;
- return rc;
+ pb->buf.buf = NULL; /* Do not free any data. */
+ }
+
+ /* Free state. */
+ rc = psParseBufCheckState(pb);
+ psBufUninit(pb->pool, &pb->buf);
+ pb->master = NULL;
+ pb->err = 0;
+ pb->pool = NULL;
+ return rc;
}
void psParseBufCancel(psParseBuf_t *pb)
{
- /* Free state. */
- if (pb->master)
- pb->buf.buf = NULL; /* Do not free any data. */
- psBufUninit(pb->pool, &pb->buf);
- pb->master = NULL;
- pb->err = 0;
- pb->pool = NULL;
+ /* Free state. */
+ if (pb->master)
+ {
+ pb->buf.buf = NULL; /* Do not free any data. */
+ }
+ psBufUninit(pb->pool, &pb->buf);
+ pb->master = NULL;
+ pb->err = 0;
+ pb->pool = NULL;
}
/* end of file psbuf.c */
diff --git a/core/psbuf.h b/core/psbuf.h
index 928b16a..e502073 100644
--- a/core/psbuf.h
+++ b/core/psbuf.h
@@ -1,77 +1,92 @@
/**
- * @file psbuf.h
- * @version $Format:%h%d$
+ * @file psbuf.h
+ * @version $Format:%h%d$
*
- * API for handling buffers containing binary data.
+ * API for handling buffers containing binary data.
*/
/*
- * Copyright (c) 2016 INSIDE Secure Corporation
- * All Rights Reserved
+ * Copyright (c) 2017 INSIDE Secure Corporation
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_BUF
-#define _h_PS_BUF
+# define _h_PS_BUF
-#include "coreApi.h"
-#include
+# include "coreApi.h"
+# include
/* API for psBuf initialization and basic usage.*/
void *psBufInit(psPool_t *pool, psBuf_t *buf, size_t capacity);
void psBufUninit(psPool_t *pool, psBuf_t *buf);
+int32_t psBufFromStaticData(psBuf_t *buf, const void *data, size_t len);
+int32_t psBufEmptyFromPointerSize(psBuf_t *buf, void *data, size_t len);
void *psBufDetach(psPool_t *pool, psBuf_t *buf, size_t *len_p);
void *psBufAppendSize(psBuf_t *buf, size_t sz);
+size_t psBufGetMaxAppendSize(const psBuf_t *buf);
void psBufReservePrepend(psBuf_t *buf, size_t sz);
void *psBufPrependSize(psBuf_t *buf, size_t sz);
+size_t psBufGetMaxPrependSize(const psBuf_t *buf);
+void *psBufGetData(psBuf_t *buf);
+size_t psBufGetDataSize(const psBuf_t *buf);
+void psBufNormalize(psBuf_t *buf);
char *psBufAsHex(psPool_t *pool, const psBuf_t *buf);
+int32_t psBufCopyDataN(psBuf_t *buf, size_t reqLen,
+ unsigned char *target, size_t *targetlen);
int32_t psBufFromData(psPool_t *pool, psBuf_t *buf,
- const void *data, size_t len);
+ const void *data, size_t len);
static __inline int psBufEq(const psBuf_t *buf1, const psBuf_t *buf2)
{
- return (buf1->end - buf1->start) == (buf2->end - buf2->start) &&
- buf1->start != NULL &&
- buf2->start != NULL &&
- memcmp(buf1->start, buf2->start, (buf1->end - buf1->start))
- == 0;
+ return (buf1->end - buf1->start) == (buf2->end - buf2->start) &&
+ buf1->start != NULL &&
+ buf2->start != NULL &&
+ memcmp(buf1->start, buf2->start, (buf1->end - buf1->start))
+ == 0;
}
static __inline void *psBufAppendChar(psBuf_t *buf, char ch)
{
void *loc = psBufAppendSize(buf, 1);
+
if (loc)
- *(char*)loc = ch;
+ {
+ *(char *) loc = ch;
+ }
return loc;
}
static __inline void *psBufPrependChar(psBuf_t *buf, char ch)
{
void *loc = psBufPrependSize(buf, 1);
+
if (loc)
- *(char*)loc = ch;
+ {
+ *(char *) loc = ch;
+ }
return loc;
}
@@ -86,8 +101,11 @@ void *psDynBufPrependSize(psDynBuf_t *db, size_t sz);
static __inline void *psDynBufAppendChar(psDynBuf_t *db, char ch)
{
void *loc = psDynBufAppendSize(db, 1);
+
if (loc)
- *(char*)loc = ch;
+ {
+ *(char *) loc = ch;
+ }
return loc;
}
@@ -96,8 +114,11 @@ void *psDynBufAppendUtf8(psDynBuf_t *db, int chr);
static __inline void *psDynBufPrependChar(psDynBuf_t *db, char ch)
{
void *loc = psDynBufPrependSize(db, 1);
+
if (loc)
- *(char*)loc = ch;
+ {
+ *(char *) loc = ch;
+ }
return loc;
}
@@ -105,8 +126,11 @@ static __inline void *psDynBufAppendStr(psDynBuf_t *db, const char *s)
{
size_t len = s ? strlen(s) : 0;
void *loc = psDynBufAppendSize(db, len);
+
if (loc)
+ {
memcpy(loc, s, len);
+ }
return loc;
}
@@ -114,105 +138,119 @@ static __inline void *psDynBufPrependStr(psDynBuf_t *db, const char *s)
{
size_t len = s ? strlen(s) : 0;
void *loc = psDynBufPrependSize(db, len);
+
if (loc)
+ {
memcpy(loc, s, len);
+ }
return loc;
}
static __inline void *psDynBufAppendOctets(psDynBuf_t *db, const void *data,
- size_t len)
+ size_t len)
{
- void *loc = psDynBufAppendSize(db, len);
- if (loc)
- memcpy(loc, data, len);
- return loc;
+ void *loc = psDynBufAppendSize(db, len);
+
+ if (loc)
+ {
+ memcpy(loc, data, len);
+ }
+ return loc;
}
static __inline void *psDynBufAppendBuf(psDynBuf_t *db, const psBuf_t *b)
{
- return psDynBufAppendOctets(db, b->start, b->end - b->start);
+ return psDynBufAppendOctets(db, b->start, b->end - b->start);
}
static __inline void *psDynBufIncorporateDynBuf(psDynBuf_t *db, psDynBuf_t *db2)
{
- size_t len;
- void *data = psDynBufDetach(db2, &len);
- if (data) {
- return psDynBufAppendOctets(db, data, len);
- } else {
- db->err++;
- return NULL;
- }
+ size_t len;
+ void *data = psDynBufDetach(db2, &len);
+
+ if (data)
+ {
+ return psDynBufAppendOctets(db, data, len);
+ }
+ else
+ {
+ db->err++;
+ return NULL;
+ }
}
/* Dynamic buffer subbuffers. */
void *psDynBufSubInit(psDynBuf_t *db, psDynBuf_t *sub, size_t capacity);
void *psDynBufSubInitAt(psDynBuf_t *db, psDynBuf_t *sub, size_t at,
- size_t length);
+ size_t length);
void *psDynBufSubFinish(psDynBuf_t *sub);
/* Note: This variable argument function is currently implemented as a macro. */
-#define psDynBufAppendStrf(ps_dyn_buf_p, ...) \
- do { \
- char tmp; \
- size_t len = 1 + snprintf(&tmp, 1, __VA_ARGS__); \
- char *target = psDynBufAppendSize((ps_dyn_buf_p), len); \
- if (target) { \
- snprintf(target, len, __VA_ARGS__); \
- (ps_dyn_buf_p)->buf.end -= 1; \
- } \
- } while(0)
+# define psDynBufAppendStrf(ps_dyn_buf_p, ...) \
+ do { \
+ char tmp; \
+ size_t len = 1 + snprintf(&tmp, 1, __VA_ARGS__); \
+ char *target = psDynBufAppendSize((ps_dyn_buf_p), len); \
+ if (target) { \
+ snprintf(target, len, __VA_ARGS__); \
+ (ps_dyn_buf_p)->buf.end -= 1; \
+ } \
+ } while (0)
/* Subset of ASN.1 via psDynBuf. */
char *psDynBufAppendAsn1TagGen(psDynBuf_t *db, unsigned char tag,
- const unsigned char *bytes, size_t len);
+ const unsigned char *bytes, size_t len);
char *psDynBufBeginConstructedTag(psDynBuf_t *db, psDynBuf_t *sub);
char *psDynBufEndConstructedTag(psDynBuf_t *sub, unsigned char tag);
static __inline char *psDynBufBeginSequence(psDynBuf_t *db, psDynBuf_t *sub)
{
- return psDynBufBeginConstructedTag(db, sub);
+ return psDynBufBeginConstructedTag(db, sub);
}
static __inline char *psDynBufEndSequence(psDynBuf_t *sub)
{
- return psDynBufEndConstructedTag(sub, 0x30);
+ return psDynBufEndConstructedTag(sub, 0x30);
}
static __inline int32_t psDynBufDetachBuf(psDynBuf_t *db, psBuf_t *target)
{
- size_t sz;
- void *buf;
+ size_t sz;
+ void *buf;
- target->start = target->buf = buf = psDynBufDetach(db, &sz);
- if (!buf) {
- /* Exception path: memory allocation failure. */
- target->size = 0;
- target->end = buf;
- return PS_MEM_FAIL;
- }
+ buf = psDynBufDetach(db, &sz);
+ target->start = target->buf = (unsigned char *) buf;
+ if (!buf)
+ {
+ /* Exception path: memory allocation failure. */
+ target->size = 0;
+ target->end = (unsigned char *) buf;
+ return PS_MEM_FAIL;
+ }
- target->size = sz;
- target->end = ((unsigned char *) buf) + sz;
- return PS_SUCCESS;
+ target->size = sz;
+ target->end = ((unsigned char *) buf) + sz;
+ return PS_SUCCESS;
}
/* Start parsing static data using psParseBuf_t. */
int32_t psParseBufFromStaticData(psParseBuf_t *pb,
- const void *data, size_t len);
+ const void *data, size_t len);
/* Check if there is sufficient data to parse left. */
static __inline int psParseCanRead(const psParseBuf_t *pb, size_t nbytes)
{
- size_t bytes_readable;
+ size_t bytes_readable;
- if (pb->err)
- return 0;
+ if (pb->err)
+ {
+ return 0;
+ }
- bytes_readable = pb->buf.end - pb->buf.start;
- return bytes_readable >= nbytes;
+ bytes_readable = pb->buf.end - pb->buf.start;
+ return bytes_readable >= nbytes;
}
/* Get length of following ASN.1 tag
@@ -221,9 +259,9 @@ static __inline int psParseCanRead(const psParseBuf_t *pb, size_t nbytes)
This is for parsing content of parsebuf as ASN.1 DER data.
If hdrLen_p is non-null, the function also returns the length of tag header.
-*/
+ */
size_t psParseBufGetTagLen(const psParseBuf_t *pb, unsigned char tag,
- size_t *hdrLen_p);
+ size_t *hdrLen_p);
/* Test if there is specific (tag > 0) or any (tag == 0) ASN.1 der
encoding at current parsing location.
return 0 no, 1 yes */
@@ -235,16 +273,16 @@ int psParseBufCanGetTag(const psParseBuf_t *pb, unsigned char tag);
Parsing location will advance once finished with content.
*/
size_t psParseBufTryReadTagSub(const psParseBuf_t *pb,
- psParseBuf_t *content, unsigned char tag);
+ psParseBuf_t *content, unsigned char tag);
/* Read specified (or any) ASN.1 tag at the current parsing location.
it is considered error if read fails.
Parsing location will advance once finished with content. */
size_t psParseBufReadTagSub(psParseBuf_t *pb,
- psParseBuf_t *content, unsigned char tag);
+ psParseBuf_t *content, unsigned char tag);
/* Copy all data from parse buffer. Supports length negotiations.
Fails if parsing errors have been seen. */
int32_t psParseBufCopyAll(const psParseBuf_t *pb, unsigned char *target,
- size_t *targetlen);
+ size_t *targetlen);
/* Return true only if buffers have encountered no parsing errors and
the contents are equal. */
int psParseBufEq(const psParseBuf_t *pb1, const psParseBuf_t *pb2);
@@ -253,12 +291,12 @@ int32_t psParseBufCheckState(const psParseBuf_t *pb);
/* Alias (implemented as a macro) for psParseBufTryReadTagSub used on sequence.
*/
-#define psParseBufTryReadSequenceSub(pb, content) \
- psParseBufTryReadTagSub(pb, content, 0x30)
+# define psParseBufTryReadSequenceSub(pb, content) \
+ psParseBufTryReadTagSub(pb, content, 0x30)
/* Alias (implemented as a macro) for psParseBufReadTagSub used on sequence. */
-#define psParseBufReadSequenceSub(pb, content) \
- psParseBufReadTagSub(pb, content, 0x30)
+# define psParseBufReadSequenceSub(pb, content) \
+ psParseBufReadTagSub(pb, content, 0x30)
/* Skip tag with specified tag id (or 0 for any) if possible.
If tag was skipped, return length in bytes that was skipped. */
@@ -283,17 +321,27 @@ void psParseBufCancel(psParseBuf_t *buf);
/* Skip specified bytes (such as tag with specific contents or non-ASN.1 data)*/
size_t psParseBufTrySkipBytes(psParseBuf_t *pb,
- const unsigned char *bytes,
- size_t numbytes);
+ const unsigned char *bytes,
+ size_t numbytes);
/* Skip specified bytes. Not finding the bytes is an error. */
size_t psParseBufSkipBytes(psParseBuf_t *pb, const unsigned char *bytes,
- size_t numbytes);
+ size_t numbytes);
/* Read given tag and fill-in reference with the content.
Parse buffer is moved to point to the next parsing location. */
size_t psParseBufReadTagRef(psParseBuf_t *pb,
- psBuf_t *ref, unsigned char tag);
+ psBuf_t *ref, unsigned char tag);
+/* Copy data from parse buffer until stopbyte is seen.
+ The target shall be large enough or NULL to inquire size.
+ The stopbyte will be included in bytes copied.
+ This function does not update buffer parsing position. */
+int32_t psParseBufCopyUntilByte(psParseBuf_t *pb, unsigned char stopbyte,
+ unsigned char *target, size_t *targetlen);
+/* Copy specified amount of data from parse buffer without moving buffer
+ parsing position. */
+int32_t psParseBufCopyN(const psParseBuf_t *pb, size_t reqLen,
+ unsigned char *target, size_t *targetlen);
#endif /* _h_PS_BUF */
/* end of file psbuf.h */
diff --git a/core/psmalloc.h b/core/psmalloc.h
index 6a4135b..b79ccde 100644
--- a/core/psmalloc.h
+++ b/core/psmalloc.h
@@ -1,83 +1,87 @@
/**
- * @file psmalloc.h
- * @version $Format:%h%d$
+ * @file psmalloc.h
+ * @version $Format:%h%d$
*
- * Header for psMalloc functions.
+ * Header for psMalloc functions.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_MALLOC
-#define _h_PS_MALLOC
+# define _h_PS_MALLOC
/******************************************************************************/
/*
-*/
-#ifdef PS_UNSUPPORTED_OS
- #include "matrixos.h"
-#else
+ */
+# ifdef PS_UNSUPPORTED_OS
+# include "matrixos.h"
+# else
/******************************************************************************/
/*
-*/
+ */
-#include /* memset, memcpy */
-
-#define MATRIX_NO_POOL (void *)0x0
+# define MATRIX_NO_POOL (void *) 0x0
/* Introduce variables used for memory pooling, so that the compiler does not
give spurious warnings even when memory pools are not supported by the
target operating system. */
-#define PS_POOL_USED(poolVar) PS_VARIABLE_SET_BUT_UNUSED(poolVar)
+# define PS_POOL_USED(poolVar) PS_VARIABLE_SET_BUT_UNUSED(poolVar)
/******************************************************************************/
/*
- Native memory routines
-*/
-#include /* malloc, free, etc... */
+ Native memory routines
+ */
+# include /* malloc, free, etc... */
-#define MAX_MEMORY_USAGE 0
-#define psOpenMalloc() 0
-#define psCloseMalloc()
-#define psDefineHeap(A, B)
-#define psAddPoolCache(A, B)
-#define psMalloc(A, B) malloc(B)
-#define psCalloc(A, B, C) calloc(B, C)
-#define psMallocNoPool malloc
-#define psRealloc(A, B, C) realloc(A, B)
-#define psFree(A, B) free(A)
-#define psMemset memset
-#define psMemcpy memcpy
+# define MAX_MEMORY_USAGE 0
+# define psOpenMalloc() 0
+# define psCloseMalloc()
+# define psDefineHeap(A, B)
+# define psAddPoolCache(A, B)
+# define psMalloc(A, B) malloc(B)
+# define psCalloc(A, B, C) calloc(B, C)
+# define psMallocNoPool malloc
+# define psRealloc(A, B, C) realloc(A, B)
+# define psFree(A, B) free(A)
+# define psFreeNoPool free
typedef int32 psPool_t;
+/* Functions without pool: Add N to the name, omit pool. */
+# define psCallocN(B, C) psCalloc(MATRIX_NO_POOL, (B), (C))
+# define psZallocN(B) psCalloc(MATRIX_NO_POOL, (B), 1)
+# define psMallocN(B) psMalloc(MATRIX_NO_POOL, (B))
+
+/* See psUtil.h for psFreeN, psFreeFRR etc. helper functions. */
+
/******************************************************************************/
-#endif /* !PS_UNSUPPORTED_OS */
-#endif /* _h_PS_MALLOC */
+# endif /* !PS_UNSUPPORTED_OS */
+#endif /* _h_PS_MALLOC */
/******************************************************************************/
diff --git a/core/psnet.h b/core/psnet.h
new file mode 100644
index 0000000..1a71335
--- /dev/null
+++ b/core/psnet.h
@@ -0,0 +1,304 @@
+/* psnet.h
+ *
+ * Basic sockets based networking support.
+ */
+
+/*****************************************************************************
+* Copyright (c) 2007-2017 INSIDE Secure Oy. All Rights Reserved.
+*
+* This confidential and proprietary software may be used only as authorized
+* by a licensing agreement from INSIDE Secure.
+*
+* The entire notice above must be reproduced on all authorized copies that
+* may only be made to the extent permitted by a licensing agreement from
+* INSIDE Secure.
+*****************************************************************************/
+
+#ifndef INCLUDE_GUARD_PSNET_H
+#define INCLUDE_GUARD_PSNET_H
+
+#include
+#include
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef USE_PS_NETWORKING
+/* Use sockets to connect external host and use HTTP protocol to fetch external
+ resource(s). These APIs are optional, because the smallest embedded
+ devices do not have standard networking APIs. */
+
+struct psSocketFunctions; /* Forward reference. */
+struct psSocketTls; /* Extra information of TLS socket. */
+
+typedef enum
+{
+ PS_SOCKET_UNKNOWN,
+ PS_SOCKET_STREAM,
+ PS_SOCKET_DATAGRAM,
+ PS_SOCKET_TLS
+} psSocketType_t;
+
+typedef struct
+{
+# ifdef IMPLEMENT_MATRIXSSL_PSNET
+ int fd;
+# else
+ int internal_fd; /* Use prefix internal_ to discourage access. */
+# endif
+ const struct psSocketFunctions *func;
+ /* Socket type */
+ psSocketType_t type;
+ union
+ {
+ struct psSocketTls *tls;
+ } extra;
+} psSocket_t;
+# define PS_INVALID_SOCKET (NULL)
+
+/* Select access mode and other options for socket.
+ Note: Depending on option, function and operating system, specifying some of
+ these options may affect the executing function only or affect also
+ subsequent socket operations. */
+# define PS_SOCKET_OPTION_NONE 0 /* No options. */
+# define PS_SOCKET_OPTION_BLOCK 1 /* Set socket to blocking mode. */
+# define PS_SOCKET_OPTION_NONBLOCK 2 /* Set socket to non-blocking mode. */
+# define PS_SOCKET_OPTION_NODELAY 4 /* Set nodelay option to socket. */
+# define PS_SOCKET_OPTION_DELAY 8 /* Enable nagle algorithm. */
+# define PS_SOCKET_OPTION_DATAGRAM 16 /* Use datagram protocol (UDP).
+ TCP / stream protocol is the default. */
+/* These are only for psSocketGetOptions(). */
+# define PS_SOCKET_OPTION_STATUS_CONNECTED 65536 /* Connected (not yet supported). */
+# define PS_SOCKET_OPTION_STATUS_ERROR 131072 /* The socket is inoperable. */
+typedef uint32 psSocketOptions_t;
+
+/* send/recv larger than this will need to be performed in multiple parts. */
+# define PS_MAX_SOCKET_SIZE ((~(size_t) 0) >> 1)
+
+/******************************************************************************/
+/* Structure for extending psUrlInteract() API. */
+struct sockaddr;
+struct addrinfo;
+typedef struct psSocketFunctions
+{
+ /* The API matches POSIX standards for interaction with socket,
+ with sockfd replace with pointer to psSocket_t.
+ socklen_t is replaced with size_t. */
+ ssize_t (*psWrite)(psSocket_t *sock, const void *buf, size_t len);
+ ssize_t (*psRead)(psSocket_t *sock, void *buf, size_t len);
+ int (*psIsConnected)(psSocket_t *sock);
+ int (*psIoctl)(psSocket_t *sock, unsigned long request, void *opt_argp);
+ int (*psSetsockopt)(psSocket_t *sock, int level, int optname,
+ const void *optval, size_t optlen);
+ int (*psGetsockopt)(psSocket_t *sock, int level, int optname,
+ void *optval, size_t *optlen);
+ int (*psFcntl)(psSocket_t *sock, int cmd, int opt_argp);
+ /* The provide sock only has func filled in. */
+ int (*psSocket)(psSocket_t *sock, int domain, psSocketType_t type, int protocol,
+ void *typespecific);
+ int (*psShutdown)(psSocket_t *sock, int how);
+ int (*psClose)(psSocket_t *sock);
+ int (*psConnect)(psSocket_t *sock, const struct sockaddr *addr,
+ size_t addrlen);
+ int (*psBind)(psSocket_t *sock, const struct sockaddr *addr,
+ size_t addrlen);
+ int (*psListen)(psSocket_t *sock, int backlog);
+ int (*psAccept)(psSocket_t *listen_sock,
+ struct sockaddr *addr, size_t *addrlen);
+ /* Note: no socket for addres resolution functions. */
+ int (*psGetaddrinfo)(const char *node, const char *service,
+ const struct addrinfo *hints,
+ struct addrinfo **res);
+ void (*psFreeaddrinfo)(struct addrinfo *res);
+ int (*psFd)(const psSocket_t *sock);
+} psSocketFunctions_t;
+
+/*
+ Get default implementation of psSocketFunctions_t. This
+ implementation only provides unencrypted networking.
+ */
+const psSocketFunctions_t *psGetSocketFunctionsDefault(void);
+
+/*
+ Open an outgoing blocking socket connection to a remote host and port.
+ The host can be expressed as DNS name or IP address, and port can be
+ either number (represented as a C string) or name.
+ This function is used for "stream" connections like HTTP or HTTPS
+ protocol.
+
+ @param hostname IPv4 or IPv6 address or name of the target host
+ @param port service name or port number
+ @param socket_p Will be written with the resulting socket handle or
+ INVALID_SOCKET on failure. This handle will be used to interact with
+ the socket using platform dependent function calls.
+ @param state Must be NULL currently. In future this parameter can be
+ used to provide additional information to psUrlInteract and to allow
+ asynchronous requests.
+
+ @retval PS_SUCCESS On successful execution of the function.
+ @retval PS_ARG_FAIL Invalid arguments to the function.
+ @retval PS_HOSTNAME_RESOLUTION Could not resolve hostname or
+ service port.
+ @retval PS_CONNECT Could not connect to the peer.
+ */
+PSPUBLIC int32 psSocketConnect(const char *hostname, const char *port,
+ psSocketOptions_t opts,
+ psSocketType_t type,
+ void *typespecific,
+ const psSocketFunctions_t *func,
+ psSocket_t **socket_p);
+
+/*
+ Open a socket based on pre-existing file descriptor (e.g. connection).
+ This function is used for "stream" connections like HTTP or HTTPS
+ protocol.
+
+ @param fd file descriptor
+ @param socket_p Will be written with the resulting socket handle or
+ INVALID_SOCKET on failure. This handle will be used to interact with
+ the socket using platform dependent function calls.
+
+ @retval PS_SUCCESS On successful execution of the function.
+ @retval PS_ARG_FAIL Invalid arguments to the function.
+ @retval PS_HOSTNAME_RESOLUTION Could not resolve hostname or
+ service port.
+ @retval PS_CONNECT Could not connect to the peer.
+ */
+PSPUBLIC int32 psSocketConnected(int fd,
+ psSocketOptions_t opts,
+ psSocketType_t type,
+ void *typespecific,
+ const psSocketFunctions_t *func,
+ psSocket_t **socket_p);
+
+/*
+ Socket apis
+ */
+PSPUBLIC int32 psSocketListen(const char *hostname, const char *port,
+ int max_backlog, psSocketOptions_t opts,
+ psSocketType_t type,
+ void *typespecific,
+ const psSocketFunctions_t *func,
+ psSocket_t **socketListen_p);
+PSPUBLIC int32 psSocketAccept(psSocket_t *listenfd, psSocketOptions_t opts,
+ psSocket_t **socketAccept_p);
+PSPUBLIC void psSocketShutdown(psSocket_t *sock,
+ psSocketOptions_t opts);
+PSPUBLIC int32 psSocketReadAppendBuf(psSocket_t *sock, psBuf_t *in,
+ psSocketOptions_t opts);
+PSPUBLIC ssize_t psSocketReadData(psSocket_t *sock, void *data,
+ size_t len, psSocketOptions_t opts);
+PSPUBLIC int32 psSocketReadBufferSequence(psSocket_t *sock,
+ void *response,
+ size_t *responseLen,
+ psBuf_t *inputbuf_p,
+ int prefetch,
+ psSocketOptions_t opts);
+PSPUBLIC ssize_t psSocketWriteData(psSocket_t *sock, const void *data,
+ size_t len, psSocketOptions_t opts);
+PSPUBLIC int32 psSocketWriteShiftBuf(psSocket_t *sock, psBuf_t *out,
+ psSocketOptions_t opts);
+PSPUBLIC int32 psSocketSetOptions(psSocket_t *sock, psSocketOptions_t opts);
+PSPUBLIC void psSocketSetBlock(psSocket_t *sock);
+PSPUBLIC void psSocketSetNonblock(psSocket_t *sock);
+PSPUBLIC void psSocketSetNodelay(psSocket_t *sock);
+PSPUBLIC void psSocketSetDelay(psSocket_t *sock);
+PSPUBLIC psSocketOptions_t psSocketGetOptions(psSocket_t *sock);
+PSPUBLIC int psSocketGetFd(psSocket_t *sock);
+
+/* Structure for extending psUrlInteract() API.
+ Currently only used for psSocketFunctions_t pointer. */
+typedef struct
+{
+ /* Describe socket interface. */
+ psSocketType_t type;
+ void *typespecific;
+ const psSocketFunctions_t *func;
+} psUrlInteractState_t;
+
+/* Invoke specified URL (i.e. web address).
+
+ The function allows passing in addition values for HTTP request and response.
+
+ @param method String "GET" or "POST" etc. (see RFC 2616)
+ @param url String like "http://target.addr.com:port/index2.php"
+ @param headers_names_in List of strings containing extra header field names
+ @param headers_values_in List of strings containing extra header field values
+ @param headers_in_count Number of entries in headers_names_in and
+ headers_values_in
+ @param request Pointer to binary data to send to method "POST" or other
+ HTTP methods requiring data to be sent. For methods not not sending data,
+ provide NULL for request and requestLen.
+ @param requestLen Length of binary data to send in bytes.
+ @param headers_names_out List of interesting response fields.
+ @param headers_values_out List of response value. The fields found in server
+ response have their values replaced with server response.
+ @param headers_values_out_length List of lengths of response values.
+ The values returned are adjusted to the actual length returned. The
+ length needs to include space also for zero termination.
+ @param headers_out_count Number of entries in headers_names_out,
+ headers_values_out and headers_values_out_length.
+ @param response Pointer to binary data to send to method "POST".
+ If there is no data to send, provide zero.
+ @param responseLen Pointer to response length. On input the size of
+ memory available, on output the size actually used or amount of output
+ that would have been needed.
+ @param state Must be NULL currently. In future this parameter can be
+ used to provide additional information to psUrlInteract and to allow
+ asynchronous requests.
+
+ @retval PS_SUCCESS On successful execution of the function. The
+ response has been filled with values from HTTP server 200 OK response.
+ @retval 100-505 If the HTTP service responded to the request with
+ return code that is not 200, then the return code and no response will be
+ returned.
+ @retval PS_ARG_FAIL Invalid arguments to the function.
+ @retval PS_HOSTNAME_RESOLUTION Could not resolve hostname or
+ service port.
+ @retval PS_CONNECT Could not connect to the peer.
+ @retval PS_PROTOCOL_FAIL The peer did not respond correctly to the request.
+
+ @note This function currently does not support https URLs. The function is
+ intended for retrieving resources that use http URLs such as CRL or OCSP.
+ (The MatrixSSL provides other functions to deal with SSL/TLS based protocols,
+ such as https.)
+ */
+
+PSPUBLIC int32 psUrlInteract(const char *method,
+ const char *url,
+ const char **headers_names_in,
+ const char **headers_values_in,
+ int headers_in_count,
+ void *request,
+ size_t requestLen,
+ const char **headers_names_out,
+ char **headers_values_out,
+ size_t *headers_values_out_length,
+ int headers_out_count,
+ void *response, size_t *responseLen,
+ psUrlInteractState_t *state);
+
+/* Process HTTP response with input from specified file handle.
+ This function implements part of psUrlInteract, where HTTP response
+ is received.
+ */
+PSPUBLIC int32 psUrlInteractProcessHTTPResponse(
+ psPool_t *pool,
+ psSocket_t *sock,
+ const char **headers_names_out,
+ char **headers_values_out,
+ size_t *headers_values_out_length,
+ int headers_out_count,
+ void *response,
+ size_t *responseLen,
+ psUrlInteractState_t *state);
+
+#endif /* USE_PS_NETWORKING */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* INCLUDE_GUARD_PSNET_H */
+
+/* end of file psnet.h */
diff --git a/crypto/Makefile b/crypto/Makefile
index e53469f..1dc6a86 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -3,7 +3,7 @@
# 'make' builds debug (Default).
# 'make gold' builds optimized.
#
-# Copyright (c) 2013-2016 INSIDE Secure Corporation. All Rights Reserved.
+# Copyright (c) 2013-2017 INSIDE Secure Corporation. All Rights Reserved.
#
MATRIXSSL_ROOT:=..
@@ -28,12 +28,14 @@ SRC:=\
digest/md4.c \
digest/md2.c \
keyformat/asn1.c \
+ keyformat/asn1fmt.c \
keyformat/base64.c \
keyformat/crl.c \
keyformat/pkcs.c \
keyformat/x509.c \
layer/matrix.c \
math/pstm.c \
+ math/pstmnt.c \
math/pstm_montgomery_reduce.c \
math/pstm_mul_comba.c \
math/pstm_sqr_comba.c \
@@ -59,6 +61,29 @@ SRC+=\
endif
#endif
+# Deal with a build flags special case:
+# Comba multiplier and squaring requires all registers it can get on x86.
+# These extra compilation definitions make those registers available for
+# these files to use.
+COMBA_MULTIPLIER_DEBUG=ON # Default on non-x86 platforms (debug build).
+ifneq (,$(findstring i386-,$(CCARCH)))
+COMBA_MULTIPLIER_DEBUG=OFF
+endif
+ifneq (,$(findstring i486-,$(CCARCH)))
+COMBA_MULTIPLIER_DEBUG=OFF
+endif
+ifneq (,$(findstring i586-,$(CCARCH)))
+COMBA_MULTIPLIER_DEBUG=OFF
+endif
+ifneq (,$(findstring i686-,$(CCARCH)))
+COMBA_MULTIPLIER_DEBUG=OFF
+endif
+ifeq '$(COMBA_MULTIPLIER_DEBUG)' 'OFF'
+CFLAGS_BASE:=$(CFLAGS)
+math/pstm_mul_comba.o: CFLAGS=$(CFLAGS_BASE) -fomit-frame-pointer
+math/pstm_sqr_comba.o: CFLAGS=$(CFLAGS_BASE) -fomit-frame-pointer
+endif
+
# Generated files
STATIC:=libcrypt_s.a
diff --git a/crypto/cryptoApi.h b/crypto/cryptoApi.h
index fd3ad33..e1ab7c2 100644
--- a/crypto/cryptoApi.h
+++ b/crypto/cryptoApi.h
@@ -1,525 +1,569 @@
/**
- * @file cryptoApi.h
- * @version $Format:%h%d$
+ * @file cryptoApi.h
+ * @version $Format:%h%d$
*
- * Prototypes for the Matrix crypto public APIs.
+ * Prototypes for the Matrix crypto public APIs.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_CRYPTOAPI
-#define _h_PS_CRYPTOAPI
+# define _h_PS_CRYPTOAPI
-#ifdef __cplusplus
+# ifdef __cplusplus
extern "C" {
-#endif
+# endif
-#include "../core/coreApi.h" /* Must be included first */
-#ifdef MATRIX_CONFIGURATION_INCDIR_FIRST
-#include /* Must be included second */
-#else
-#include "cryptoConfig.h" /* Must be included second */
-#endif
-#include "cryptolib.h"
+# include "../core/coreApi.h" /* Must be included first */
+# ifdef MATRIX_CONFIGURATION_INCDIR_FIRST
+# include /* Must be included second */
+# else
+# include "cryptoConfig.h" /* Must be included second */
+# endif
+# include "cryptolib.h"
+
+/* Use optional constant time modular exponentiation algorithm.
+ The setting is set here unless explicitly requested not to. */
+# ifndef USE_NON_CONSTANT_TIME_MODEXP
+# define USE_CONSTANT_TIME_MODEXP
+# endif
/******************************************************************************/
/**
- Public return codes.
- These are in addition to those in core/
- Failure codes MUST be < 0
- @note The range for crypto error codes must be between -30 and -49
-*/
-#define PS_PARSE_FAIL -31
+ Public return codes.
+ These are in addition to those in core/
+ Failure codes MUST be < 0
+ @note The range for crypto error codes must be between -30 and -49
+ */
+# define PS_PARSE_FAIL -31
/**
- @note Any future additions to certificate authentication failures
- must be carried through to MatrixSSL code
-*/
-#define PS_CERT_AUTH_PASS PS_TRUE
-#define PS_CERT_AUTH_FAIL_BC -32 /* BasicConstraint failure */
-#define PS_CERT_AUTH_FAIL_DN -33 /* DistinguishedName failure */
-#define PS_CERT_AUTH_FAIL_SIG -34 /* Signature validation failure */
-#define PS_CERT_AUTH_FAIL_REVOKED -35 /* Revoked via CRL or OCSP */
-#define PS_CERT_AUTH_FAIL -36 /* Generic cert auth fail */
-#define PS_CERT_AUTH_FAIL_EXTENSION -37 /* extension permission problem */
-#define PS_CERT_AUTH_FAIL_PATH_LEN -38 /* pathLen exceeded */
-#define PS_CERT_AUTH_FAIL_AUTHKEY -39 /* subjectKeyid != issuer authKeyid */
+ @note Any future additions to certificate authentication failures
+ must be carried through to MatrixSSL code
+ */
+# define PS_CERT_AUTH_PASS PS_TRUE
+# define PS_CERT_AUTH_FAIL_BC -32 /* BasicConstraint failure */
+# define PS_CERT_AUTH_FAIL_DN -33 /* DistinguishedName failure */
+# define PS_CERT_AUTH_FAIL_SIG -34 /* Signature validation failure */
+# define PS_CERT_AUTH_FAIL_REVOKED -35 /* Revoked via CRL or OCSP */
+# define PS_CERT_AUTH_FAIL -36 /* Generic cert auth fail */
+# define PS_CERT_AUTH_FAIL_EXTENSION -37 /* extension permission problem */
+# define PS_CERT_AUTH_FAIL_PATH_LEN -38 /* pathLen exceeded */
+# define PS_CERT_AUTH_FAIL_AUTHKEY -39 /* subjectKeyid != issuer authKeyid */
-#define PS_SIGNATURE_MISMATCH -40 /* Algorithms all work but sig not a match */
+# define PS_SIGNATURE_MISMATCH -40 /* Algorithms all work but sig not a match */
-#define PS_AUTH_FAIL -41 /* An AEAD or HASH authentication fail */
+# define PS_AUTH_FAIL -41 /* An AEAD or HASH authentication fail */
+# define PS_MESSAGE_UNSUPPORTED -42 /* Request/Response format/type is unsupported. */
+# define PS_VERSION_UNSUPPORTED -43 /* Request/Response version is unsupported. */
+
+/** Public return value codes for OCSP.
+
+ These are additional possible return values from OCSP parsing.
+ Currently these values are for OCSP Response and thus map directly to
+ RFC 6960, section 4.2.1 (values -86 ... -81 correspond to 1 ... 6.)
+ When one of these values is returned by psOcspParseResponse(), function
+ psOcspResponseGetStatus() can be used to map it into an OCSP Response Status
+ code.
+
+ @note The additional range used by OCSP error codes is between -80 and -89.
+ */
+# define PS_OCSP_UNAUTHORIZED -81 /* Request unauthorized */
+# define PS_OCSP_SIG_REQUIRED -82 /* Must sign the request */
+/* -83 Is reserved for future extensions. */
+# define PS_OCSP_TRY_LATER -84 /* Try again later */
+# define PS_OCSP_INTERNAL_ERROR -85 /* Internal error in issuer */
+# define PS_OCSP_MALFORMED_REQUEST -86 /* Illegal confirmation request */
+
+/******************************************************************************/
/* Set as authStatusFlags to certificate callback when authStatus
- is PS_CERT_AUTH_FAIL_EXTENSION */
-#define PS_CERT_AUTH_FAIL_KEY_USAGE_FLAG 0x01
-#define PS_CERT_AUTH_FAIL_EKU_FLAG 0x02
-#define PS_CERT_AUTH_FAIL_SUBJECT_FLAG 0x04
-#define PS_CERT_AUTH_FAIL_DATE_FLAG 0x08
+ is PS_CERT_AUTH_FAIL_EXTENSION */
+# define PS_CERT_AUTH_FAIL_KEY_USAGE_FLAG 0x01
+# define PS_CERT_AUTH_FAIL_EKU_FLAG 0x02
+# define PS_CERT_AUTH_FAIL_SUBJECT_FLAG 0x04
+# define PS_CERT_AUTH_FAIL_DATE_FLAG 0x08
+/* Set as authStatusFlags to certificate callback when authStatus
+ is PS_CERT_AUTH_FAIL_PATH_LEN. This flag indicates that the maximum
+ peer cert chain verification depth specified in session options
+ was exceeded.
+*/
+# define PS_CERT_AUTH_FAIL_VERIFY_DEPTH_FLAG 0x10
/******************************************************************************/
/**
- Build the configuration string with the relevant build options for
- runtime validation of compile-time configuration.
-*/
-#if defined PSTM_X86 || defined PSTM_X86_64 || defined PSTM_ARM || \
- defined PSTM_MIPS
- #define PSTM_ASM_CONFIG_STR "Y"
-#else
- #define PSTM_ASM_CONFIG_STR "N"
-#endif
-#ifdef PSTM_64BIT
- #define PSTM_64_CONFIG_STR "Y"
-#else
- #define PSTM_64_CONFIG_STR "N"
-#endif
-#ifdef USE_AESNI_CRYPTO
- #define AESNI_CONFIG_STR "Y"
-#else
- #define AESNI_CONFIG_STR "N"
-#endif
- #define HW_PKA_CONFIG_STR "N"
- #define PKCS11_CONFIG_STR "N"
- #define FIPS_CONFIG_STR "N"
+ Build the configuration string with the relevant build options for
+ runtime validation of compile-time configuration.
+ */
+# if defined PSTM_X86 || defined PSTM_X86_64 || defined PSTM_ARM || \
+ defined PSTM_MIPS
+# define PSTM_ASM_CONFIG_STR "Y"
+# else
+# define PSTM_ASM_CONFIG_STR "N"
+# endif
+# ifdef PSTM_64BIT
+# define PSTM_64_CONFIG_STR "Y"
+# else
+# define PSTM_64_CONFIG_STR "N"
+# endif
+# ifdef USE_AESNI_CRYPTO
+# define AESNI_CONFIG_STR "Y"
+# else
+# define AESNI_CONFIG_STR "N"
+# endif
+# define HW_PKA_CONFIG_STR "N"
+# define PKCS11_CONFIG_STR "N"
+# define FIPS_CONFIG_STR "N"
-#define PSCRYPTO_CONFIG \
- "Y" \
- PSTM_ASM_CONFIG_STR \
- PSTM_64_CONFIG_STR \
- AESNI_CONFIG_STR \
- HW_PKA_CONFIG_STR \
- PKCS11_CONFIG_STR \
- FIPS_CONFIG_STR \
- PSCORE_CONFIG
+# define PSCRYPTO_CONFIG \
+ "Y" \
+ PSTM_ASM_CONFIG_STR \
+ PSTM_64_CONFIG_STR \
+ AESNI_CONFIG_STR \
+ HW_PKA_CONFIG_STR \
+ PKCS11_CONFIG_STR \
+ FIPS_CONFIG_STR \
+ PSCORE_CONFIG
/******************************************************************************/
/*
- Crypto module open/close
-*/
+ Crypto module open/close
+ */
PSPUBLIC int32_t psCryptoOpen(const char *config);
PSPUBLIC void psCryptoClose(void);
/******************************************************************************/
/*
- Abstract Cipher API
- Handles symmetric crypto, aead ciphers, hashes and macs.
-*/
-typedef enum {
+ Crypto module control (only available with CLS crypto)
+ */
- AES_CBC_ENC = 1,
- AES_CBC_DEC,
- AES_GCM_ENC,
- AES_GCM_DEC,
- CHACHA20_POLY1305_ENC,
- CHACHA20_POLY1305_DEC,
- ARC4,
- DES3,
- IDEA,
- SEED,
+/******************************************************************************/
+/*
+ Abstract Cipher API
+ Handles symmetric crypto, aead ciphers, hashes and macs.
+ */
+typedef enum
+{
- HASH_MD2,
- HASH_MD5,
- HASH_SHA1,
- HASH_MD5SHA1,
- HASH_SHA256,
- HASH_SHA384,
- HASH_SHA512,
+ AES_CBC_ENC = 1,
+ AES_CBC_DEC,
+ AES_GCM_ENC,
+ AES_GCM_DEC,
+ CHACHA20_POLY1305_ENC,
+ CHACHA20_POLY1305_DEC,
+ ARC4,
+ DES3,
+ IDEA,
+ SEED,
- HMAC_MD5,
- HMAC_SHA1,
- HMAC_SHA256,
- HMAC_SHA384,
+ HASH_MD2,
+ HASH_MD5,
+ HASH_SHA1,
+ HASH_MD5SHA1,
+ HASH_SHA256,
+ HASH_SHA384,
+ HASH_SHA512,
+
+ HMAC_MD5,
+ HMAC_SHA1,
+ HMAC_SHA256,
+ HMAC_SHA384,
} psCipherType_e;
/******************************************************************************/
/*
- Symmetric Cipher Algorithms
-*/
-#ifdef USE_AES
+ Symmetric Cipher Algorithms
+ */
+# ifdef USE_AES
-#define PS_AES_ENCRYPT 0x1
-#define PS_AES_DECRYPT 0x2
+# define PS_AES_ENCRYPT 0x1
+# define PS_AES_DECRYPT 0x2
-#ifdef USE_AES_BLOCK
+# ifdef USE_AES_BLOCK
/******************************************************************************/
PSPUBLIC int32_t psAesInitBlockKey(psAesKey_t *key,
- const unsigned char ckey[AES_MAXKEYLEN], uint8_t keylen,
- uint32_t flags);
+ const unsigned char ckey[AES_MAXKEYLEN], uint8_t keylen,
+ uint32_t flags);
PSPUBLIC void psAesEncryptBlock(psAesKey_t *key, const unsigned char *pt,
- unsigned char *ct);
+ unsigned char *ct);
PSPUBLIC void psAesDecryptBlock(psAesKey_t *key, const unsigned char *ct,
- unsigned char *pt);
+ unsigned char *pt);
PSPUBLIC void psAesClearBlockKey(psAesKey_t *key);
-#endif
+# endif
-#ifdef USE_AES_CBC
+# ifdef USE_AES_CBC
/******************************************************************************/
PSPUBLIC int32_t psAesInitCBC(psAesCbc_t *ctx,
- const unsigned char IV[AES_IVLEN],
- const unsigned char key[AES_MAXKEYLEN], uint8_t keylen,
- uint32_t flags);
+ const unsigned char IV[AES_IVLEN],
+ const unsigned char key[AES_MAXKEYLEN], uint8_t keylen,
+ uint32_t flags);
PSPUBLIC void psAesDecryptCBC(psAesCbc_t *ctx,
- const unsigned char *ct, unsigned char *pt,
- uint32_t len);
+ const unsigned char *ct, unsigned char *pt,
+ uint32_t len);
PSPUBLIC void psAesEncryptCBC(psAesCbc_t *ctx,
- const unsigned char *pt, unsigned char *ct,
- uint32_t len);
+ const unsigned char *pt, unsigned char *ct,
+ uint32_t len);
PSPUBLIC void psAesClearCBC(psAesCbc_t *ctx);
-#endif
+# endif
-#ifdef USE_AES_GCM
+# ifdef USE_AES_GCM
/******************************************************************************/
PSPUBLIC int32_t psAesInitGCM(psAesGcm_t *ctx,
- const unsigned char key[AES_MAXKEYLEN], uint8_t keylen);
+ const unsigned char key[AES_MAXKEYLEN], uint8_t keylen);
PSPUBLIC void psAesReadyGCM(psAesGcm_t *ctx,
- const unsigned char IV[AES_IVLEN],
- const unsigned char *aad, uint16_t aadLen);
-PSPUBLIC int32_t psAesReadyGCMRandomIV(psAesGcm_t *ctx,
- unsigned char IV[12],
- const unsigned char *aad, uint16_t aadLen,
- void *poolUserPtr);
+ const unsigned char IV[AES_IVLEN],
+ const unsigned char *aad, psSize_t aadLen);
+PSPUBLIC int32_t psAesReadyGCMRandomIV(psAesGcm_t * ctx,
+ unsigned char IV[12],
+ const unsigned char *aad, psSize_t aadLen,
+ void *poolUserPtr);
PSPUBLIC void psAesEncryptGCM(psAesGcm_t *ctx,
- const unsigned char *pt, unsigned char *ct,
- uint32_t len);
+ const unsigned char *pt, unsigned char *ct,
+ uint32_t len);
PSPUBLIC int32_t psAesDecryptGCM(psAesGcm_t *ctx,
- const unsigned char *ct, uint32_t ctLen,
- unsigned char *pt, uint32_t ptLen);
+ const unsigned char *ct, uint32_t ctLen,
+ unsigned char *pt, uint32_t ptLen);
PSPUBLIC int32_t psAesDecryptGCM2(psAesGcm_t *ctx,
- const unsigned char *ct,
- unsigned char *pt, uint32_t len,
- const unsigned char *tag, uint32_t tagLen);
+ const unsigned char *ct,
+ unsigned char *pt, uint32_t len,
+ const unsigned char *tag, uint32_t tagLen);
PSPUBLIC void psAesDecryptGCMtagless(psAesGcm_t *ctx,
- const unsigned char *ct, unsigned char *pt,
- uint32_t len);
-PSPUBLIC void psAesGetGCMTag(psAesGcm_t *ctx,
- uint8_t tagBytes, unsigned char tag[AES_BLOCKLEN]);
+ const unsigned char *ct, unsigned char *pt,
+ uint32_t len);
+PSPUBLIC void psAesGetGCMTag(psAesGcm_t * ctx,
+ uint8_t tagBytes, unsigned char tag[AES_BLOCKLEN]);
PSPUBLIC void psAesClearGCM(psAesGcm_t *ctx);
-#endif /* USE_AES_GCM */
+# endif /* USE_AES_GCM */
-#endif /* USE_AES */
+# endif /* USE_AES */
-#ifdef USE_CHACHA20_POLY1305
+# ifdef USE_CHACHA20_POLY1305
/******************************************************************************/
PSPUBLIC int32_t psChacha20Poly1305Init(psChacha20Poly1305_t *ctx,
- const unsigned char key[crypto_aead_chacha20poly1305_KEYBYTES],
- uint8_t keylen);
+ const unsigned char key[crypto_aead_chacha20poly1305_KEYBYTES],
+ uint8_t keylen);
PSPUBLIC void psChacha20Poly1305Ready(psChacha20Poly1305_t *ctx,
- const unsigned char IV[crypto_aead_chacha20poly1305_NPUBBYTES+4],
- const unsigned char *aad, uint16_t aadLen);
+ const unsigned char IV[crypto_aead_chacha20poly1305_NPUBBYTES + 4],
+ const unsigned char *aad, psSize_t aadLen);
PSPUBLIC void psChacha20Poly1305Encrypt(psChacha20Poly1305_t *ctx,
- const unsigned char *pt, unsigned char *ct,uint32_t len);
+ const unsigned char *pt, unsigned char *ct, uint32_t len);
PSPUBLIC int32_t psChacha20Poly1305Decrypt(psChacha20Poly1305_t *ctx,
- const unsigned char *ct, uint32_t ctLen,
- unsigned char *pt, uint32_t ptLen);
+ const unsigned char *ct, uint32_t ctLen,
+ unsigned char *pt, uint32_t ptLen);
PSPUBLIC void psChacha20Poly1305DecryptTagless(psChacha20Poly1305_t *ctx,
- const unsigned char *ct, unsigned char *pt,
- uint32_t len);
+ const unsigned char *ct, unsigned char *pt,
+ uint32_t len);
-PSPUBLIC void psChacha20Poly1305GetTag(psChacha20Poly1305_t *ctx,
- uint8_t tagBytes,
- unsigned char tag[crypto_aead_chacha20poly1305_ABYTES]);
+PSPUBLIC void psChacha20Poly1305GetTag(psChacha20Poly1305_t * ctx,
+ uint8_t tagBytes,
+ unsigned char tag[crypto_aead_chacha20poly1305_ABYTES]);
PSPUBLIC void psChacha20Poly1305Clear(psChacha20Poly1305_t *ctx);
-#endif
+# endif
-#ifdef USE_3DES
+# ifdef USE_3DES
/******************************************************************************/
PSPUBLIC int32_t psDes3Init(psDes3_t *ctx, const unsigned char IV[DES3_IVLEN],
- const unsigned char key[DES3_KEYLEN]);
+ const unsigned char key[DES3_KEYLEN]);
PSPUBLIC void psDes3Decrypt(psDes3_t *ctx, const unsigned char *ct,
- unsigned char *pt, uint32_t len);
+ unsigned char *pt, uint32_t len);
PSPUBLIC void psDes3Encrypt(psDes3_t *ctx, const unsigned char *pt,
- unsigned char *ct, uint32_t len);
+ unsigned char *ct, uint32_t len);
PSPUBLIC void psDes3Clear(psDes3_t *ctx);
-#endif
+# endif
/******************************************************************************/
/*
- Hash Digest Algorithms
-*/
-#ifdef USE_MD5
+ Hash Digest Algorithms
+ */
+# ifdef USE_MD5
/******************************************************************************/
static __inline void psMd5PreInit(psMd5_t *md5)
{
- /* Nothing to pre-initialize for native crypto. */
+ /* Nothing to pre-initialize for native crypto. */
}
PSPUBLIC int32_t psMd5Init(psMd5_t *md5);
PSPUBLIC void psMd5Update(psMd5_t *md5, const unsigned char *buf, uint32_t len);
-PSPUBLIC void psMd5Final(psMd5_t *md, unsigned char hash[MD5_HASHLEN]);
-#endif
+PSPUBLIC void psMd5Final(psMd5_t * md, unsigned char hash[MD5_HASHLEN]);
+# endif
-#ifdef USE_SHA1
+# ifdef USE_SHA1
/******************************************************************************/
/* Pre-init should be called for uninitialized, e.g. function local
digest contexts, before calling the initialization function. */
static __inline void psSha1PreInit(psSha1_t *sha1)
{
- /* Nothing to pre-initialize for native crypto. */
+ /* Nothing to pre-initialize for native crypto. */
}
PSPUBLIC int32_t psSha1Init(psSha1_t *sha1);
PSPUBLIC void psSha1Update(psSha1_t *sha1,
- const unsigned char *buf, uint32_t len);
-PSPUBLIC void psSha1Final(psSha1_t *sha1, unsigned char hash[SHA1_HASHLEN]);
+ const unsigned char *buf, uint32_t len);
+PSPUBLIC void psSha1Final(psSha1_t * sha1, unsigned char hash[SHA1_HASHLEN]);
static __inline void psSha1Sync(psSha1_t *ctx, int sync_all)
{
}
static __inline void psSha1Cpy(psSha1_t *d, const psSha1_t *s)
{
- memcpy(d, s, sizeof(psSha1_t));
+ memcpy(d, s, sizeof(psSha1_t));
}
-#endif /* USE_SHA1 */
+# endif /* USE_SHA1 */
-#ifdef USE_MD5SHA1
+# ifdef USE_MD5SHA1
/******************************************************************************/
/* Pre-init should be called for uninitialized, e.g. function local
digest contexts, before calling the initialization function. */
static __inline void psMd5Sha1PreInit(psMd5Sha1_t *md)
{
- /* Nothing to pre-initialize for native crypto. */
+ /* Nothing to pre-initialize for native crypto. */
}
PSPUBLIC int32_t psMd5Sha1Init(psMd5Sha1_t *md);
PSPUBLIC void psMd5Sha1Update(psMd5Sha1_t *md,
- const unsigned char *buf, uint32_t len);
-PSPUBLIC void psMd5Sha1Final(psMd5Sha1_t *md,
- unsigned char hash[MD5SHA1_HASHLEN]);
+ const unsigned char *buf, uint32_t len);
+PSPUBLIC void psMd5Sha1Final(psMd5Sha1_t * md,
+ unsigned char hash[MD5SHA1_HASHLEN]);
static __inline void psMd5Sha1Sync(psMd5Sha1_t *ctx, int sync_all)
{
}
static __inline void psMd5Sha1Cpy(psMd5Sha1_t *d, const psMd5Sha1_t *s)
{
- memcpy(d, s, sizeof(psMd5Sha1_t));
+ memcpy(d, s, sizeof(psMd5Sha1_t));
}
-#endif /* USE_MD5SHA1 */
+# endif /* USE_MD5SHA1 */
-#ifdef USE_SHA256
+# ifdef USE_SHA256
/******************************************************************************/
/* Pre-init should be called for uninitialized, e.g. function local
digest contexts, before calling the initialization function. */
static __inline void psSha256PreInit(psSha256_t *sha256)
{
- /* Nothing to pre-initialize for native crypto. */
+ /* Nothing to pre-initialize for native crypto. */
}
PSPUBLIC int32_t psSha256Init(psSha256_t *sha256);
PSPUBLIC void psSha256Update(psSha256_t *sha256,
- const unsigned char *buf, uint32_t len);
-PSPUBLIC void psSha256Final(psSha256_t *sha256,
- unsigned char hash[SHA256_HASHLEN]);
-static __inline void psSha256Sync(psSha256_t * md, int sync_all)
+ const unsigned char *buf, uint32_t len);
+PSPUBLIC void psSha256Final(psSha256_t * sha256,
+ unsigned char hash[SHA256_HASHLEN]);
+static __inline void psSha256Sync(psSha256_t *md, int sync_all)
{
}
-static __inline void psSha256Cpy(psSha256_t * d, const psSha256_t * s)
+static __inline void psSha256Cpy(psSha256_t *d, const psSha256_t *s)
{
- memcpy(d, s, sizeof(psSha256_t));
+ memcpy(d, s, sizeof(psSha256_t));
}
-#endif /* USE_SHA256 */
+# endif /* USE_SHA256 */
/******************************************************************************/
-#ifdef USE_SHA384
+# ifdef USE_SHA384
/* Pre-init should be called for uninitialized, e.g. function local
digest contexts, before calling the initialization function. */
static __inline void psSha384PreInit(psSha384_t *sha384)
{
- /* Nothing to pre-initialize for native crypto. */
+ /* Nothing to pre-initialize for native crypto. */
}
PSPUBLIC int32_t psSha384Init(psSha384_t *sha384);
PSPUBLIC void psSha384Update(psSha384_t *sha384,
- const unsigned char *buf, uint32_t len);
-PSPUBLIC void psSha384Final(psSha384_t *sha384,
- unsigned char hash[SHA384_HASHLEN]);
-static __inline void psSha384Sync(psSha384_t * md, int sync_all)
+ const unsigned char *buf, uint32_t len);
+PSPUBLIC void psSha384Final(psSha384_t * sha384,
+ unsigned char hash[SHA384_HASHLEN]);
+static __inline void psSha384Sync(psSha384_t *md, int sync_all)
{
}
-static __inline void psSha384Cpy(psSha384_t * d, const psSha384_t * s)
+static __inline void psSha384Cpy(psSha384_t *d, const psSha384_t *s)
{
- memcpy(d, s, sizeof(psSha384_t));
+ memcpy(d, s, sizeof(psSha384_t));
}
-#endif /* USE_SHA384 */
+# endif /* USE_SHA384 */
-#ifdef USE_SHA512
+# ifdef USE_SHA512
/******************************************************************************/
/* Pre-init should be called for uninitialized, e.g. function local
digest contexts, before calling the initialization function. */
static __inline void psSha512PreInit(psSha512_t *sha512)
{
- /* Nothing to pre-initialize for native crypto. */
+ /* Nothing to pre-initialize for native crypto. */
}
PSPUBLIC int32_t psSha512Init(psSha512_t *md);
PSPUBLIC void psSha512Update(psSha512_t *md,
- const unsigned char *buf, uint32_t len);
-PSPUBLIC void psSha512Final(psSha512_t *md,
- unsigned char hash[SHA512_HASHLEN]);
-static __inline void psSha512Sync(psSha512_t * md, int sync_all)
+ const unsigned char *buf, uint32_t len);
+PSPUBLIC void psSha512Final(psSha512_t * md,
+ unsigned char hash[SHA512_HASHLEN]);
+static __inline void psSha512Sync(psSha512_t *md, int sync_all)
{
}
-static __inline void psSha512Cpy(psSha512_t * d, const psSha512_t * s)
+static __inline void psSha512Cpy(psSha512_t *d, const psSha512_t *s)
{
- memcpy(d, s, sizeof(psSha512_t));
+ memcpy(d, s, sizeof(psSha512_t));
}
-#endif /* USE_SHA512 */
+# endif /* USE_SHA512 */
/******************************************************************************/
/*
- HMAC Algorithms
-*/
+ HMAC Algorithms
+ */
/* Generic HMAC algorithms, specify cipher by type. */
PSPUBLIC int32_t psHmacInit(psHmac_t *ctx, psCipherType_e type,
- const unsigned char *key, uint16_t keyLen);
+ const unsigned char *key, psSize_t keyLen);
PSPUBLIC void psHmacUpdate(psHmac_t *ctx,
- const unsigned char *buf, uint32_t len);
-PSPUBLIC void psHmacFinal(psHmac_t *ctx,
- unsigned char hash[MAX_HASHLEN]);
+ const unsigned char *buf, uint32_t len);
+PSPUBLIC void psHmacFinal(psHmac_t * ctx,
+ unsigned char hash[MAX_HASHLEN]);
-#ifdef USE_HMAC_MD5
+# ifdef USE_HMAC_MD5
/******************************************************************************/
-PSPUBLIC int32_t psHmacMd5(const unsigned char *key, uint16_t keyLen,
- const unsigned char *buf, uint32_t len,
- unsigned char hash[MD5_HASHLEN],
- unsigned char *hmacKey, uint16_t *hmacKeyLen);
+PSPUBLIC int32_t psHmacMd5(const unsigned char *key, psSize_t keyLen,
+ const unsigned char *buf, uint32_t len,
+ unsigned char hash[MD5_HASHLEN],
+ unsigned char *hmacKey, psSize_t * hmacKeyLen);
PSPUBLIC int32_t psHmacMd5Init(psHmacMd5_t *ctx,
- const unsigned char *key, uint16_t keyLen);
+ const unsigned char *key, psSize_t keyLen);
PSPUBLIC void psHmacMd5Update(psHmacMd5_t *ctx,
- const unsigned char *buf, uint32_t len);
-PSPUBLIC void psHmacMd5Final(psHmacMd5_t *ctx,
- unsigned char hash[MD5_HASHLEN]);
-#endif
+ const unsigned char *buf, uint32_t len);
+PSPUBLIC void psHmacMd5Final(psHmacMd5_t * ctx,
+ unsigned char hash[MD5_HASHLEN]);
+# endif
-#ifdef USE_HMAC_SHA1
+# ifdef USE_HMAC_SHA1
/******************************************************************************/
-PSPUBLIC int32_t psHmacSha1(const unsigned char *key, uint16_t keyLen,
- const unsigned char *buf, uint32_t len,
- unsigned char hash[SHA1_HASHLEN],
- unsigned char *hmacKey, uint16_t *hmacKeyLen);
-#ifdef USE_HMAC_TLS
+PSPUBLIC int32_t psHmacSha1(const unsigned char *key, psSize_t keyLen,
+ const unsigned char *buf, uint32_t len,
+ unsigned char hash[SHA1_HASHLEN],
+ unsigned char *hmacKey, psSize_t * hmacKeyLen);
+# ifdef USE_HMAC_TLS
PSPUBLIC int32_t psHmacSha1Tls(const unsigned char *key, uint32_t keyLen,
- const unsigned char *buf1, uint32_t len1,
- const unsigned char *buf2, uint32_t len2,
- const unsigned char *buf3, uint32_t len3,
- uint32_t len3_alt, unsigned char *hmac);
-#endif
+ const unsigned char *buf1, uint32_t len1,
+ const unsigned char *buf2, uint32_t len2,
+ const unsigned char *buf3, uint32_t len3,
+ uint32_t len3_alt, unsigned char *hmac);
+# endif
PSPUBLIC int32_t psHmacSha1Init(psHmacSha1_t *ctx,
- const unsigned char *key, uint16_t keyLen);
+ const unsigned char *key, psSize_t keyLen);
PSPUBLIC void psHmacSha1Update(psHmacSha1_t *ctx,
- const unsigned char *buf, uint32_t len);
-PSPUBLIC void psHmacSha1Final(psHmacSha1_t *ctx,
- unsigned char hash[SHA1_HASHLEN]);
-#endif
+ const unsigned char *buf, uint32_t len);
+PSPUBLIC void psHmacSha1Final(psHmacSha1_t * ctx,
+ unsigned char hash[SHA1_HASHLEN]);
+# endif
-#ifdef USE_HMAC_SHA256
+# ifdef USE_HMAC_SHA256
/******************************************************************************/
-PSPUBLIC int32_t psHmacSha256(const unsigned char *key, uint16_t keyLen,
- const unsigned char *buf, uint32_t len,
- unsigned char hash[SHA256_HASHLEN],
- unsigned char *hmacKey, uint16_t *hmacKeyLen);
-#ifdef USE_HMAC_TLS
+PSPUBLIC int32_t psHmacSha256(const unsigned char *key, psSize_t keyLen,
+ const unsigned char *buf, uint32_t len,
+ unsigned char hash[SHA256_HASHLEN],
+ unsigned char *hmacKey, psSize_t * hmacKeyLen);
+# ifdef USE_HMAC_TLS
PSPUBLIC int32 psHmacSha2Tls(const unsigned char *key, uint32 keyLen,
- const unsigned char *buf1, uint32 len1,
- const unsigned char *buf2, uint32 len2,
- const unsigned char *buf3, uint32 len3,
- uint32 len3_alt, unsigned char *hmac,
- uint32 hashSize);
-#endif
+ const unsigned char *buf1, uint32 len1,
+ const unsigned char *buf2, uint32 len2,
+ const unsigned char *buf3, uint32 len3,
+ uint32 len3_alt, unsigned char *hmac,
+ uint32 hashSize);
+# endif
PSPUBLIC int32_t psHmacSha256Init(psHmacSha256_t *ctx,
- const unsigned char *key, uint16_t keyLen);
+ const unsigned char *key, psSize_t keyLen);
PSPUBLIC void psHmacSha256Update(psHmacSha256_t *ctx,
- const unsigned char *buf, uint32_t len);
-PSPUBLIC void psHmacSha256Final(psHmacSha256_t *ctx,
- unsigned char hash[SHA256_HASHLEN]);
-#endif
-#ifdef USE_HMAC_SHA384
+ const unsigned char *buf, uint32_t len);
+PSPUBLIC void psHmacSha256Final(psHmacSha256_t * ctx,
+ unsigned char hash[SHA256_HASHLEN]);
+# endif
+# ifdef USE_HMAC_SHA384
/******************************************************************************/
-PSPUBLIC int32_t psHmacSha384(const unsigned char *key, uint16_t keyLen,
- const unsigned char *buf, uint32_t len,
- unsigned char hash[SHA384_HASHLEN],
- unsigned char *hmacKey, uint16_t *hmacKeyLen);
+PSPUBLIC int32_t psHmacSha384(const unsigned char *key, psSize_t keyLen,
+ const unsigned char *buf, uint32_t len,
+ unsigned char hash[SHA384_HASHLEN],
+ unsigned char *hmacKey, psSize_t * hmacKeyLen);
PSPUBLIC int32_t psHmacSha384Init(psHmacSha384_t *ctx,
- const unsigned char *key, uint16_t keyLen);
+ const unsigned char *key, psSize_t keyLen);
PSPUBLIC void psHmacSha384Update(psHmacSha384_t *ctx,
- const unsigned char *buf, uint32_t len);
-PSPUBLIC void psHmacSha384Final(psHmacSha384_t *ctx,
- unsigned char hash[SHA384_HASHLEN]);
-#endif
+ const unsigned char *buf, uint32_t len);
+PSPUBLIC void psHmacSha384Final(psHmacSha384_t * ctx,
+ unsigned char hash[SHA384_HASHLEN]);
+# endif
/******************************************************************************/
/*
- Private Key Parsing
- PKCS#1 - RSA specific
- PKCS#8 - General private key storage format
-*/
-#ifdef USE_PRIVATE_KEY_PARSING
-#ifdef MATRIX_USE_FILE_SYSTEM
-#ifdef USE_RSA
-PSPUBLIC int32_t pkcs1ParsePrivFile(psPool_t *pool, const char *fileName,
- const char *password, psRsaKey_t *key);
-#endif
-PSPUBLIC int32_t pkcs1DecodePrivFile(psPool_t *pool, const char *fileName,
- const char *password, unsigned char **DERout, uint16_t *DERlen);
-#endif /* MATRIX_USE_FILESYSTEM */
-#ifdef USE_PKCS8
-PSPUBLIC int32 pkcs8ParsePrivBin(psPool_t *pool, unsigned char *p,
- int32 size, char *pass, psPubKey_t *key);
-#if defined(MATRIX_USE_FILE_SYSTEM) && defined (USE_PKCS12)
+ Private Key Parsing
+ PKCS#1 - RSA specific
+ PKCS#8 - General private key storage format
+ */
+# ifdef USE_PRIVATE_KEY_PARSING
+# ifdef MATRIX_USE_FILE_SYSTEM
+# ifdef USE_RSA
+PSPUBLIC int32_t psPkcs1ParsePrivFile(psPool_t *pool, const char *fileName,
+ const char *password, psRsaKey_t *key);
+PSPUBLIC int32_t psPkcs1ParsePubFile(psPool_t *pool, const char *fileName,
+ psRsaKey_t *key);
+# endif
+PSPUBLIC int32_t psPkcs1DecodePrivFile(psPool_t *pool, const char *fileName,
+ const char *password, unsigned char **DERout, psSize_t *DERlen);
+# endif /* MATRIX_USE_FILESYSTEM */
+# ifdef USE_PKCS8
+PSPUBLIC int32 psPkcs8ParsePrivBin(psPool_t *pool, unsigned char *p,
+ int32 size, char *pass, psPubKey_t *key);
+# if defined(MATRIX_USE_FILE_SYSTEM) && defined (USE_PKCS12)
PSPUBLIC int32 psPkcs12Parse(psPool_t *pool, psX509Cert_t **cert,
- psPubKey_t *privKey, const unsigned char *file, int32 flags,
- unsigned char *importPass, int32 ipasslen,
- unsigned char *privkeyPass, int32 kpasslen);
-#endif
-#endif /* USE_PKCS8 */
-#endif /* USE_PRIVATE_KEY_PARSING */
+ psPubKey_t *privKey, const unsigned char *file, int32 flags,
+ unsigned char *importPass, int32 ipasslen,
+ unsigned char *privkeyPass, int32 kpasslen);
+# endif
+# endif /* USE_PKCS8 */
+# endif /* USE_PRIVATE_KEY_PARSING */
-#ifdef USE_PKCS5
+# ifdef USE_PKCS5
/******************************************************************************/
/*
- PKCS#5 PBKDF v1 and v2 key generation
-*/
-PSPUBLIC int32_t pkcs5pbkdf1(unsigned char *pass, uint32 passlen,
- unsigned char *salt, int32 iter, unsigned char *key);
-PSPUBLIC void pkcs5pbkdf2(unsigned char *password, uint32 pLen,
- unsigned char *salt, uint32 sLen, int32 rounds,
- unsigned char *key, uint32 kLen);
-#endif /* USE_PKCS5 */
+ PKCS#5 PBKDF v1 and v2 key generation
+ */
+PSPUBLIC int32_t psPkcs5Pbkdf1(unsigned char *pass, uint32 passlen,
+ unsigned char *salt, int32 iter, unsigned char *key);
+PSPUBLIC void psPkcs5Pbkdf2(unsigned char *password, uint32 pLen,
+ unsigned char *salt, uint32 sLen, int32 rounds,
+ unsigned char *key, uint32 kLen);
+# endif /* USE_PKCS5 */
/******************************************************************************/
/*
- Public Key Cryptography
-*/
-#if defined(USE_RSA) || defined(USE_ECC) || defined(USE_DH)
+ Public Key Cryptography
+ */
+# if defined(USE_RSA) || defined(USE_ECC) || defined(USE_DH)
PSPUBLIC int32_t psInitPubKey(psPool_t *pool, psPubKey_t *key, uint8_t type);
PSPUBLIC void psClearPubKey(psPubKey_t *key);
PSPUBLIC int32_t psNewPubKey(psPool_t *pool, uint8_t type, psPubKey_t **key);
PSPUBLIC void psDeletePubKey(psPubKey_t **key);
PSPUBLIC int32_t psParseUnknownPrivKey(psPool_t *pool, int pemOrDer,
- char *keyfile, char *password, psPubKey_t *privkey);
-#endif
+ char *keyfile, char *password, psPubKey_t *privkey);
+PSPUBLIC int32_t psParseUnknownPubKey(psPool_t *pool, int pemOrDer,
+ char *keyfile, const char *password, psPubKey_t *pubkey);
+# endif
-#ifdef USE_RSA
+# ifdef USE_RSA
/******************************************************************************/
PSPUBLIC int32_t psRsaInitKey(psPool_t *pool, psRsaKey_t *key);
@@ -527,287 +571,335 @@ PSPUBLIC void psRsaClearKey(psRsaKey_t *key);
PSPUBLIC int32_t psRsaCopyKey(psRsaKey_t *to, const psRsaKey_t *from);
PSPUBLIC int32_t psRsaParsePkcs1PrivKey(psPool_t *pool,
- const unsigned char *p, uint16_t size,
- psRsaKey_t *key);
-PSPUBLIC int32_t psRsaParseAsnPubKey(psPool_t *pool,
- const unsigned char **pp, uint16_t len,
- psRsaKey_t *key, unsigned char sha1KeyHash[SHA1_HASHLEN]);
-PSPUBLIC uint16_t psRsaSize(const psRsaKey_t *key);
+ const unsigned char *p, psSize_t size,
+ psRsaKey_t *key);
+PSPUBLIC int32_t psRsaParseAsnPubKey(psPool_t * pool,
+ const unsigned char **pp, psSize_t len,
+ psRsaKey_t * key, unsigned char sha1KeyHash[SHA1_HASHLEN]);
+PSPUBLIC psSize_t psRsaSize(const psRsaKey_t *key);
PSPUBLIC int32_t psRsaCmpPubKey(const psRsaKey_t *k1, const psRsaKey_t *k2);
PSPUBLIC int32_t psRsaEncryptPriv(psPool_t *pool, psRsaKey_t *key,
- const unsigned char *in, uint16_t inlen,
- unsigned char *out, uint16_t outlen,
- void *data);
+ const unsigned char *in, psSize_t inlen,
+ unsigned char *out, psSize_t outlen,
+ void *data);
PSPUBLIC int32_t psRsaEncryptPub(psPool_t *pool, psRsaKey_t *key,
- const unsigned char *in, uint16_t inlen,
- unsigned char *out, uint16_t outlen,
- void *data);
+ const unsigned char *in, psSize_t inlen,
+ unsigned char *out, psSize_t outlen,
+ void *data);
PSPUBLIC int32_t psRsaDecryptPriv(psPool_t *pool, psRsaKey_t *key,
- unsigned char *in, uint16_t inlen,
- unsigned char *out, uint16_t outlen,
- void *data);
+ unsigned char *in, psSize_t inlen,
+ unsigned char *out, psSize_t outlen,
+ void *data);
PSPUBLIC int32_t psRsaDecryptPub(psPool_t *pool, psRsaKey_t *key,
- unsigned char *in, uint16_t inlen,
- unsigned char *out, uint16_t outlen,
- void *data);
+ unsigned char *in, psSize_t inlen,
+ unsigned char *out, psSize_t outlen,
+ void *data);
PSPUBLIC int32_t psRsaCrypt(psPool_t *pool, psRsaKey_t *key,
- const unsigned char *in, uint16_t inlen,
- unsigned char *out, uint16_t *outlen,
- uint8_t type, void *data);
+ const unsigned char *in, psSize_t inlen,
+ unsigned char *out, psSize_t *outlen,
+ uint8_t type, void *data);
PSPUBLIC int32_t pubRsaDecryptSignedElement(psPool_t *pool, psRsaKey_t *key,
- unsigned char *in, uint16_t inlen,
- unsigned char *out, uint16_t outlen,
- void *data);
+ unsigned char *in, psSize_t inlen,
+ unsigned char *out, psSize_t outlen,
+ void *data);
+PSPUBLIC int32_t pubRsaDecryptSignedElementExt(psPool_t *pool, psRsaKey_t *key,
+ unsigned char *in, psSize_t inlen,
+ unsigned char *out, psSize_t outlen,
+ int32_t signatureAlgorithm, void *data);
PSPUBLIC int32_t privRsaEncryptSignedElement(psPool_t *pool, psRsaKey_t *key,
- const unsigned char *in, uint16_t inlen,
- unsigned char *out, uint16_t outlen,
- void *data);
-#ifdef USE_PKCS1_OAEP
-PSPUBLIC int32 pkcs1OaepEncode(psPool_t *pool, const unsigned char *msg,
- uint32 msglen, const unsigned char *lparam,
- uint32 lparamlen, unsigned char *seed, uint32 seedLen,
- uint32 modulus_bitlen, int32 hash_idx,
- unsigned char *out, uint16_t *outlen);
-PSPUBLIC int32 pkcs1OaepDecode(psPool_t *pool, const unsigned char *msg,
- uint32 msglen, const unsigned char *lparam, uint32 lparamlen,
- uint32 modulus_bitlen, int32 hash_idx,
- unsigned char *out, uint16_t *outlen);
-#endif /* USE_PKCS1_OAEP */
-#ifdef USE_PKCS1_PSS
-PSPUBLIC int32 pkcs1PssEncode(psPool_t *pool, const unsigned char *msghash,
- uint32 msghashlen, unsigned char *salt, uint32 saltlen,
- int32 hash_idx, uint32 modulus_bitlen, unsigned char *out,
- uint16_t *outlen);
-PSPUBLIC int32 pkcs1PssDecode(psPool_t *pool, const unsigned char *msghash,
- uint32 msghashlen, const unsigned char *sig, uint32 siglen,
- uint32 saltlen, int32 hash_idx, uint32 modulus_bitlen, int32 *res);
-#endif /* USE_PKCS1_PSS */
-#endif /* USE_RSA */
+ const unsigned char *in, psSize_t inlen,
+ unsigned char *out, psSize_t outlen,
+ void *data);
+# ifdef USE_PKCS1_OAEP
+PSPUBLIC int32 psPkcs1OaepEncode(psPool_t *pool, const unsigned char *msg,
+ uint32 msglen, const unsigned char *lparam,
+ uint32 lparamlen, unsigned char *seed, uint32 seedLen,
+ uint32 modulus_bitlen, int32 hash_idx,
+ unsigned char *out, psSize_t *outlen);
+PSPUBLIC int32 psPkcs1OaepDecode(psPool_t *pool, const unsigned char *msg,
+ uint32 msglen, const unsigned char *lparam, uint32 lparamlen,
+ uint32 modulus_bitlen, int32 hash_idx,
+ unsigned char *out, psSize_t *outlen);
+# endif /* USE_PKCS1_OAEP */
+# ifdef USE_PKCS1_PSS
+PSPUBLIC int32 psPkcs1PssEncode(psPool_t *pool, const unsigned char *msghash,
+ uint32 msghashlen, unsigned char *salt, uint32 saltlen,
+ int32 hash_idx, uint32 modulus_bitlen, unsigned char *out,
+ psSize_t *outlen);
+PSPUBLIC int32 psPkcs1PssDecode(psPool_t *pool, const unsigned char *msghash,
+ uint32 msghashlen, const unsigned char *sig, uint32 siglen,
+ uint32 saltlen, int32 hash_idx, uint32 modulus_bitlen, int32 *res);
+# endif /* USE_PKCS1_PSS */
+# endif /* USE_RSA */
-#ifdef USE_ECC
+# ifdef USE_ECC
/******************************************************************************/
PSPUBLIC int32_t psEccInitKey(psPool_t *pool, psEccKey_t *key,
- const psEccCurve_t *curve);
+ const psEccCurve_t *curve);
PSPUBLIC void psEccClearKey(psEccKey_t *key);
PSPUBLIC int32_t psEccNewKey(psPool_t *pool, psEccKey_t **key,
- const psEccCurve_t *curve);
+ const psEccCurve_t *curve);
PSPUBLIC void psEccDeleteKey(psEccKey_t **key);
PSPUBLIC int32 psEccCopyKey(psEccKey_t *to, psEccKey_t *from);
PSPUBLIC uint8_t psEccSize(const psEccKey_t *key);
PSPUBLIC int32_t psEccGenKey(psPool_t *pool, psEccKey_t *key,
- const psEccCurve_t *curve, void *usrData);
+ const psEccCurve_t *curve, void *usrData);
PSPUBLIC int32_t psEccParsePrivKey(psPool_t *pool,
- const unsigned char *keyBuf, uint16_t keyBufLen,
- psEccKey_t *keyPtr, const psEccCurve_t *curve);
+ const unsigned char *keyBuf, psSize_t keyBufLen,
+ psEccKey_t *keyPtr, const psEccCurve_t *curve);
PSPUBLIC int32_t psEccParsePrivFile(psPool_t *pool,
- const char *fileName, const char *password,
- psEccKey_t *key);
+ const char *fileName, const char *password,
+ psEccKey_t *key);
PSPUBLIC int32_t psEccX963ImportKey(psPool_t *pool,
- const unsigned char *in, uint16_t inlen,
- psEccKey_t *key, const psEccCurve_t *curve);
+ const unsigned char *in, psSize_t inlen,
+ psEccKey_t *key, const psEccCurve_t *curve);
PSPUBLIC int32_t psEccX963ExportKey(psPool_t *pool, const psEccKey_t *key,
- unsigned char *out, uint16_t *outlen);
+ unsigned char *out, psSize_t *outlen);
PSPUBLIC int32_t psEccGenSharedSecret(psPool_t *pool,
- const psEccKey_t *privKey, const psEccKey_t *pubKey,
- unsigned char *outbuf, uint16_t *outlen, void *usrData);
+ const psEccKey_t *privKey, const psEccKey_t *pubKey,
+ unsigned char *outbuf, psSize_t *outlen, void *usrData);
PSPUBLIC int32_t psEccDsaSign(psPool_t *pool, const psEccKey_t *privKey,
- const unsigned char *buf, uint16_t buflen,
- unsigned char *sig, uint16_t *siglen,
- uint8_t includeSize, void *usrData);
+ const unsigned char *buf, psSize_t buflen,
+ unsigned char *sig, psSize_t *siglen,
+ uint8_t includeSize, void *usrData);
PSPUBLIC int32_t psEccDsaVerify(psPool_t *pool, const psEccKey_t *key,
- const unsigned char *buf, uint16_t bufLen,
- const unsigned char *sig, uint16_t siglen,
- int32_t *status, void *usrData);
-#endif /* USE_ECC */
+ const unsigned char *buf, psSize_t bufLen,
+ const unsigned char *sig, psSize_t siglen,
+ int32_t *status, void *usrData);
+# endif /* USE_ECC */
-#ifdef USE_DH
+# ifdef USE_DH
/******************************************************************************/
/*
- PKCS#3 - Diffie-Hellman parameters
-*/
-PSPUBLIC int32_t pkcs3ParseDhParamBin(psPool_t *pool,
- const unsigned char *dhBin, uint16_t dhBinLen,
- psDhParams_t *params);
-#ifdef MATRIX_USE_FILE_SYSTEM
-PSPUBLIC int32_t pkcs3ParseDhParamFile(psPool_t *pool,const char *fileName,
- psDhParams_t *params);
-#endif
+ PKCS#3 - Diffie-Hellman parameters
+ */
+PSPUBLIC int32_t psPkcs3ParseDhParamBin(psPool_t *pool,
+ const unsigned char *dhBin, psSize_t dhBinLen,
+ psDhParams_t *params);
+# ifdef MATRIX_USE_FILE_SYSTEM
+PSPUBLIC int32_t psPkcs3ParseDhParamFile(psPool_t *pool, const char *fileName,
+ psDhParams_t *params);
+# endif
PSPUBLIC int32_t psDhExportParameters(psPool_t *pool,
- const psDhParams_t *params,
- unsigned char **pp, uint16_t *pLen,
- unsigned char **pg, uint16_t *gLen);
-PSPUBLIC void pkcs3ClearDhParams(psDhParams_t *params);
+ const psDhParams_t *params,
+ unsigned char **pp, psSize_t *pLen,
+ unsigned char **pg, psSize_t *gLen);
+PSPUBLIC void psPkcs3ClearDhParams(psDhParams_t *params);
PSPUBLIC int32_t psDhImportPubKey(psPool_t *pool,
- const unsigned char *inbuf, uint16_t inlen,
- psDhKey_t *key);
+ const unsigned char *inbuf, psSize_t inlen,
+ psDhKey_t *key);
PSPUBLIC int32_t psDhExportPubKey(psPool_t *pool, const psDhKey_t *key,
- unsigned char *out, uint16_t *outlen);
+ unsigned char *out, psSize_t *outlen);
PSPUBLIC void psDhClearKey(psDhKey_t *key);
-PSPUBLIC uint16_t psDhSize(const psDhKey_t *key);
+PSPUBLIC psSize_t psDhSize(const psDhKey_t *key);
-PSPUBLIC int32_t psDhGenKey(psPool_t *pool, uint16_t keysize,
- const unsigned char *pBin, uint16_t pLen,
- const unsigned char *gBin, uint16_t gLen,
- psDhKey_t *key, void *usrData);
-PSPUBLIC int32_t psDhGenKeyInts(psPool_t *pool, uint16_t keysize,
- const pstm_int *p, const pstm_int *g,
- psDhKey_t *key, void *usrData);
+PSPUBLIC int32_t psDhGenKey(psPool_t *pool, psSize_t keysize,
+ const unsigned char *pBin, psSize_t pLen,
+ const unsigned char *gBin, psSize_t gLen,
+ psDhKey_t *key, void *usrData);
+PSPUBLIC int32_t psDhGenKeyInts(psPool_t *pool, psSize_t keysize,
+ const pstm_int *p, const pstm_int *g,
+ psDhKey_t *key, void *usrData);
PSPUBLIC int32_t psDhGenSharedSecret(psPool_t *pool,
- const psDhKey_t *privKey, const psDhKey_t *pubKey,
- const unsigned char *pBin, uint16_t pBinLen,
- unsigned char *out, uint16_t *outlen, void *usrData);
+ const psDhKey_t *privKey, const psDhKey_t *pubKey,
+ const unsigned char *pBin, psSize_t pBinLen,
+ unsigned char *out, psSize_t *outlen, void *usrData);
-#endif /* USE_DH */
+# endif /* USE_DH */
-#ifdef USE_X509
+# ifdef USE_X509
/******************************************************************************/
/*
- X.509 Certificate support
-*/
+ X.509 Certificate support
+ */
PSPUBLIC int32 psX509ParseCertFile(psPool_t *pool, char *fileName,
- psX509Cert_t **outcert, int32 flags);
+ psX509Cert_t **outcert, int32 flags);
PSPUBLIC int32 psX509ParseCert(psPool_t *pool, const unsigned char *pp, uint32 size,
- psX509Cert_t **outcert, int32 flags);
+ psX509Cert_t **outcert, int32 flags);
PSPUBLIC void psX509FreeCert(psX509Cert_t *cert);
-#ifdef USE_CERT_PARSE
+# ifdef USE_CERT_PARSE
PSPUBLIC int32 psX509GetCertPublicKeyDer(psX509Cert_t *cert,
- unsigned char *der_out,
- uint16_t *der_out_len);
+ unsigned char *der_out,
+ psSize_t *der_out_len);
PSPUBLIC int32 psX509AuthenticateCert(psPool_t *pool, psX509Cert_t *subjectCert,
- psX509Cert_t *issuerCert, psX509Cert_t **foundIssuer,
- void *hwCtx, void *poolUserPtr);
-#endif
-#ifdef USE_CRL
-#define CRL_CHECK_EXPECTED 5 /* cert had a dist point but not fetched yet */
-#define CRL_CHECK_NOT_EXPECTED 6 /* cert didn't have dist point */
-#define CRL_CHECK_PASSED_AND_AUTHENTICATED 7 /* all completely good */
-#define CRL_CHECK_PASSED_BUT_NOT_AUTHENTICATED 8 /* had CRL but no auth done */
-#define CRL_CHECK_REVOKED_AND_AUTHENTICATED 9
-#define CRL_CHECK_REVOKED_BUT_NOT_AUTHENTICATED 10
-#define CRL_CHECK_CRL_EXPIRED 11 /* CRL expired. Revocation not tested */
+ psX509Cert_t *issuerCert, psX509Cert_t **foundIssuer,
+ void *hwCtx, void *poolUserPtr);
+# endif
+# ifdef USE_CRL
+# define CRL_CHECK_EXPECTED 5 /* cert had a dist point but not fetched yet */
+# define CRL_CHECK_NOT_EXPECTED 6 /* cert didn't have dist point */
+# define CRL_CHECK_PASSED_AND_AUTHENTICATED 7 /* all completely good */
+# define CRL_CHECK_PASSED_BUT_NOT_AUTHENTICATED 8 /* had CRL but no auth done */
+# define CRL_CHECK_REVOKED_AND_AUTHENTICATED 9
+# define CRL_CHECK_REVOKED_BUT_NOT_AUTHENTICATED 10
+# define CRL_CHECK_CRL_EXPIRED 11/* CRL expired. Revocation not tested */
+PSPUBLIC int32 psX509GetCRLVersion(const unsigned char *crlBin,
+ int32 crlBinLen);
PSPUBLIC int32_t psX509ParseCRL(psPool_t *pool, psX509Crl_t **crl,
- unsigned char *crlBin, int32 crlBinLen);
-PSPUBLIC void psX509FreeCRL(psX509Crl_t *crl);
+ unsigned char *crlBin, int32 crlBinLen);
+PSPUBLIC void psX509FreeCRL(psX509Crl_t *crl);
PSPUBLIC int32_t psX509GetCRLdistURL(psX509Cert_t *cert, char **url,
- uint32_t *urlLen);
+ uint32_t *urlLen);
PSPUBLIC int32_t psX509AuthenticateCRL(psX509Cert_t *CA, psX509Crl_t *CRL,
- void *poolUserPtr);
+ void *poolUserPtr);
/* CRL global cache management */
PSPUBLIC int psCRL_Update(psX509Crl_t *crl, int deleteExisting);
PSPUBLIC int psCRL_Insert(psX509Crl_t *crl);
-PSPUBLIC int psCRL_Remove(psX509Crl_t *crl); /* Doesn't delete! */
+PSPUBLIC int psCRL_Remove(psX509Crl_t *crl); /* Doesn't delete! */
PSPUBLIC int psCRL_Delete(psX509Crl_t *crl);
PSPUBLIC void psCRL_RemoveAll();
PSPUBLIC void psCRL_DeleteAll();
-PSPUBLIC psX509Crl_t* psCRL_GetCRLForCert(psX509Cert_t *cert);
+PSPUBLIC psX509Crl_t *psCRL_GetCRLForCert(psX509Cert_t *cert);
PSPUBLIC int32_t psCRL_isRevoked(psX509Cert_t *cert, psX509Crl_t *CRL);
PSPUBLIC int32_t psCRL_determineRevokedStatus(psX509Cert_t *cert);
+PSPUBLIC int32_t psCRL_determineRevokedStatusBDT(psX509Cert_t *cert,
+ psBrokenDownTime_t *bdt);
-#endif /* USE_CRL */
-#endif /* USE_X509 */
+# endif /* USE_CRL */
+# endif /* USE_X509 */
/******************************************************************************/
/*
- Pseudorandom Number Generation
-*/
+ Pseudorandom Number Generation
+ */
PSPUBLIC int32_t psInitPrng(psRandom_t *ctx, void *userPtr);
-PSPUBLIC int32_t psGetPrng(psRandom_t *ctx, unsigned char *bytes, uint16_t size,
- void *userPtr);
+PSPUBLIC int32_t psGetPrng(psRandom_t *ctx, unsigned char *bytes, psSize_t size,
+ void *userPtr);
-#ifdef USE_YARROW
+# ifdef USE_YARROW
/******************************************************************************/
PSPUBLIC int32 psYarrowStart(psYarrow_t *ctx);
PSPUBLIC int32 psYarrowAddEntropy(unsigned char *in, uint32 inlen,
- psYarrow_t *prng);
+ psYarrow_t *prng);
PSPUBLIC int32 psYarrowReseed(psYarrow_t *ctx);
PSPUBLIC uint32 psYarrowRead(unsigned char *out, uint32 outlen, psYarrow_t *cx);
PSPUBLIC int32 psYarrowDone(psYarrow_t *ctx);
PSPUBLIC int32 psYarrowExport(unsigned char *out, uint32 *outlen,
- psYarrow_t *ctx);
+ psYarrow_t *ctx);
PSPUBLIC int32 psYarrowImport(unsigned char *in, uint32 inlen, psYarrow_t *ctx);
-#endif /* USE_YARROW */
+# endif /* USE_YARROW */
/******************************************************************************/
/*
- Deprecated Algorithms
-*/
-#ifdef USE_ARC4
+ Deprecated Algorithms
+ */
+# ifdef USE_ARC4
/******************************************************************************/
PSPUBLIC int32_t psArc4Init(psArc4_t *ctx,
- const unsigned char *key, uint8_t keylen);
+ const unsigned char *key, uint8_t keylen);
PSPUBLIC void psArc4(psArc4_t *ctx, const unsigned char *in,
- unsigned char *out, uint32_t len);
+ unsigned char *out, uint32_t len);
PSPUBLIC void psArc4Clear(psArc4_t *ctx);
-#endif
+# endif
-#ifdef USE_SEED
+# ifdef USE_SEED
/******************************************************************************/
PSPUBLIC int32_t psSeedInit(psSeed_t *ctx, const unsigned char IV[SEED_IVLEN],
- const unsigned char key[SEED_KEYLEN]);
+ const unsigned char key[SEED_KEYLEN]);
PSPUBLIC void psSeedDecrypt(psSeed_t *ctx, const unsigned char *ct,
- unsigned char *pt, uint32_t len);
+ unsigned char *pt, uint32_t len);
PSPUBLIC void psSeedEncrypt(psSeed_t *ctx, const unsigned char *pt,
- unsigned char *ct, uint32_t len);
+ unsigned char *ct, uint32_t len);
PSPUBLIC void psSeedClear(psSeed_t *ctx);
-#endif
+# endif
-#ifdef USE_IDEA
+# ifdef USE_IDEA
/******************************************************************************/
PSPUBLIC int32_t psIdeaInit(psIdea_t *ctx, const unsigned char IV[IDEA_IVLEN],
- const unsigned char key[IDEA_KEYLEN]);
+ const unsigned char key[IDEA_KEYLEN]);
PSPUBLIC void psIdeaDecrypt(psIdea_t *ctx, const unsigned char *ct,
- unsigned char *pt, uint32_t len);
+ unsigned char *pt, uint32_t len);
PSPUBLIC void psIdeaEncrypt(psIdea_t *ctx, const unsigned char *pt,
- unsigned char *ct, uint32_t len);
+ unsigned char *ct, uint32_t len);
PSPUBLIC void psIdeaClear(psIdea_t *ctx);
-#endif
+# endif
-#ifdef USE_RC2
+# ifdef USE_RC2
/******************************************************************************/
PSPUBLIC int32_t psRc2Init(psRc2Cbc_t *ctx, const unsigned char *IV,
- const unsigned char *key, uint8_t keylen);
+ const unsigned char *key, uint8_t keylen);
PSPUBLIC int32_t psRc2Decrypt(psRc2Cbc_t *ctx, const unsigned char *ct,
- unsigned char *pt, uint32_t len);
+ unsigned char *pt, uint32_t len);
PSPUBLIC int32_t psRc2Encrypt(psRc2Cbc_t *ctx, const unsigned char *pt,
- unsigned char *ct, uint32_t len);
-#endif
+ unsigned char *ct, uint32_t len);
+# endif
-#ifdef USE_MD4
+# ifdef USE_MD4
/******************************************************************************/
PSPUBLIC void psMd4Init(psMd4_t *md);
PSPUBLIC void psMd4Update(psMd4_t *md, const unsigned char *buf, uint32_t len);
PSPUBLIC int32_t psMd4Final(psMd4_t *md, unsigned char *hash);
-#endif
+# endif
-#ifdef USE_MD2
+# ifdef USE_MD2
/******************************************************************************/
static __inline void psMd2PreInit(psMd2_t *md2)
{
- /* Nothing to pre-initialize for native crypto. */
+ /* Nothing to pre-initialize for native crypto. */
}
PSPUBLIC void psMd2Init(psMd2_t *md);
PSPUBLIC int32_t psMd2Update(psMd2_t *md, const unsigned char *buf,
- uint32_t len);
+ uint32_t len);
PSPUBLIC int32_t psMd2Final(psMd2_t *md, unsigned char *hash);
-#endif
+# endif
-#ifdef __cplusplus
+/* MatrixSSL 3.9.0 has cleaned up namespaces used by MatrixSSL crypto library.
+ These aliases are provided for backwards compatibility with applications
+ using MatrixSSL 3.8.x API. */
+# ifndef NO_MATRIXSSL_3_8_API_COMPATIBILITY
+# define pkcs1OaepEncode psPkcs1OaepEncode
+# define pkcs1OaepDecode psPkcs1OaepDecode
+# define pkcs1PssEncode psPkcs1PssEncode
+# define pkcs1PssDecode psPkcs1PssDecode
+# define pkcs1ParsePrivFile psPkcs1ParsePrivFile
+# define pkcs1DecodePrivFile psPkcs1DecodePrivFile
+# define pkcs8ParsePrivBin psPkcs8ParsePrivBin
+# define pkcs5pbkdf1 psPkcs5Pbkdf1
+# define pkcs5pbkdf2 psPkcs5Pbkdf2
+# define pkcs3ParseDhParamBin psPkcs3ParseDhParamBin
+# define pkcs3ParseDhParamFile psPkcs3ParseDhParamFile
+# define pkcs3ClearDhParams psPkcs3ClearDhParams
+# define matrixSslWriteOCSPRequest psOcspRequestWriteOld
+# define matrixSslWriteOCSPRequestInfoSetSigning \
+ psOcspRequestWriteInfoSetSigning
+# define matrixSslWriteOCSPRequestInfoSetRequestorId \
+ psOcspRequestWriteInfoSetRequestorId
+# define matrixSslWriteOCSPRequestInfoFreeRequestorId \
+ psOcspRequestWriteInfoFreeRequestorId
+# define matrixSslWriteOCSPRequestExt psOcspRequestWrite
+# define matrixSslWriteOCSPRequestVersion \
+ psOcspRequestWriteVersion
+# define matrixSslOCSPNonceExtension psOcspWriteNonceExtension
+# define validateOCSPResponse psOcspResponseValidateOld
+# define validateOCSPResponse_ex psOcspResponseValidate
+# define parseOCSPResponse psOcspParseResponse
+# define getOCSPResponseStatus psOcspResponseGetStatus
+# define checkOCSPResponseDates psOcspResponseCheckDates
+# define uninitOCSPResponse psOcspResponseUninit
+# define matrixCryptoGetPrngData psGetPrngLocked
+# define s_pstm_sub pstm_sub_s
+# define mOCSPResponse_t psOcspResponse_t
+# define mOCSPSingleResponse_t psOcspSingleResponse_t
+
+# endif /* NO_MATRIXSSL_3_8_API_COMPATIBILITY */
+
+# ifdef __cplusplus
}
-#endif
+# endif
#endif /* _h_PS_CRYPTOAPI */
diff --git a/crypto/cryptoCheck.h b/crypto/cryptoCheck.h
index e5f5dd7..8a66e02 100644
--- a/crypto/cryptoCheck.h
+++ b/crypto/cryptoCheck.h
@@ -1,117 +1,117 @@
/**
- * @file cryptoCheck.h
- * @version $Format:%h%d$
+ * @file cryptoCheck.h
+ * @version $Format:%h%d$
*
- * Configuration validation/sanity checks.
+ * Configuration validation/sanity checks.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_CRYPTOCHECK
-#define _h_PS_CRYPTOCHECK
+# define _h_PS_CRYPTOCHECK
/******************************************************************************/
/*
-*/
-#ifdef USE_CERT_PARSE
- #ifndef USE_X509
- #error "Must enable USE_X509 if USE_CERT_PARSE is enabled"
- #endif
- #if !defined(USE_MD5) && !defined(USE_SHA1) && !defined(USE_SHA256)
- #error "At least one of USE_MD5, USE_SHA1 or USE_SHA256 must be enabled for USE_CERT_PARSE"
- #endif
-#endif
+ */
+# ifdef USE_CERT_PARSE
+# ifndef USE_X509
+# error "Must enable USE_X509 if USE_CERT_PARSE is enabled"
+# endif
+# if !defined(USE_MD5) && !defined(USE_SHA1) && !defined(USE_SHA256)
+# error "At least one of USE_MD5, USE_SHA1 or USE_SHA256 must be enabled for USE_CERT_PARSE"
+# endif
+# endif
-#ifdef USE_PBKDF1
- #ifndef USE_PKCS5
- #error "Enable USE_PKCS5 in cryptoConfig.h for PKBDF1 support"
- #endif
-#endif
+# ifdef USE_PBKDF1
+# ifndef USE_PKCS5
+# error "Enable USE_PKCS5 in cryptoConfig.h for PKBDF1 support"
+# endif
+# endif
-#ifdef USE_PKCS5
- #ifdef USE_PBKDF1
- #ifndef USE_MD5
- #error "Enable USE_MD5 in cryptoConfig.h for PBKDF1 support"
- #endif
- #endif
- #ifndef USE_3DES
- #error "Enable USE_3DES in cryptoConfig.h for PKCS5 support"
- #endif
- #ifndef USE_AES
- #error "Enable USE_AES in cryptoConfig.h for PKCS5 support"
- #endif
-#endif
+# ifdef USE_PKCS5
+# ifdef USE_PBKDF1
+# ifndef USE_MD5
+# error "Enable USE_MD5 in cryptoConfig.h for PBKDF1 support"
+# endif
+# endif
+# ifndef USE_3DES
+# error "Enable USE_3DES in cryptoConfig.h for PKCS5 support"
+# endif
+# ifndef USE_AES
+# error "Enable USE_AES in cryptoConfig.h for PKCS5 support"
+# endif
+# endif
-#ifdef USE_PKCS8
- #ifndef USE_HMAC_SHA1
- #error "Enable USE_HMAC_SHA1 in cryptoConfig.h for PKCS8 support"
- #endif
-#endif
+# ifdef USE_PKCS8
+# ifndef USE_HMAC_SHA1
+# error "Enable USE_HMAC_SHA1 in cryptoConfig.h for PKCS8 support"
+# endif
+# endif
- #define USE_NATIVE_ECC
- #define USE_NATIVE_AES
- #define USE_NATIVE_HASH
+# define USE_NATIVE_ECC
+# define USE_NATIVE_AES
+# define USE_NATIVE_HASH
-#ifdef USE_PKCS12
- #ifndef USE_PKCS8
- #error "Enable USE_PKCS8 in cryptoConfig.h for PKCS12 support"
- #endif
-#else
- #ifdef USE_RC2
- #error "RC2 only allowed for PKCS12 support"
- #endif
-#endif
+# ifdef USE_PKCS12
+# ifndef USE_PKCS8
+# error "Enable USE_PKCS8 in cryptoConfig.h for PKCS12 support"
+# endif
+# else
+# ifdef USE_RC2
+# error "RC2 only allowed for PKCS12 support"
+# endif
+# endif
-#ifdef USE_CERT_PARSE
- #ifndef USE_X509
- #error "USE_X509 required for USE_CERT_PARSE"
- #endif
-#endif
+# ifdef USE_CERT_PARSE
+# ifndef USE_X509
+# error "USE_X509 required for USE_CERT_PARSE"
+# endif
+# endif
-#ifdef USE_FULL_CERT_PARSE
- #ifndef USE_CERT_PARSE
- #error "USE_CERT_PARSE required for USE_FULL_CERT_PARSE"
- #endif
-#endif
+# ifdef USE_FULL_CERT_PARSE
+# ifndef USE_CERT_PARSE
+# error "USE_CERT_PARSE required for USE_FULL_CERT_PARSE"
+# endif
+# endif
-#ifdef ENABLE_CA_CERT_HASH
- #if !defined(USE_SHA1) || !defined(USE_X509)
- #error "USE_SHA1 and USE_X509 required for ENABLE_CA_CERT_HASH"
- #endif
-#endif
+# ifdef ENABLE_CA_CERT_HASH
+# if !defined(USE_SHA1) || !defined(USE_X509)
+# error "USE_SHA1 and USE_X509 required for ENABLE_CA_CERT_HASH"
+# endif
+# endif
-#ifdef USE_OCSP
- #ifndef USE_SHA1
- #error "Enable USE_SHA1 in cryptoConfig.h for OCSP support"
- #endif
-#endif
+# ifdef USE_OCSP
+# ifndef USE_SHA1
+# error "Enable USE_SHA1 in cryptoConfig.h for OCSP support"
+# endif
+# endif
-#endif /* _h_PS_CRYPTOCHECK */
+#endif /* _h_PS_CRYPTOCHECK */
/******************************************************************************/
diff --git a/crypto/cryptoConfig.h b/crypto/cryptoConfig.h
deleted file mode 100644
index f822e75..0000000
--- a/crypto/cryptoConfig.h
+++ /dev/null
@@ -1,220 +0,0 @@
-/**
- * @file cryptoConfig.h
- * @version $Format:%h%d$
- *
- * Configuration file for crypto features.
- */
-/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
- *
- * The latest version of this code is available at http://www.matrixssl.org
- *
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
- *
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
- */
-/******************************************************************************/
-
-#ifndef _h_PS_CRYPTOCONFIG
-#define _h_PS_CRYPTOCONFIG
-
-/******************************************************************************/
-/* Configurable features */
-/******************************************************************************/
-/**
- Define to enable psTrace*Crypto APIs for debugging the crypto module.
-*/
-//#define USE_CRYPTO_TRACE
-
-#ifdef DEBUG
-//#define CRYPTO_ASSERT /**< Extra sanity asserts */
-#endif
-
-/******************************************************************************/
-/*
- Use built-in cryptographic library delivered with MatrixSSL
-*/
-#define USE_NATIVE_RSA /* Default built-in software support */
-
-/******************************************************************************/
-/**
- Security related settings.
-
- @security MIN_*_BITS is the minimum supported key sizes in bits, weaker
- keys will be rejected.
-*/
-#define MIN_ECC_BITS 192/**< @security Affects ECC curves below */
-
-#define MIN_RSA_BITS 1024
-
-#define MIN_DH_BITS 1024
-
-#define USE_BURN_STACK/**< @security Zero sensitive data from the stack. */
-
-/******************************************************************************/
-/**
- Public-Key Algorithm Support.
-*/
-#define USE_RSA
-#define USE_ECC
-#define USE_DH
-/**< @note Enable verification of DSA signatures in certificate validation.
- Works only when using the CL/SL library. @pre USE_CERT_PARSE. */
-//#define USE_DSA_VERIFY
-
-/******************************************************************************/
-/**
- Build the PKCS and ASN1 extra CL sublibraries.
- These are needed by the CL_PKCS API.
-*/
-
-/******************************************************************************/
-
-/**
- Define to enable the individual NIST Prime curves.
- @see http://csrc.nist.gov/groups/ST/toolkit/documents/dss/NISTReCur.pdf
-*/
-#ifdef USE_ECC
- #define USE_SECP192R1/**< @security FIPS allowed for sig ver only. */
- #define USE_SECP224R1
- #define USE_SECP256R1/**< @security NIST_SHALL */
- #define USE_SECP384R1/**< @security NIST_SHALL */
- #define USE_SECP521R1
-#endif
-
-/**
- Define to enable the individual Brainpool curves.
- @see https://tools.ietf.org/html/rfc5639
- @security WARNING: Public points on Brainpool curves are not validated
-*/
-#ifdef USE_ECC
-//#define USE_BRAIN224R1
-//#define USE_BRAIN256R1
-//#define USE_BRAIN384R1
-//#define USE_BRAIN512R1
-#endif
-
-/******************************************************************************/
-/**
- Symmetric and AEAD ciphers.
- @security Deprecated ciphers must be enabled in cryptolib.h
-*/
-//#define USE_AES /* Enable/Disable AES */
-#define USE_AES_CBC
-#define USE_AES_GCM
-
-#ifdef USE_LIBSODIUM
-//#define USE_CHACHA20_POLY1305
-#endif
-
-/** @security 3DES is still relatively secure, however is deprecated for TLS */
-#define USE_3DES
-
-/******************************************************************************/
-/**
- Digest algorithms.
-
- @note SHA256 and above are used with TLS 1.2, and also used for
- certificate signatures on some certificates regardless of TLS version.
-
- @security MD5 is deprecated, but still required in combination with SHA-1
- for TLS handshakes before TLS 1.2, meaning that the strength is at least
- that of SHA-1 in this usage. The define USE_MD5SHA1 can be used to enable
- MD5 only for this purpose. The only other usage of MD5 by TLS is for
- certificate signatures and MD5 based cipher suites. Both of which are
- disabled at compile time by default.
-
- @security SHA1 will be deprecated in the future, but is still required in
- combination with MD5 for versions prior to TLS 1.2. In addition, SHA1
- certificates are still commonly used, so SHA1 support may be needed
- to validate older certificates. It is possible to completely disable
- SHA1 using TLS 1.2 and SHA2 based ciphersuites, and interacting
- only with newer certificates.
-*/
-//#define USE_SHA224 /**< @note Used only for cert signature */
-#define USE_SHA256/**< @note Required for TLS 1.2 and above */
-#define USE_HMAC_SHA256
-#define USE_SHA384/**< @pre USE_SHA512 */
-#define USE_HMAC_SHA384
-#define USE_SHA512
-
-/**
- @security SHA-1 based hashes are deprecated but enabled by default
- @note ENABLE_SHA1_SIGNED_CERTS can additionally be configured below.
-*/
-#define USE_SHA1
-#define USE_HMAC_SHA1
-
-/**
- @security MD5 is considered insecure, but required by TLS < 1.2
- @note ENABLE_MD5_SIGNED_CERTS can additionally be configured below.
-*/
-#define USE_MD5
-#define USE_MD5SHA1/* Required for < TLS 1.2 Handshake */
-#define USE_HMAC_MD5
-
-/**
- @security MD2 is considered insecure, but is sometimes used for
- verification of legacy root certificate signatures.
- @note MD2 signature verification also requires
- ENABLE_MD5_SIGNED_CERTS and USE_MD5.
-*/
-//#define USE_MD2
-
-/* Please enable, unless using no HMAC algorithms. */
-#define USE_HMAC
-
-/******************************************************************************/
-/**
- X.509 Certificates/PKI
-*/
-#define USE_BASE64_DECODE
-#define USE_X509/**< Enable minimal X.509 support. */
-#define USE_CERT_PARSE/**< Enable TBSCertificate parsing. Usually required. @pre USE_X509 */
-#define USE_FULL_CERT_PARSE/**< @pre USE_CERT_PARSE */
- /**< Support extra distinguished name attributes that SHOULD be supported according to RFC 5280. */
-//#define USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
- /**< Support extra distinguished name attributes not mentioned in RFC 5280. */
-//#define USE_EXTRA_DN_ATTRIBUTES
-//#define ENABLE_CA_CERT_HASH /**< Used only for TLS trusted CA ind ext. */
-//#define ENABLE_MD5_SIGNED_CERTS /** @security Accept MD5 signed certs? */
-#define ENABLE_SHA1_SIGNED_CERTS/** @security Accept SHA1 signed certs? */
- /**< @security Allow parsing of locally trusted v1 root certs? */
-//#define ALLOW_VERSION_1_ROOT_CERT_PARSE
-#define USE_CRL/***< @pre USE_FULL_CERT_PARSE */
-#define USE_OCSP/**< @pre USE_SHA1 */
-
-/******************************************************************************/
-/**
- Various PKCS standards support
-*/
-#define USE_PRIVATE_KEY_PARSING
-#define USE_PKCS5/**< v2.0 PBKDF encrypted priv keys. @pre USE_3DES */
-/**< Enable PBKDF1 in priv key PEM encryption. @pre USE_PKCS5 and @pre USE_MD5. @security Not recommended. */
-#define USE_PBKDF1
-#define USE_PKCS8/* Alternative private key storage format */
-#define USE_PKCS12/**< @pre USE_PKCS8 */
-#define USE_PKCS1_OAEP/* OAEP padding algorithm */
-#define USE_PKCS1_PSS/* PSS padding algorithm */
-
-#endif /* _h_PS_CRYPTOCONFIG */
-
-/******************************************************************************/
-
diff --git a/crypto/cryptoImpl.h b/crypto/cryptoImpl.h
new file mode 100644
index 0000000..17f2bfb
--- /dev/null
+++ b/crypto/cryptoImpl.h
@@ -0,0 +1,43 @@
+/**
+ * @file cryptoImpl.h
+ * @version $Format:%h%d$
+ *
+ * Include common include files for compiling part of MatrixSSL's crypto.
+ */
+/*
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#ifndef _h_PS_CRYPTOIMPL
+# define _h_PS_CRYPTOIMPL
+
+# define PS_CRYPTO_IMPLEMENTATION 1
+# include "cryptoApi.h"
+# include "../core/osdep.h"
+# include "../core/psUtil.h"
+
+#endif /* _h_PS_CRYPTOIMPL */
diff --git a/crypto/cryptolib.h b/crypto/cryptolib.h
index aae524a..7d0eac0 100644
--- a/crypto/cryptolib.h
+++ b/crypto/cryptolib.h
@@ -1,699 +1,702 @@
/**
- * @file cryptolib.h
- * @version $Format:%h%d$
+ * @file cryptolib.h
+ * @version $Format:%h%d$
*
- * Header file for definitions used with crypto lib.
+ * Header file for definitions used with crypto lib.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_CRYPTOLIB
-#define _h_PS_CRYPTOLIB
+# define _h_PS_CRYPTOLIB
/******************************************************************************/
/*
- Additional 'hidden' algorithm configuration here for deprecated support
-*/
+ Additional 'hidden' algorithm configuration here for deprecated support
+ */
/** Symmetric. @security These are generally insecure and not enabled by default. */
-//#define USE_RC2
-//#define USE_ARC4
-//#define USE_SEED
-//#define USE_IDEA
-#ifdef USE_PKCS12
-//#define USE_RC2 /* Only PKCS#12 parse should ever want this algorithm */
-#endif
+/* #define USE_RC2 */
+/* #define USE_ARC4 */
+/* #define USE_SEED */
+/* #define USE_IDEA */
+# ifdef USE_PKCS12
+/* #define USE_RC2 / * Only PKCS#12 parse should ever want this algorithm * / */
+# endif
/** Digest. @security These are generally insecure and not enabled by default */
-//#define USE_MD4
-//#define USE_MD2
+/* #define USE_MD4 */
+/* #define USE_MD2 */
/** PRNG. @security By default the OS PRNG will be used directly. */
-#define USE_PRNG
-//#define USE_YARROW
+# define USE_PRNG
+/* #define USE_YARROW */
/******************************************************************************/
/*
- Additional configuration that is usually not modified.
-*/
-#define OCSP_VALID_TIME_WINDOW 604800 /* In seconds (1 week default window) */
+ Additional configuration that is usually not modified.
+ */
+# define OCSP_VALID_TIME_WINDOW 604800 /* In seconds (1 week default window) */
/******************************************************************************/
/*
- Include crypto provider layer headers
-*/
-#include "layer/layer.h"
+ Include crypto provider layer headers
+ */
+# include "layer/layer.h"
/* Configuration validation/sanity checks */
-#include "cryptoCheck.h"
+# include "cryptoCheck.h"
/* Implementation layer */
-#include "symmetric/symmetric.h"
-#include "digest/digest.h"
-#include "math/pstm.h"
-#include "pubkey/pubkey.h"
-#include "keyformat/asn1.h"
-#include "keyformat/x509.h"
-#include "prng/prng.h"
+# include "symmetric/symmetric.h"
+# include "digest/digest.h"
+# include "math/pstm.h"
+# include "pubkey/pubkey.h"
+# include "keyformat/asn1.h"
+# include "keyformat/x509.h"
+# include "prng/prng.h"
/******************************************************************************/
/*
- Crypto trace
-*/
-#ifndef USE_CRYPTO_TRACE
-#define psTraceCrypto(x)
-#define psTraceStrCrypto(x, y)
-#define psTraceIntCrypto(x, y)
-#define psTracePtrCrypto(x, y)
-#else
-#define psTraceCrypto(x) _psTrace(x)
-#define psTraceStrCrypto(x, y) _psTraceStr(x, y)
-#define psTraceIntCrypto(x, y) _psTraceInt(x, y)
-#define psTracePtrCrypto(x, y) _psTracePtr(x, y)
-#endif /* USE_CRYPTO_TRACE */
+ Crypto trace
+ */
+# ifndef USE_CRYPTO_TRACE
+# define psTraceCrypto(x)
+# define psTraceStrCrypto(x, y)
+# define psTraceIntCrypto(x, y)
+# define psTracePtrCrypto(x, y)
+# else
+# define psTraceCrypto(x) _psTrace(x)
+# define psTraceStrCrypto(x, y) _psTraceStr(x, y)
+# define psTraceIntCrypto(x, y) _psTraceInt(x, y)
+# define psTracePtrCrypto(x, y) _psTracePtr(x, y)
+# endif /* USE_CRYPTO_TRACE */
/******************************************************************************/
/*
- Helpers
-*/
-extern int32_t psBase64decode(const unsigned char *in, uint16_t len,
- unsigned char *out, uint16_t *outlen);
+ Helpers
+ */
+extern int32_t psBase64decode(const unsigned char *in, psSize_t len,
+ unsigned char *out, psSize_t *outlen);
extern void psOpenPrng(void);
extern void psClosePrng(void);
-extern int32_t matrixCryptoGetPrngData(unsigned char *bytes, uint16_t size,
- void *userPtr);
+extern int32_t psGetPrngLocked(unsigned char *bytes, psSize_t size,
+ void *userPtr);
/******************************************************************************/
/*
- RFC 3279 OID and PKCS standards OIDs
- Matrix uses an oid summing mechanism to arrive at these defines.
- The byte values of the OID are summed and compared with OID database
- entries to produce a unique numbers (assuming MATRIXSSL_NO_OID_DATABASE
- is not set.)
-*/
+ RFC 3279 OID and PKCS standards OIDs
+ Matrix uses an oid summing mechanism to arrive at these defines.
+ The byte values of the OID are summed and compared with OID database
+ entries to produce a unique numbers (assuming MATRIXSSL_NO_OID_DATABASE
+ is not set.)
+ */
-#ifdef MATRIXSSL_NO_OID_DATABASE
+# ifdef MATRIXSSL_NO_OID_DATABASE
/* Without OID database, some entries will be duplicates. */
-#define OID_COLLISION 0
-#else
+# define OID_COLLISION 0
+# else
/* To prevent collisions, some oids are added a sufficient multiple of this
to make them unique. */
-#define OID_COLLISION 1024
+# define OID_COLLISION 1024
/* Marking for OIDs that have not been discovered in the database.
The OIDs not discovered are guaranteed to be this value or larger. */
-#define OID_NOT_FOUND 32768
-#endif /* MATRIXSSL_NO_OID_DATABASE */
+# define OID_NOT_FOUND 32768
+# endif /* MATRIXSSL_NO_OID_DATABASE */
/* Raw digest algorithms */
-#define OID_SHA1_ALG_STR "1.3.14.3.2.26"
-#define OID_SHA1_ALG 88
-#define OID_SHA1_ALG_HEX "\x06\x05\x2B\x0E\x03\x02\x1A"
-#define OID_SHA256_ALG_STR "2.16.840.1.101.3.4.2.1"
-#define OID_SHA256_ALG 414
-#define OID_SHA256_ALG_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01"
-#define OID_SHA384_ALG_STR "2.16.840.1.101.3.4.2.2"
-#define OID_SHA384_ALG 415
-#define OID_SHA384_ALG_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02"
-#define OID_SHA512_ALG_STR "2.16.840.1.101.3.4.2.3"
-#define OID_SHA512_ALG 416
-#define OID_SHA512_ALG_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03"
-#define OID_MD2_ALG_STR "1.2.840.113549.2.2"
-#define OID_MD2_ALG 646
-#define OID_MD2_ALG_HEX "\x06\x08\x2A\x86\x48\x86\xF7\x0D\x02\x02"
-#define OID_MD5_ALG_STR "1.2.840.113549.2.5"
-#define OID_MD5_ALG 649
-#define OID_MD5_ALG_HEX "\x06\x08\x2A\x86\x48\x86\xF7\x0D\x02\x05"
+# define OID_SHA1_ALG_STR "1.3.14.3.2.26"
+# define OID_SHA1_ALG 88
+# define OID_SHA1_ALG_HEX "\x06\x05\x2B\x0E\x03\x02\x1A"
+# define OID_SHA256_ALG_STR "2.16.840.1.101.3.4.2.1"
+# define OID_SHA256_ALG 414
+# define OID_SHA256_ALG_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01"
+# define OID_SHA384_ALG_STR "2.16.840.1.101.3.4.2.2"
+# define OID_SHA384_ALG 415
+# define OID_SHA384_ALG_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02"
+# define OID_SHA512_ALG_STR "2.16.840.1.101.3.4.2.3"
+# define OID_SHA512_ALG 416
+# define OID_SHA512_ALG_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03"
+# define OID_MD2_ALG_STR "1.2.840.113549.2.2"
+# define OID_MD2_ALG 646
+# define OID_MD2_ALG_HEX "\x06\x08\x2A\x86\x48\x86\xF7\x0D\x02\x02"
+# define OID_MD5_ALG_STR "1.2.840.113549.2.5"
+# define OID_MD5_ALG 649
+# define OID_MD5_ALG_HEX "\x06\x08\x2A\x86\x48\x86\xF7\x0D\x02\x05"
/* Signature algorithms */
-#define OID_MD2_RSA_SIG_STR "1.2.840.113549.1.1.2"
-#define OID_MD2_RSA_SIG (646 + OID_COLLISION)
-#define OID_MD2_RSA_SIG_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x02"
-#define OID_MD5_RSA_SIG_STR "1.2.840.113549.1.1.4"
-#define OID_MD5_RSA_SIG 648
-#define OID_MD5_RSA_SIG_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x04"
-#define OID_SHA1_RSA_SIG_STR "1.2.840.113549.1.1.5"
-#define OID_SHA1_RSA_SIG (649 + OID_COLLISION)
-#define OID_SHA1_RSA_SIG_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05"
-#define OID_ID_MGF1_STR "1.2.840.113549.1.1.8"
-#define OID_ID_MGF1 (652 + OID_COLLISION * 2)
-#define OID_ID_MGF1_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x08"
-#define OID_RSASSA_PSS_STR "1.2.840.113549.1.1.10"
-#define OID_RSASSA_PSS (654 + OID_COLLISION)
-#define OID_RSASSA_PSS_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0A"
-#define OID_SHA256_RSA_SIG_STR "1.2.840.113549.1.1.11"
-#define OID_SHA256_RSA_SIG (655 + OID_COLLISION)
-#define OID_SHA256_RSA_SIG_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0B"
-#define OID_SHA384_RSA_SIG_STR "1.2.840.113549.1.1.12"
-#define OID_SHA384_RSA_SIG (656 + OID_COLLISION)
-#define OID_SHA384_RSA_SIG_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0C"
-#define OID_SHA512_RSA_SIG_STR "1.2.840.113549.1.1.13"
-#define OID_SHA512_RSA_SIG (657 + OID_COLLISION)
-#define OID_SHA512_RSA_SIG_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0D"
-#define OID_SHA1_DSA_SIG_STR "1.2.840.10040.4.3"
-#define OID_SHA1_DSA_SIG 517
-#define OID_SHA1_DSA_SIG_HEX "\x06\x07\x2A\x86\x48\xCE\x38\x04\x03"
-#define OID_SHA1_ECDSA_SIG_STR "1.2.840.10045.4.1"
-#define OID_SHA1_ECDSA_SIG 520
-#define OID_SHA1_ECDSA_SIG_HEX "\x06\x07\x2A\x86\x48\xCE\x3D\x04\x01"
-#define OID_SHA224_ECDSA_SIG_STR "1.2.840.10045.4.3.1"
-#define OID_SHA224_ECDSA_SIG 523
-#define OID_SHA224_ECDSA_SIG_HEX "\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x01"
-#define OID_SHA256_ECDSA_SIG_STR "1.2.840.10045.4.3.2"
-#define OID_SHA256_ECDSA_SIG 524
-#define OID_SHA256_ECDSA_SIG_HEX "\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02"
-#define OID_SHA384_ECDSA_SIG_STR "1.2.840.10045.4.3.3"
-#define OID_SHA384_ECDSA_SIG 525
-#define OID_SHA384_ECDSA_SIG_HEX "\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x03"
-#define OID_SHA512_ECDSA_SIG_STR "1.2.840.10045.4.3.4"
-#define OID_SHA512_ECDSA_SIG 526
-#define OID_SHA512_ECDSA_SIG_HEX "\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x04"
+# define OID_MD2_RSA_SIG_STR "1.2.840.113549.1.1.2"
+# define OID_MD2_RSA_SIG (646 + OID_COLLISION)
+# define OID_MD2_RSA_SIG_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x02"
+# define OID_MD5_RSA_SIG_STR "1.2.840.113549.1.1.4"
+# define OID_MD5_RSA_SIG 648
+# define OID_MD5_RSA_SIG_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x04"
+# define OID_SHA1_RSA_SIG_STR "1.2.840.113549.1.1.5"
+# define OID_SHA1_RSA_SIG (649 + OID_COLLISION)
+# define OID_SHA1_RSA_SIG_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05"
+# define OID_SHA1_RSA_SIG2_STR "1.3.14.3.2.29"
+# define OID_SHA1_RSA_SIG2 91/* Older, alternate for SHA1_RSA */
+# define OID_SHA1_RSA_SIG2_HEX "\x06\x05\x2B\x0E\x03\x02\x1D"
+# define OID_ID_MGF1_STR "1.2.840.113549.1.1.8"
+# define OID_ID_MGF1 (652 + OID_COLLISION * 2)
+# define OID_ID_MGF1_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x08"
+# define OID_RSASSA_PSS_STR "1.2.840.113549.1.1.10"
+# define OID_RSASSA_PSS (654 + OID_COLLISION)
+# define OID_RSASSA_PSS_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0A"
+# define OID_SHA256_RSA_SIG_STR "1.2.840.113549.1.1.11"
+# define OID_SHA256_RSA_SIG (655 + OID_COLLISION)
+# define OID_SHA256_RSA_SIG_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0B"
+# define OID_SHA384_RSA_SIG_STR "1.2.840.113549.1.1.12"
+# define OID_SHA384_RSA_SIG (656 + OID_COLLISION)
+# define OID_SHA384_RSA_SIG_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0C"
+# define OID_SHA512_RSA_SIG_STR "1.2.840.113549.1.1.13"
+# define OID_SHA512_RSA_SIG (657 + OID_COLLISION)
+# define OID_SHA512_RSA_SIG_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x0D"
+# define OID_SHA1_DSA_SIG_STR "1.2.840.10040.4.3"
+# define OID_SHA1_DSA_SIG 517
+# define OID_SHA1_DSA_SIG_HEX "\x06\x07\x2A\x86\x48\xCE\x38\x04\x03"
+# define OID_SHA1_ECDSA_SIG_STR "1.2.840.10045.4.1"
+# define OID_SHA1_ECDSA_SIG 520
+# define OID_SHA1_ECDSA_SIG_HEX "\x06\x07\x2A\x86\x48\xCE\x3D\x04\x01"
+# define OID_SHA224_ECDSA_SIG_STR "1.2.840.10045.4.3.1"
+# define OID_SHA224_ECDSA_SIG 523
+# define OID_SHA224_ECDSA_SIG_HEX "\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x01"
+# define OID_SHA256_ECDSA_SIG_STR "1.2.840.10045.4.3.2"
+# define OID_SHA256_ECDSA_SIG 524
+# define OID_SHA256_ECDSA_SIG_HEX "\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x02"
+# define OID_SHA384_ECDSA_SIG_STR "1.2.840.10045.4.3.3"
+# define OID_SHA384_ECDSA_SIG 525
+# define OID_SHA384_ECDSA_SIG_HEX "\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x03"
+# define OID_SHA512_ECDSA_SIG_STR "1.2.840.10045.4.3.4"
+# define OID_SHA512_ECDSA_SIG 526
+# define OID_SHA512_ECDSA_SIG_HEX "\x06\x08\x2A\x86\x48\xCE\x3D\x04\x03\x04"
/* Public key algorithms */
-#define OID_RSA_KEY_ALG_STR "1.2.840.113549.1.1.1"
-#define OID_RSA_KEY_ALG 645
-#define OID_RSA_KEY_ALG_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01"
-#define OID_DSA_KEY_ALG_STR "1.2.840.10040.4.1"
-#define OID_DSA_KEY_ALG 515
-#define OID_DSA_KEY_ALG_HEX "\x06\x07\x2A\x86\x48\xCE\x38\x04\x01"
-#define OID_ECDSA_KEY_ALG_STR "1.2.840.10045.2.1"
-#define OID_ECDSA_KEY_ALG 518
-#define OID_ECDSA_KEY_ALG_HEX "\x06\x07\x2A\x86\x48\xCE\x3D\x02\x01"
+# define OID_RSA_KEY_ALG_STR "1.2.840.113549.1.1.1"
+# define OID_RSA_KEY_ALG 645
+# define OID_RSA_KEY_ALG_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01"
+# define OID_DSA_KEY_ALG_STR "1.2.840.10040.4.1"
+# define OID_DSA_KEY_ALG 515
+# define OID_DSA_KEY_ALG_HEX "\x06\x07\x2A\x86\x48\xCE\x38\x04\x01"
+# define OID_ECDSA_KEY_ALG_STR "1.2.840.10045.2.1"
+# define OID_ECDSA_KEY_ALG 518
+# define OID_ECDSA_KEY_ALG_HEX "\x06\x07\x2A\x86\x48\xCE\x3D\x02\x01"
/* Encryption algorithms */
-#define OID_DES_EDE3_CBC_STR "1.2.840.113549.3.7"
-#define OID_DES_EDE3_CBC (652 + OID_COLLISION)
-#define OID_DES_EDE3_CBC_HEX "\x06\x08\x2A\x86\x48\x86\xF7\x0D\x03\x07"
+# define OID_DES_EDE3_CBC_STR "1.2.840.113549.3.7"
+# define OID_DES_EDE3_CBC (652 + OID_COLLISION)
+# define OID_DES_EDE3_CBC_HEX "\x06\x08\x2A\x86\x48\x86\xF7\x0D\x03\x07"
-#define OID_AES_128_CBC_STR "2.16.840.1.101.3.4.1.2"
-#define OID_AES_128_CBC (414 + OID_COLLISION)
-#define OID_AES_128_CBC_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x02"
-#define OID_AES_128_WRAP_STR "2.16.840.1.101.3.4.1.5"
-#define OID_AES_128_WRAP 417
-#define OID_AES_128_WRAP_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x05"
-#define OID_AES_128_GCM_STR "2.16.840.1.101.3.4.1.6"
-#define OID_AES_128_GCM 418
-#define OID_AES_128_GCM_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x06"
-#define OID_AES_192_CBC_STR "2.16.840.1.101.3.4.1.22"
-#define OID_AES_192_CBC 434
-#define OID_AES_192_CBC_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x16"
-#define OID_AES_192_WRAP_STR "2.16.840.1.101.3.4.1.25"
-#define OID_AES_192_WRAP 437
-#define OID_AES_192_WRAP_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x19"
-#define OID_AES_192_GCM_STR "2.16.840.1.101.3.4.1.26"
-#define OID_AES_192_GCM 438
-#define OID_AES_192_GCM_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x1A"
-#define OID_AES_256_CBC_STR "2.16.840.1.101.3.4.1.42"
-#define OID_AES_256_CBC 454
-#define OID_AES_256_CBC_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x2A"
-#define OID_AES_256_WRAP_STR "2.16.840.1.101.3.4.1.45"
-#define OID_AES_256_WRAP 457
-#define OID_AES_256_WRAP_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x2D"
-#define OID_AES_256_GCM_STR "2.16.840.1.101.3.4.1.46"
-#define OID_AES_256_GCM 458
-#define OID_AES_256_GCM_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x2E"
+# define OID_AES_128_CBC_STR "2.16.840.1.101.3.4.1.2"
+# define OID_AES_128_CBC (414 + OID_COLLISION)
+# define OID_AES_128_CBC_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x02"
+# define OID_AES_128_WRAP_STR "2.16.840.1.101.3.4.1.5"
+# define OID_AES_128_WRAP 417
+# define OID_AES_128_WRAP_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x05"
+# define OID_AES_128_GCM_STR "2.16.840.1.101.3.4.1.6"
+# define OID_AES_128_GCM 418
+# define OID_AES_128_GCM_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x06"
+# define OID_AES_192_CBC_STR "2.16.840.1.101.3.4.1.22"
+# define OID_AES_192_CBC 434
+# define OID_AES_192_CBC_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x16"
+# define OID_AES_192_WRAP_STR "2.16.840.1.101.3.4.1.25"
+# define OID_AES_192_WRAP 437
+# define OID_AES_192_WRAP_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x19"
+# define OID_AES_192_GCM_STR "2.16.840.1.101.3.4.1.26"
+# define OID_AES_192_GCM 438
+# define OID_AES_192_GCM_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x1A"
+# define OID_AES_256_CBC_STR "2.16.840.1.101.3.4.1.42"
+# define OID_AES_256_CBC 454
+# define OID_AES_256_CBC_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x2A"
+# define OID_AES_256_WRAP_STR "2.16.840.1.101.3.4.1.45"
+# define OID_AES_256_WRAP 457
+# define OID_AES_256_WRAP_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x2D"
+# define OID_AES_256_GCM_STR "2.16.840.1.101.3.4.1.46"
+# define OID_AES_256_GCM 458
+# define OID_AES_256_GCM_HEX "\x06\x09\x60\x86\x48\x01\x65\x03\x04\x01\x2E"
-#define OID_AES_CMAC_STR "2.16.840.1.101.3.4.1.200_alt"
-#define OID_AES_CMAC 612
-#define OID_AES_CMAC_HEX "\x06\x0A\x60\x86\x48\x01\x65\x03\x04\x01\xC8"
+# define OID_AES_CMAC_STR "2.16.840.1.101.3.4.1.200_alt"
+# define OID_AES_CMAC 612
+# define OID_AES_CMAC_HEX "\x06\x0A\x60\x86\x48\x01\x65\x03\x04\x01\xC8"
-#define OID_AES_CBC_CMAC_128_STR "0.4.0.127.0.7.1.1.1.2"
-#define OID_AES_CBC_CMAC_128 143
-#define OID_AES_CBC_CMAC_128_HEX "\x06\x09\x04\x00\x7F\x00\x07\x01\x01\x01\x02"
-#define OID_AES_CBC_CMAC_192_STR "0.4.0.127.0.7.1.1.1.3"
-#define OID_AES_CBC_CMAC_192 144
-#define OID_AES_CBC_CMAC_192_HEX "\x06\x09\x04\x00\x7F\x00\x07\x01\x01\x01\x03"
-#define OID_AES_CBC_CMAC_256_STR "0.4.0.127.0.7.1.1.1.4"
-#define OID_AES_CBC_CMAC_256 145
-#define OID_AES_CBC_CMAC_256_HEX "\x06\x09\x04\x00\x7F\x00\x07\x01\x01\x01\x04"
+# define OID_AES_CBC_CMAC_128_STR "0.4.0.127.0.7.1.1.1.2"
+# define OID_AES_CBC_CMAC_128 143
+# define OID_AES_CBC_CMAC_128_HEX "\x06\x09\x04\x00\x7F\x00\x07\x01\x01\x01\x02"
+# define OID_AES_CBC_CMAC_192_STR "0.4.0.127.0.7.1.1.1.3"
+# define OID_AES_CBC_CMAC_192 144
+# define OID_AES_CBC_CMAC_192_HEX "\x06\x09\x04\x00\x7F\x00\x07\x01\x01\x01\x03"
+# define OID_AES_CBC_CMAC_256_STR "0.4.0.127.0.7.1.1.1.4"
+# define OID_AES_CBC_CMAC_256 145
+# define OID_AES_CBC_CMAC_256_HEX "\x06\x09\x04\x00\x7F\x00\x07\x01\x01\x01\x04"
-#define OID_AUTH_ENC_256_SUM_STR "1.2.840.113549.1.9.16.3.16"
-#define OID_AUTH_ENC_256_SUM 687 /* See RFC 6476 */
-#define OID_AUTH_ENC_256_SUM_HEX "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x03\x10"
+# define OID_AUTH_ENC_256_SUM_STR "1.2.840.113549.1.9.16.3.16"
+# define OID_AUTH_ENC_256_SUM 687/* See RFC 6476 */
+# define OID_AUTH_ENC_256_SUM_HEX "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x03\x10"
-#define OID_PKCS_PBKDF2_STR "1.2.840.113549.1.5.12"
-#define OID_PKCS_PBKDF2 (660 + OID_COLLISION)
-#define OID_PKCS_PBKDF2_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x05\x0C"
-#define OID_PKCS_PBES2_STR "1.2.840.113549.1.5.13"
-#define OID_PKCS_PBES2 (661 + OID_COLLISION)
-#define OID_PKCS_PBES2_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x05\x0D"
+# define OID_PKCS_PBKDF2_STR "1.2.840.113549.1.5.12"
+# define OID_PKCS_PBKDF2 (660 + OID_COLLISION)
+# define OID_PKCS_PBKDF2_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x05\x0C"
+# define OID_PKCS_PBES2_STR "1.2.840.113549.1.5.13"
+# define OID_PKCS_PBES2 (661 + OID_COLLISION)
+# define OID_PKCS_PBES2_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x05\x0D"
-#define OID_PKCS_PBESHA128RC4_STR "1.2.840.113549.1.12.1.1"
-#define OID_PKCS_PBESHA128RC4 657
-#define OID_PKCS_PBESHA128RC4_HEX "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x01"
-#define OID_PKCS_PBESHA40RC4_STR "1.2.840.113549.1.12.1.2"
-#define OID_PKCS_PBESHA40RC4 658
-#define OID_PKCS_PBESHA40RC4_HEX "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x02"
-#define OID_PKCS_PBESHA3DES3_STR "1.2.840.113549.1.12.1.3"
-#define OID_PKCS_PBESHA3DES3 659
-#define OID_PKCS_PBESHA3DES3_HEX "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x03"
-#define OID_PKCS_PBESHA2DES3_STR "1.2.840.113549.1.12.1.4"
-#define OID_PKCS_PBESHA2DES3 660
-#define OID_PKCS_PBESHA2DES3_HEX "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x04"
-#define OID_PKCS_PBESHA128RC2_STR "1.2.840.113549.1.12.1.5"
-#define OID_PKCS_PBESHA128RC2 661
-#define OID_PKCS_PBESHA128RC2_HEX "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x05"
-#define OID_PKCS_PBESHA40RC2_STR "1.2.840.113549.1.12.1.6"
-#define OID_PKCS_PBESHA40RC2 662
-#define OID_PKCS_PBESHA40RC2_HEX "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x06"
+# define OID_PKCS_PBESHA128RC4_STR "1.2.840.113549.1.12.1.1"
+# define OID_PKCS_PBESHA128RC4 657
+# define OID_PKCS_PBESHA128RC4_HEX "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x01"
+# define OID_PKCS_PBESHA40RC4_STR "1.2.840.113549.1.12.1.2"
+# define OID_PKCS_PBESHA40RC4 658
+# define OID_PKCS_PBESHA40RC4_HEX "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x02"
+# define OID_PKCS_PBESHA3DES3_STR "1.2.840.113549.1.12.1.3"
+# define OID_PKCS_PBESHA3DES3 659
+# define OID_PKCS_PBESHA3DES3_HEX "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x03"
+# define OID_PKCS_PBESHA2DES3_STR "1.2.840.113549.1.12.1.4"
+# define OID_PKCS_PBESHA2DES3 660
+# define OID_PKCS_PBESHA2DES3_HEX "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x04"
+# define OID_PKCS_PBESHA128RC2_STR "1.2.840.113549.1.12.1.5"
+# define OID_PKCS_PBESHA128RC2 661
+# define OID_PKCS_PBESHA128RC2_HEX "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x05"
+# define OID_PKCS_PBESHA40RC2_STR "1.2.840.113549.1.12.1.6"
+# define OID_PKCS_PBESHA40RC2 662
+# define OID_PKCS_PBESHA40RC2_HEX "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x01\x06"
-#define OID_PKCS12_BAG_TYPE_KEY_STR "1.2.840.113549.1.12.10.1.1"
-#define OID_PKCS12_BAG_TYPE_KEY 667
-#define OID_PKCS12_BAG_TYPE_KEY_HEX "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x0A\x01\x01"
-#define OID_PKCS12_BAG_TYPE_SHROUD_STR "1.2.840.113549.1.12.10.1.2"
-#define OID_PKCS12_BAG_TYPE_SHROUD 668
-#define OID_PKCS12_BAG_TYPE_SHROUD_HEX "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x0A\x01\x02"
-#define OID_PKCS12_BAG_TYPE_CERT_STR "1.2.840.113549.1.12.10.1.3"
-#define OID_PKCS12_BAG_TYPE_CERT 669
-#define OID_PKCS12_BAG_TYPE_CERT_HEX "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x0A\x01\x03"
-#define OID_PKCS12_BAG_TYPE_CRL_STR "1.2.840.113549.1.12.10.1.4"
-#define OID_PKCS12_BAG_TYPE_CRL 670
-#define OID_PKCS12_BAG_TYPE_CRL_HEX "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x0A\x01\x04"
-#define OID_PKCS12_BAG_TYPE_SECRET_STR "1.2.840.113549.1.12.10.1.5"
-#define OID_PKCS12_BAG_TYPE_SECRET 671
-#define OID_PKCS12_BAG_TYPE_SECRET_HEX "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x0A\x01\x05"
-#define OID_PKCS12_BAG_TYPE_SAFE_STR "1.2.840.113549.1.12.10.1.6"
-#define OID_PKCS12_BAG_TYPE_SAFE 672
-#define OID_PKCS12_BAG_TYPE_SAFE_HEX "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x0A\x01\x06"
+# define OID_PKCS12_BAG_TYPE_KEY_STR "1.2.840.113549.1.12.10.1.1"
+# define OID_PKCS12_BAG_TYPE_KEY 667
+# define OID_PKCS12_BAG_TYPE_KEY_HEX "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x0A\x01\x01"
+# define OID_PKCS12_BAG_TYPE_SHROUD_STR "1.2.840.113549.1.12.10.1.2"
+# define OID_PKCS12_BAG_TYPE_SHROUD 668
+# define OID_PKCS12_BAG_TYPE_SHROUD_HEX "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x0A\x01\x02"
+# define OID_PKCS12_BAG_TYPE_CERT_STR "1.2.840.113549.1.12.10.1.3"
+# define OID_PKCS12_BAG_TYPE_CERT 669
+# define OID_PKCS12_BAG_TYPE_CERT_HEX "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x0A\x01\x03"
+# define OID_PKCS12_BAG_TYPE_CRL_STR "1.2.840.113549.1.12.10.1.4"
+# define OID_PKCS12_BAG_TYPE_CRL 670
+# define OID_PKCS12_BAG_TYPE_CRL_HEX "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x0A\x01\x04"
+# define OID_PKCS12_BAG_TYPE_SECRET_STR "1.2.840.113549.1.12.10.1.5"
+# define OID_PKCS12_BAG_TYPE_SECRET 671
+# define OID_PKCS12_BAG_TYPE_SECRET_HEX "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x0A\x01\x05"
+# define OID_PKCS12_BAG_TYPE_SAFE_STR "1.2.840.113549.1.12.10.1.6"
+# define OID_PKCS12_BAG_TYPE_SAFE 672
+# define OID_PKCS12_BAG_TYPE_SAFE_HEX "\x06\x0B\x2A\x86\x48\x86\xF7\x0D\x01\x0C\x0A\x01\x06"
-#define OID_PKCS9_CERT_TYPE_X509_STR "1.2.840.113549.1.9.22.1"
-#define OID_PKCS9_CERT_TYPE_X509 675
-#define OID_PKCS9_CERT_TYPE_X509_HEX "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x09\x16\x01"
-#define OID_PKCS9_CERT_TYPE_SDSI_STR "1.2.840.113549.1.9.22.2"
-#define OID_PKCS9_CERT_TYPE_SDSI 676
-#define OID_PKCS9_CERT_TYPE_SDSI_HEX "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x09\x16\x02"
+# define OID_PKCS9_CERT_TYPE_X509_STR "1.2.840.113549.1.9.22.1"
+# define OID_PKCS9_CERT_TYPE_X509 675
+# define OID_PKCS9_CERT_TYPE_X509_HEX "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x09\x16\x01"
+# define OID_PKCS9_CERT_TYPE_SDSI_STR "1.2.840.113549.1.9.22.2"
+# define OID_PKCS9_CERT_TYPE_SDSI 676
+# define OID_PKCS9_CERT_TYPE_SDSI_HEX "\x06\x0A\x2A\x86\x48\x86\xF7\x0D\x01\x09\x16\x02"
-#define OID_PKCS7_DATA_STR "1.2.840.113549.1.7.1"
-#define OID_PKCS7_DATA 651
-#define OID_PKCS7_DATA_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x01"
-#define OID_PKCS7_SIGNED_DATA_STR "1.2.840.113549.1.7.2"
-#define OID_PKCS7_SIGNED_DATA 652
-#define OID_PKCS7_SIGNED_DATA_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x02"
-#define OID_PKCS7_ENVELOPED_DATA_STR "1.2.840.113549.1.7.3"
-#define OID_PKCS7_ENVELOPED_DATA 653
-#define OID_PKCS7_ENVELOPED_DATA_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x03"
-#define OID_PKCS7_SIGNED_ENVELOPED_DATA_STR "1.2.840.113549.1.7.4"
-#define OID_PKCS7_SIGNED_ENVELOPED_DATA 654
-#define OID_PKCS7_SIGNED_ENVELOPED_DATA_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x04"
-#define OID_PKCS7_DIGESTED_DATA_STR "1.2.840.113549.1.7.5"
-#define OID_PKCS7_DIGESTED_DATA 655
-#define OID_PKCS7_DIGESTED_DATA_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x05"
-#define OID_PKCS7_ENCRYPTED_DATA_STR "1.2.840.113549.1.7.6"
-#define OID_PKCS7_ENCRYPTED_DATA 656
-#define OID_PKCS7_ENCRYPTED_DATA_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x06"
+# define OID_PKCS7_DATA_STR "1.2.840.113549.1.7.1"
+# define OID_PKCS7_DATA 651
+# define OID_PKCS7_DATA_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x01"
+# define OID_PKCS7_SIGNED_DATA_STR "1.2.840.113549.1.7.2"
+# define OID_PKCS7_SIGNED_DATA 652
+# define OID_PKCS7_SIGNED_DATA_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x02"
+# define OID_PKCS7_ENVELOPED_DATA_STR "1.2.840.113549.1.7.3"
+# define OID_PKCS7_ENVELOPED_DATA 653
+# define OID_PKCS7_ENVELOPED_DATA_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x03"
+# define OID_PKCS7_SIGNED_ENVELOPED_DATA_STR "1.2.840.113549.1.7.4"
+# define OID_PKCS7_SIGNED_ENVELOPED_DATA 654
+# define OID_PKCS7_SIGNED_ENVELOPED_DATA_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x04"
+# define OID_PKCS7_DIGESTED_DATA_STR "1.2.840.113549.1.7.5"
+# define OID_PKCS7_DIGESTED_DATA 655
+# define OID_PKCS7_DIGESTED_DATA_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x05"
+# define OID_PKCS7_ENCRYPTED_DATA_STR "1.2.840.113549.1.7.6"
+# define OID_PKCS7_ENCRYPTED_DATA 656
+# define OID_PKCS7_ENCRYPTED_DATA_HEX "\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x06"
-#define OID_OCSP_STR "1.3.6.1.5.5.7.48.1"
-#define OID_OCSP 116
-#define OID_OCSP_HEX "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x01"
-#define OID_BASIC_OCSP_RESPONSE_STR "1.3.6.1.5.5.7.48.1.1"
-#define OID_BASIC_OCSP_RESPONSE 117
-#define OID_BASIC_OCSP_RESPONSE_HEX "\x06\x09\x2B\x06\x01\x05\x05\x07\x30\x01\x01"
+# define OID_OCSP_STR "1.3.6.1.5.5.7.48.1"
+# define OID_OCSP 116
+# define OID_OCSP_HEX "\x06\x08\x2B\x06\x01\x05\x05\x07\x30\x01"
+# define OID_BASIC_OCSP_RESPONSE_STR "1.3.6.1.5.5.7.48.1.1"
+# define OID_BASIC_OCSP_RESPONSE 117
+# define OID_BASIC_OCSP_RESPONSE_HEX "\x06\x09\x2B\x06\x01\x05\x05\x07\x30\x01\x01"
-#define PBE12 1
-#define PBES2 2
-#define AUTH_SAFE_3DES 1
-#define AUTH_SAFE_RC2 2
+# define PBE12 1
+# define PBES2 2
+# define AUTH_SAFE_3DES 1
+# define AUTH_SAFE_RC2 2
-#define PKCS12_KEY_ID 1
-#define PKCS12_IV_ID 2
-#define PKCS12_MAC_ID 3
+# define PKCS12_KEY_ID 1
+# define PKCS12_IV_ID 2
+# define PKCS12_MAC_ID 3
-#if defined(USE_PKCS1_OAEP) || defined(USE_PKCS1_PSS)
-#define PKCS1_SHA1_ID 0
-#define PKCS1_MD5_ID 1
-#define PKCS1_SHA256_ID 2
-#define PKCS1_SHA384_ID 3
-#define PKCS1_SHA512_ID 4
-#endif
+# if defined(USE_PKCS1_OAEP) || defined(USE_PKCS1_PSS)
+# define PKCS1_SHA1_ID 0
+# define PKCS1_MD5_ID 1
+# define PKCS1_SHA256_ID 2
+# define PKCS1_SHA384_ID 3
+# define PKCS1_SHA512_ID 4
+# endif
/******************************************************************************/
/* These values are all mutually exlusive bits to define Cipher flags */
-#define CRYPTO_FLAGS_AES (1<<0)
-#define CRYPTO_FLAGS_AES256 (1<<1)
-#define CRYPTO_FLAGS_3DES (1<<2)
-#define CRYPTO_FLAGS_ARC4 (1<<3)
-#define CRYPTO_FLAGS_SEED (1<<4)
-#define CRYPTO_FLAGS_IDEA (1<<5)
-#define CRYPTO_FLAGS_CHACHA (1<<6) /* Short for CHACHA20_POLY2305 */
+# define CRYPTO_FLAGS_AES (1 << 0)
+# define CRYPTO_FLAGS_AES256 (1 << 1)
+# define CRYPTO_FLAGS_3DES (1 << 2)
+# define CRYPTO_FLAGS_ARC4 (1 << 3)
+# define CRYPTO_FLAGS_SEED (1 << 4)
+# define CRYPTO_FLAGS_IDEA (1 << 5)
+# define CRYPTO_FLAGS_CHACHA (1 << 6) /* Short for CHACHA20_POLY2305 */
-#define CRYPTO_FLAGS_SHA1 (1<< 8)
-#define CRYPTO_FLAGS_SHA2 (1<< 9)
-#define CRYPTO_FLAGS_SHA3 (1<<10)
-#define CRYPTO_FLAGS_GCM (1<<11)
-#define CRYPTO_FLAGS_CCM (1<<12)
-#define CRYPTO_FLAGS_CCM8 (1<<13) /* CCM mode with 8 byte ICV */
-#define CRYPTO_FLAGS_MD5 (1<<14)
+# define CRYPTO_FLAGS_SHA1 (1 << 8)
+# define CRYPTO_FLAGS_SHA2 (1 << 9)
+# define CRYPTO_FLAGS_SHA3 (1 << 10)
+# define CRYPTO_FLAGS_GCM (1 << 11)
+# define CRYPTO_FLAGS_CCM (1 << 12)
+# define CRYPTO_FLAGS_CCM8 (1 << 13)/* CCM mode with 8 byte ICV */
+# define CRYPTO_FLAGS_MD5 (1 << 14)
-#define CRYPTO_FLAGS_TLS (1<<16)
-#define CRYPTO_FLAGS_TLS_1_1 (1<<17)
-#define CRYPTO_FLAGS_TLS_1_2 (1<<18)
+# define CRYPTO_FLAGS_TLS (1 << 16)
+# define CRYPTO_FLAGS_TLS_1_1 (1 << 17)
+# define CRYPTO_FLAGS_TLS_1_2 (1 << 18)
-#define CRYPTO_FLAGS_INBOUND (1<<24)
-#define CRYPTO_FLAGS_ARC4INITE (1<<25)
-#define CRYPTO_FLAGS_ARC4INITD (1<<26)
-#define CRYPTO_FLAGS_BLOCKING (1<<27)
+# define CRYPTO_FLAGS_INBOUND (1 << 24)
+# define CRYPTO_FLAGS_ARC4INITE (1 << 25)
+# define CRYPTO_FLAGS_ARC4INITD (1 << 26)
+# define CRYPTO_FLAGS_BLOCKING (1 << 27)
-#define CRYPTO_FLAGS_DISABLED (1<<30)
+# define CRYPTO_FLAGS_DISABLED (1 << 30)
/******************************************************************************/
-#define CRYPT_INVALID_KEYSIZE -21
-#define CRYPT_INVALID_ROUNDS -22
+# define CRYPT_INVALID_KEYSIZE -21
+# define CRYPT_INVALID_ROUNDS -22
/******************************************************************************/
/* 32-bit Rotates */
/******************************************************************************/
-#if defined(_MSC_VER)
+# if defined(_MSC_VER)
/******************************************************************************/
/* instrinsic rotate */
-#include
-#pragma intrinsic(_lrotr,_lrotl)
-#define ROR(x,n) _lrotr(x,n)
-#define ROL(x,n) _lrotl(x,n)
+# include
+# pragma intrinsic(_lrotr,_lrotl)
+# define ROR(x, n) _lrotr(x, n)
+# define ROL(x, n) _lrotl(x, n)
/******************************************************************************/
-#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && \
- !defined(INTEL_CC) && !defined(PS_NO_ASM)
+# elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && \
+ !defined(INTEL_CC) && !defined(PS_NO_ASM)
static __inline unsigned ROL(unsigned word, int i)
{
- asm ("roll %%cl,%0"
- :"=r" (word)
- :"0" (word),"c" (i));
- return word;
+ asm ("roll %%cl,%0"
+ : "=r" (word)
+ : "0" (word), "c" (i));
+ return word;
}
static __inline unsigned ROR(unsigned word, int i)
{
- asm ("rorl %%cl,%0"
- :"=r" (word)
- :"0" (word),"c" (i));
- return word;
+ asm ("rorl %%cl,%0"
+ : "=r" (word)
+ : "0" (word), "c" (i));
+ return word;
}
/******************************************************************************/
-#else
+# else
/* rotates the hard way */
-#define ROL(x, y) \
- ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | \
- (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & \
- 0xFFFFFFFFUL)
-#define ROR(x, y) \
- ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | \
- ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
+# define ROL(x, y) \
+ ( (((unsigned long) (x) << (unsigned long) ((y) & 31)) | \
+ (((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) (32 - ((y) & 31)))) & \
+ 0xFFFFFFFFUL)
+# define ROR(x, y) \
+ ( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \
+ ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
-#endif /* 32-bit Rotates */
+# endif /* 32-bit Rotates */
/******************************************************************************/
-#ifdef HAVE_NATIVE_INT64
-#ifdef _MSC_VER
- #define CONST64(n) n ## ui64
-#else
- #define CONST64(n) n ## ULL
-#endif
-#endif
+# ifdef HAVE_NATIVE_INT64
+# ifdef _MSC_VER
+# define CONST64(n) n ## ui64
+# else
+# define CONST64(n) n ## ULL
+# endif
+# endif
/******************************************************************************/
/*
- Endian helper macros
+ Endian helper macros
*/
-#if defined (ENDIAN_NEUTRAL)
-#define STORE32L(x, y) { \
-(y)[3] = (unsigned char)(((x)>>24)&255); \
-(y)[2] = (unsigned char)(((x)>>16)&255); \
-(y)[1] = (unsigned char)(((x)>>8)&255); \
-(y)[0] = (unsigned char)((x)&255); \
+# if defined (ENDIAN_NEUTRAL)
+# define STORE32L(x, y) { \
+ (y)[3] = (unsigned char) (((x) >> 24) & 255); \
+ (y)[2] = (unsigned char) (((x) >> 16) & 255); \
+ (y)[1] = (unsigned char) (((x) >> 8) & 255); \
+ (y)[0] = (unsigned char) ((x) & 255); \
}
-#define LOAD32L(x, y) { \
-x = ((unsigned long)((y)[3] & 255)<<24) | \
-((unsigned long)((y)[2] & 255)<<16) | \
-((unsigned long)((y)[1] & 255)<<8) | \
-((unsigned long)((y)[0] & 255)); \
+# define LOAD32L(x, y) { \
+ x = ((unsigned long) ((y)[3] & 255) << 24) | \
+ ((unsigned long) ((y)[2] & 255) << 16) | \
+ ((unsigned long) ((y)[1] & 255) << 8) | \
+ ((unsigned long) ((y)[0] & 255)); \
}
-#define STORE64L(x, y) { \
-(y)[7] = (unsigned char)(((x)>>56)&255); \
-(y)[6] = (unsigned char)(((x)>>48)&255); \
-(y)[5] = (unsigned char)(((x)>>40)&255); \
-(y)[4] = (unsigned char)(((x)>>32)&255); \
-(y)[3] = (unsigned char)(((x)>>24)&255); \
-(y)[2] = (unsigned char)(((x)>>16)&255); \
-(y)[1] = (unsigned char)(((x)>>8)&255); \
-(y)[0] = (unsigned char)((x)&255); \
+# define STORE64L(x, y) { \
+ (y)[7] = (unsigned char) (((x) >> 56) & 255); \
+ (y)[6] = (unsigned char) (((x) >> 48) & 255); \
+ (y)[5] = (unsigned char) (((x) >> 40) & 255); \
+ (y)[4] = (unsigned char) (((x) >> 32) & 255); \
+ (y)[3] = (unsigned char) (((x) >> 24) & 255); \
+ (y)[2] = (unsigned char) (((x) >> 16) & 255); \
+ (y)[1] = (unsigned char) (((x) >> 8) & 255); \
+ (y)[0] = (unsigned char) ((x) & 255); \
}
-#define LOAD64L(x, y) { \
-x = (((uint64)((y)[7] & 255))<<56)|(((uint64)((y)[6] & 255))<<48)| \
-(((uint64)((y)[5] & 255))<<40)|(((uint64)((y)[4] & 255))<<32)| \
-(((uint64)((y)[3] & 255))<<24)|(((uint64)((y)[2] & 255))<<16)| \
-(((uint64)((y)[1] & 255))<<8)|(((uint64)((y)[0] & 255))); \
+# define LOAD64L(x, y) { \
+ x = (((uint64) ((y)[7] & 255)) << 56) | (((uint64) ((y)[6] & 255)) << 48) | \
+ (((uint64) ((y)[5] & 255)) << 40) | (((uint64) ((y)[4] & 255)) << 32) | \
+ (((uint64) ((y)[3] & 255)) << 24) | (((uint64) ((y)[2] & 255)) << 16) | \
+ (((uint64) ((y)[1] & 255)) << 8) | (((uint64) ((y)[0] & 255))); \
}
-#define STORE32H(x, y) { \
-(y)[0] = (unsigned char)(((x)>>24)&255); \
-(y)[1] = (unsigned char)(((x)>>16)&255); \
-(y)[2] = (unsigned char)(((x)>>8)&255); \
-(y)[3] = (unsigned char)((x)&255); \
+# define STORE32H(x, y) { \
+ (y)[0] = (unsigned char) (((x) >> 24) & 255); \
+ (y)[1] = (unsigned char) (((x) >> 16) & 255); \
+ (y)[2] = (unsigned char) (((x) >> 8) & 255); \
+ (y)[3] = (unsigned char) ((x) & 255); \
}
-#define LOAD32H(x, y) { \
-x = ((unsigned long)((y)[0] & 255)<<24) | \
-((unsigned long)((y)[1] & 255)<<16) | \
-((unsigned long)((y)[2] & 255)<<8) | \
-((unsigned long)((y)[3] & 255)); \
+# define LOAD32H(x, y) { \
+ x = ((unsigned long) ((y)[0] & 255) << 24) | \
+ ((unsigned long) ((y)[1] & 255) << 16) | \
+ ((unsigned long) ((y)[2] & 255) << 8) | \
+ ((unsigned long) ((y)[3] & 255)); \
}
-#define STORE64H(x, y) { \
-(y)[0] = (unsigned char)(((x)>>56)&255); \
-(y)[1] = (unsigned char)(((x)>>48)&255); \
-(y)[2] = (unsigned char)(((x)>>40)&255); \
-(y)[3] = (unsigned char)(((x)>>32)&255); \
-(y)[4] = (unsigned char)(((x)>>24)&255); \
-(y)[5] = (unsigned char)(((x)>>16)&255); \
-(y)[6] = (unsigned char)(((x)>>8)&255); \
-(y)[7] = (unsigned char)((x)&255); \
+# define STORE64H(x, y) { \
+ (y)[0] = (unsigned char) (((x) >> 56) & 255); \
+ (y)[1] = (unsigned char) (((x) >> 48) & 255); \
+ (y)[2] = (unsigned char) (((x) >> 40) & 255); \
+ (y)[3] = (unsigned char) (((x) >> 32) & 255); \
+ (y)[4] = (unsigned char) (((x) >> 24) & 255); \
+ (y)[5] = (unsigned char) (((x) >> 16) & 255); \
+ (y)[6] = (unsigned char) (((x) >> 8) & 255); \
+ (y)[7] = (unsigned char) ((x) & 255); \
}
-#define LOAD64H(x, y) { \
-x = (((uint64)((y)[0] & 255))<<56)|(((uint64)((y)[1] & 255))<<48) | \
-(((uint64)((y)[2] & 255))<<40)|(((uint64)((y)[3] & 255))<<32) | \
-(((uint64)((y)[4] & 255))<<24)|(((uint64)((y)[5] & 255))<<16) | \
-(((uint64)((y)[6] & 255))<<8)|(((uint64)((y)[7] & 255))); \
+# define LOAD64H(x, y) { \
+ x = (((uint64) ((y)[0] & 255)) << 56) | (((uint64) ((y)[1] & 255)) << 48) | \
+ (((uint64) ((y)[2] & 255)) << 40) | (((uint64) ((y)[3] & 255)) << 32) | \
+ (((uint64) ((y)[4] & 255)) << 24) | (((uint64) ((y)[5] & 255)) << 16) | \
+ (((uint64) ((y)[6] & 255)) << 8) | (((uint64) ((y)[7] & 255))); \
}
-#endif /* ENDIAN_NEUTRAL */
+# endif /* ENDIAN_NEUTRAL */
-#ifdef ENDIAN_LITTLE
-#define STORE32H(x, y) { \
-(y)[0] = (unsigned char)(((x)>>24)&255); \
-(y)[1] = (unsigned char)(((x)>>16)&255); \
-(y)[2] = (unsigned char)(((x)>>8)&255); \
-(y)[3] = (unsigned char)((x)&255); \
+# ifdef ENDIAN_LITTLE
+# define STORE32H(x, y) { \
+ (y)[0] = (unsigned char) (((x) >> 24) & 255); \
+ (y)[1] = (unsigned char) (((x) >> 16) & 255); \
+ (y)[2] = (unsigned char) (((x) >> 8) & 255); \
+ (y)[3] = (unsigned char) ((x) & 255); \
}
-#define LOAD32H(x, y) { \
-x = ((unsigned long)((y)[0] & 255)<<24) | \
-((unsigned long)((y)[1] & 255)<<16) | \
-((unsigned long)((y)[2] & 255)<<8) | \
-((unsigned long)((y)[3] & 255)); \
+# define LOAD32H(x, y) { \
+ x = ((unsigned long) ((y)[0] & 255) << 24) | \
+ ((unsigned long) ((y)[1] & 255) << 16) | \
+ ((unsigned long) ((y)[2] & 255) << 8) | \
+ ((unsigned long) ((y)[3] & 255)); \
}
-#define STORE64H(x, y) { \
-(y)[0] = (unsigned char)(((x)>>56)&255); \
-(y)[1] = (unsigned char)(((x)>>48)&255); \
-(y)[2] = (unsigned char)(((x)>>40)&255); \
-(y)[3] = (unsigned char)(((x)>>32)&255); \
-(y)[4] = (unsigned char)(((x)>>24)&255); \
-(y)[5] = (unsigned char)(((x)>>16)&255); \
-(y)[6] = (unsigned char)(((x)>>8)&255); \
-(y)[7] = (unsigned char)((x)&255); \
+# define STORE64H(x, y) { \
+ (y)[0] = (unsigned char) (((x) >> 56) & 255); \
+ (y)[1] = (unsigned char) (((x) >> 48) & 255); \
+ (y)[2] = (unsigned char) (((x) >> 40) & 255); \
+ (y)[3] = (unsigned char) (((x) >> 32) & 255); \
+ (y)[4] = (unsigned char) (((x) >> 24) & 255); \
+ (y)[5] = (unsigned char) (((x) >> 16) & 255); \
+ (y)[6] = (unsigned char) (((x) >> 8) & 255); \
+ (y)[7] = (unsigned char) ((x) & 255); \
}
-#define LOAD64H(x, y) { \
-x = (((uint64)((y)[0] & 255))<<56)|(((uint64)((y)[1] & 255))<<48) | \
-(((uint64)((y)[2] & 255))<<40)|(((uint64)((y)[3] & 255))<<32) | \
-(((uint64)((y)[4] & 255))<<24)|(((uint64)((y)[5] & 255))<<16) | \
-(((uint64)((y)[6] & 255))<<8)|(((uint64)((y)[7] & 255))); }
+# define LOAD64H(x, y) { \
+ x = (((uint64) ((y)[0] & 255)) << 56) | (((uint64) ((y)[1] & 255)) << 48) | \
+ (((uint64) ((y)[2] & 255)) << 40) | (((uint64) ((y)[3] & 255)) << 32) | \
+ (((uint64) ((y)[4] & 255)) << 24) | (((uint64) ((y)[5] & 255)) << 16) | \
+ (((uint64) ((y)[6] & 255)) << 8) | (((uint64) ((y)[7] & 255))); }
-#ifdef ENDIAN_32BITWORD
-#define STORE32L(x, y) { \
-unsigned long __t = (x); memcpy(y, &__t, 4); \
+# ifdef ENDIAN_32BITWORD
+# define STORE32L(x, y) { \
+ unsigned long __t = (x); memcpy(y, &__t, 4); \
}
-#define LOAD32L(x, y) memcpy(&(x), y, 4);
+# define LOAD32L(x, y) memcpy(&(x), y, 4);
-#define STORE64L(x, y) { \
-(y)[7] = (unsigned char)(((x)>>56)&255); \
-(y)[6] = (unsigned char)(((x)>>48)&255); \
-(y)[5] = (unsigned char)(((x)>>40)&255); \
-(y)[4] = (unsigned char)(((x)>>32)&255); \
-(y)[3] = (unsigned char)(((x)>>24)&255); \
-(y)[2] = (unsigned char)(((x)>>16)&255); \
-(y)[1] = (unsigned char)(((x)>>8)&255); \
-(y)[0] = (unsigned char)((x)&255); \
+# define STORE64L(x, y) { \
+ (y)[7] = (unsigned char) (((x) >> 56) & 255); \
+ (y)[6] = (unsigned char) (((x) >> 48) & 255); \
+ (y)[5] = (unsigned char) (((x) >> 40) & 255); \
+ (y)[4] = (unsigned char) (((x) >> 32) & 255); \
+ (y)[3] = (unsigned char) (((x) >> 24) & 255); \
+ (y)[2] = (unsigned char) (((x) >> 16) & 255); \
+ (y)[1] = (unsigned char) (((x) >> 8) & 255); \
+ (y)[0] = (unsigned char) ((x) & 255); \
}
-#define LOAD64L(x, y) { \
-x = (((uint64)((y)[7] & 255))<<56)|(((uint64)((y)[6] & 255))<<48)| \
-(((uint64)((y)[5] & 255))<<40)|(((uint64)((y)[4] & 255))<<32)| \
-(((uint64)((y)[3] & 255))<<24)|(((uint64)((y)[2] & 255))<<16)| \
-(((uint64)((y)[1] & 255))<<8)|(((uint64)((y)[0] & 255))); \
+# define LOAD64L(x, y) { \
+ x = (((uint64) ((y)[7] & 255)) << 56) | (((uint64) ((y)[6] & 255)) << 48) | \
+ (((uint64) ((y)[5] & 255)) << 40) | (((uint64) ((y)[4] & 255)) << 32) | \
+ (((uint64) ((y)[3] & 255)) << 24) | (((uint64) ((y)[2] & 255)) << 16) | \
+ (((uint64) ((y)[1] & 255)) << 8) | (((uint64) ((y)[0] & 255))); \
}
-#else /* 64-bit words then */
-#define STORE32L(x, y) \
-{ unsigned int __t = (x); memcpy(y, &__t, 4); }
+# else /* 64-bit words then */
+# define STORE32L(x, y) \
+ { unsigned int __t = (x); memcpy(y, &__t, 4); }
-#define LOAD32L(x, y) \
-{ memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
+# define LOAD32L(x, y) \
+ { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
-#define STORE64L(x, y) \
-{ uint64 __t = (x); memcpy(y, &__t, 8); }
+# define STORE64L(x, y) \
+ { uint64 __t = (x); memcpy(y, &__t, 8); }
-#define LOAD64L(x, y) \
-{ memcpy(&(x), y, 8); }
+# define LOAD64L(x, y) \
+ { memcpy(&(x), y, 8); }
-#endif /* ENDIAN_64BITWORD */
-#endif /* ENDIAN_LITTLE */
+# endif /* ENDIAN_64BITWORD */
+# endif /* ENDIAN_LITTLE */
/******************************************************************************/
-#ifdef ENDIAN_BIG
-#define STORE32L(x, y) { \
-(y)[3] = (unsigned char)(((x)>>24)&255); \
-(y)[2] = (unsigned char)(((x)>>16)&255); \
-(y)[1] = (unsigned char)(((x)>>8)&255); \
-(y)[0] = (unsigned char)((x)&255); \
+# ifdef ENDIAN_BIG
+# define STORE32L(x, y) { \
+ (y)[3] = (unsigned char) (((x) >> 24) & 255); \
+ (y)[2] = (unsigned char) (((x) >> 16) & 255); \
+ (y)[1] = (unsigned char) (((x) >> 8) & 255); \
+ (y)[0] = (unsigned char) ((x) & 255); \
}
-#define LOAD32L(x, y) { \
-x = ((unsigned long)((y)[3] & 255)<<24) | \
-((unsigned long)((y)[2] & 255)<<16) | \
-((unsigned long)((y)[1] & 255)<<8) | \
-((unsigned long)((y)[0] & 255)); \
+# define LOAD32L(x, y) { \
+ x = ((unsigned long) ((y)[3] & 255) << 24) | \
+ ((unsigned long) ((y)[2] & 255) << 16) | \
+ ((unsigned long) ((y)[1] & 255) << 8) | \
+ ((unsigned long) ((y)[0] & 255)); \
}
-#define STORE64L(x, y) { \
-(y)[7] = (unsigned char)(((x)>>56)&255); \
-(y)[6] = (unsigned char)(((x)>>48)&255); \
-(y)[5] = (unsigned char)(((x)>>40)&255); \
-(y)[4] = (unsigned char)(((x)>>32)&255); \
-(y)[3] = (unsigned char)(((x)>>24)&255); \
-(y)[2] = (unsigned char)(((x)>>16)&255); \
-(y)[1] = (unsigned char)(((x)>>8)&255); \
-(y)[0] = (unsigned char)((x)&255); \
+# define STORE64L(x, y) { \
+ (y)[7] = (unsigned char) (((x) >> 56) & 255); \
+ (y)[6] = (unsigned char) (((x) >> 48) & 255); \
+ (y)[5] = (unsigned char) (((x) >> 40) & 255); \
+ (y)[4] = (unsigned char) (((x) >> 32) & 255); \
+ (y)[3] = (unsigned char) (((x) >> 24) & 255); \
+ (y)[2] = (unsigned char) (((x) >> 16) & 255); \
+ (y)[1] = (unsigned char) (((x) >> 8) & 255); \
+ (y)[0] = (unsigned char) ((x) & 255); \
}
-#define LOAD64L(x, y) { \
-x = (((uint64)((y)[7] & 255))<<56)|(((uint64)((y)[6] & 255))<<48) | \
-(((uint64)((y)[5] & 255))<<40)|(((uint64)((y)[4] & 255))<<32) | \
-(((uint64)((y)[3] & 255))<<24)|(((uint64)((y)[2] & 255))<<16) | \
-(((uint64)((y)[1] & 255))<<8)|(((uint64)((y)[0] & 255))); \
+# define LOAD64L(x, y) { \
+ x = (((uint64) ((y)[7] & 255)) << 56) | (((uint64) ((y)[6] & 255)) << 48) | \
+ (((uint64) ((y)[5] & 255)) << 40) | (((uint64) ((y)[4] & 255)) << 32) | \
+ (((uint64) ((y)[3] & 255)) << 24) | (((uint64) ((y)[2] & 255)) << 16) | \
+ (((uint64) ((y)[1] & 255)) << 8) | (((uint64) ((y)[0] & 255))); \
}
/******************************************************************************/
-#ifdef ENDIAN_32BITWORD
-#define STORE32H(x, y) \
-{ unsigned int __t = (x); memcpy(y, &__t, 4); }
+# ifdef ENDIAN_32BITWORD
+# define STORE32H(x, y) \
+ { unsigned int __t = (x); memcpy(y, &__t, 4); }
-#define LOAD32H(x, y) memcpy(&(x), y, 4);
+# define LOAD32H(x, y) memcpy(&(x), y, 4);
-#define STORE64H(x, y) { \
-(y)[0] = (unsigned char)(((x)>>56)&255); \
-(y)[1] = (unsigned char)(((x)>>48)&255); \
-(y)[2] = (unsigned char)(((x)>>40)&255); \
-(y)[3] = (unsigned char)(((x)>>32)&255); \
-(y)[4] = (unsigned char)(((x)>>24)&255); \
-(y)[5] = (unsigned char)(((x)>>16)&255); \
-(y)[6] = (unsigned char)(((x)>>8)&255); \
-(y)[7] = (unsigned char)((x)&255); \
+# define STORE64H(x, y) { \
+ (y)[0] = (unsigned char) (((x) >> 56) & 255); \
+ (y)[1] = (unsigned char) (((x) >> 48) & 255); \
+ (y)[2] = (unsigned char) (((x) >> 40) & 255); \
+ (y)[3] = (unsigned char) (((x) >> 32) & 255); \
+ (y)[4] = (unsigned char) (((x) >> 24) & 255); \
+ (y)[5] = (unsigned char) (((x) >> 16) & 255); \
+ (y)[6] = (unsigned char) (((x) >> 8) & 255); \
+ (y)[7] = (unsigned char) ((x) & 255); \
}
-#define LOAD64H(x, y) { \
-x = (((uint64)((y)[0] & 255))<<56)|(((uint64)((y)[1] & 255))<<48)| \
-(((uint64)((y)[2] & 255))<<40)|(((uint64)((y)[3] & 255))<<32)| \
-(((uint64)((y)[4] & 255))<<24)|(((uint64)((y)[5] & 255))<<16)| \
-(((uint64)((y)[6] & 255))<<8)| (((uint64)((y)[7] & 255))); \
+# define LOAD64H(x, y) { \
+ x = (((uint64) ((y)[0] & 255)) << 56) | (((uint64) ((y)[1] & 255)) << 48) | \
+ (((uint64) ((y)[2] & 255)) << 40) | (((uint64) ((y)[3] & 255)) << 32) | \
+ (((uint64) ((y)[4] & 255)) << 24) | (((uint64) ((y)[5] & 255)) << 16) | \
+ (((uint64) ((y)[6] & 255)) << 8) | (((uint64) ((y)[7] & 255))); \
}
/******************************************************************************/
-#else /* 64-bit words then */
+# else /* 64-bit words then */
-#define STORE32H(x, y) \
-{ unsigned int __t = (x); memcpy(y, &__t, 4); }
+# define STORE32H(x, y) \
+ { unsigned int __t = (x); memcpy(y, &__t, 4); }
-#define LOAD32H(x, y) \
-{ memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
+# define LOAD32H(x, y) \
+ { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
-#define STORE64H(x, y) \
-{ uint64 __t = (x); memcpy(y, &__t, 8); }
+# define STORE64H(x, y) \
+ { uint64 __t = (x); memcpy(y, &__t, 8); }
-#define LOAD64H(x, y) \
-{ memcpy(&(x), y, 8); }
+# define LOAD64H(x, y) \
+ { memcpy(&(x), y, 8); }
-#endif /* ENDIAN_64BITWORD */
-#endif /* ENDIAN_BIG */
+# endif /* ENDIAN_64BITWORD */
+# endif /* ENDIAN_BIG */
/******************************************************************************/
-#ifdef HAVE_NATIVE_INT64
-#define ROL64c(x, y) \
-( (((x)<<((uint64)(y)&63)) | \
-(((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((uint64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
+# ifdef HAVE_NATIVE_INT64
+# define ROL64c(x, y) \
+ ( (((x) << ((uint64) (y) & 63)) | \
+ (((x) & CONST64(0xFFFFFFFFFFFFFFFF)) >> ((uint64) 64 - ((y) & 63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
-#define ROR64c(x, y) \
-( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((uint64)(y)&CONST64(63))) | \
-((x)<<((uint64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
-#endif /* HAVE_NATIVE_INT64 */
+# define ROR64c(x, y) \
+ ( ((((x) & CONST64(0xFFFFFFFFFFFFFFFF)) >> ((uint64) (y) & CONST64(63))) | \
+ ((x) << ((uint64) (64 - ((y) & CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
+# endif /* HAVE_NATIVE_INT64 */
/******************************************************************************/
/*
- Return the length of padding bytes required for a record of 'LEN' bytes
- The name Pwr2 indicates that calculations will work with 'BLOCKSIZE'
- that are powers of 2.
- Because of the trailing pad length byte, a length that is a multiple
- of the pad bytes
-*/
-#define psPadLenPwr2(LEN, BLOCKSIZE) \
- BLOCKSIZE <= 1 ? (unsigned char)0 : \
- (unsigned char)(BLOCKSIZE - ((LEN) & (BLOCKSIZE - 1)))
+ Return the length of padding bytes required for a record of 'LEN' bytes
+ The name Pwr2 indicates that calculations will work with 'BLOCKSIZE'
+ that are powers of 2.
+ Because of the trailing pad length byte, a length that is a multiple
+ of the pad bytes
+ */
+# define psPadLenPwr2(LEN, BLOCKSIZE) \
+ BLOCKSIZE <= 1 ? (unsigned char) 0 : \
+ (unsigned char) (BLOCKSIZE - ((LEN) &(BLOCKSIZE - 1)))
-#ifdef USE_CRL
+# ifdef USE_CRL
extern int32_t psCrlOpen();
extern void psCrlClose();
-#endif
+# endif
#endif /* _h_PS_CRYPTOLIB */
diff --git a/crypto/digest/digest.h b/crypto/digest/digest.h
index f73a3d1..726bf73 100644
--- a/crypto/digest/digest.h
+++ b/crypto/digest/digest.h
@@ -1,123 +1,127 @@
/**
- * @file digest.h
- * @version $Format:%h%d$
+ * @file digest.h
+ * @version $Format:%h%d$
*
- * Header for internal symmetric key cryptography support.
+ * Header for internal symmetric key cryptography support.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_CRYPTO_DIGEST
-#define _h_CRYPTO_DIGEST
+# define _h_CRYPTO_DIGEST
/******************************************************************************/
-#define SHA1_HASH_SIZE 20
-#define SHA224_HASH_SIZE 28
-#define SHA256_HASH_SIZE 32
-#define SHA384_HASH_SIZE 48
-#define SHA512_HASH_SIZE 64
-#define MD5_HASH_SIZE 16
+# define SHA1_HASH_SIZE 20
+# define SHA224_HASH_SIZE 28
+# define SHA256_HASH_SIZE 32
+# define SHA384_HASH_SIZE 48
+# define SHA512_HASH_SIZE 64
+# define MD2_HASH_SIZE 16
+# define MD5_HASH_SIZE 16
-#define SHA1_HASHLEN 20
-#define SHA224_HASHLEN 28
-#define SHA256_HASHLEN 32
-#define SHA384_HASHLEN 48
-#define SHA512_HASHLEN 64
-#define MD2_HASHLEN 16
-#define MD5_HASHLEN 16
-#define MD5SHA1_HASHLEN (MD5_HASHLEN + SHA1_HASHLEN)
+# define SHA1_HASHLEN 20
+# define SHA224_HASHLEN 28
+# define SHA256_HASHLEN 32
+# define SHA384_HASHLEN 48
+# define SHA512_HASHLEN 64
+# define MD2_HASHLEN 16
+# define MD5_HASHLEN 16
+# define MD5SHA1_HASHLEN (MD5_HASHLEN + SHA1_HASHLEN)
-#if defined(USE_SHA512)
- #define MAX_HASH_SIZE SHA512_HASHLEN
-#elif defined(USE_SHA384)
- #define MAX_HASH_SIZE SHA384_HASHLEN
-#elif defined(USE_SHA256)
- #define MAX_HASH_SIZE SHA256_HASHLEN
-#else
- #define MAX_HASH_SIZE SHA1_HASHLEN
-#endif
+# if defined(USE_SHA512)
+# define MAX_HASH_SIZE SHA512_HASHLEN
+# elif defined(USE_SHA384)
+# define MAX_HASH_SIZE SHA384_HASHLEN
+# elif defined(USE_SHA256)
+# define MAX_HASH_SIZE SHA256_HASHLEN
+# else
+# define MAX_HASH_SIZE SHA1_HASHLEN
+# endif
-#define MAX_HASHLEN MAX_HASH_SIZE
+# define MAX_HASHLEN MAX_HASH_SIZE
-#ifdef USE_LIBSODIUM_CRYPTO
-#include "digest_libsodium.h"
-#endif
-#include "digest_matrix.h"
-#ifdef USE_OPENSSL_CRYPTO
-#include "digest_openssl.h"
-#endif
+# ifdef USE_LIBSODIUM_CRYPTO
+# include "digest_libsodium.h"
+# endif
+# include "digest_matrix.h"
+# ifdef USE_OPENSSL_CRYPTO
+# include "digest_openssl.h"
+# endif
/******************************************************************************/
-typedef union {
-#ifdef USE_SHA1
- psSha1_t sha1;
-#endif
-#ifdef USE_MD5SHA1
- psMd5Sha1_t md5sha1;
-#endif
-#ifdef USE_SHA256
- psSha256_t sha256;
-#endif
-#ifdef USE_SHA384
- psSha384_t sha384;
-#endif
-#ifdef USE_SHA512
- psSha512_t sha512;
-#endif
-#ifdef USE_MD5
- psMd5_t md5;
-#endif
-#ifdef USE_MD2
- psMd2_t md2;
-#endif
-#ifdef USE_MD4
- psMd4_t md4;
-#endif
+typedef union
+{
+# ifdef USE_SHA1
+ psSha1_t sha1;
+# endif
+# ifdef USE_MD5SHA1
+ psMd5Sha1_t md5sha1;
+# endif
+# ifdef USE_SHA256
+ psSha256_t sha256;
+# endif
+# ifdef USE_SHA384
+ psSha384_t sha384;
+# endif
+# ifdef USE_SHA512
+ psSha512_t sha512;
+# endif
+# ifdef USE_MD5
+ psMd5_t md5;
+# endif
+# ifdef USE_MD2
+ psMd2_t md2;
+# endif
+# ifdef USE_MD4
+ psMd4_t md4;
+# endif
} psDigestContext_t;
-typedef struct {
- union {
-#ifdef USE_HMAC_MD5
- psHmacMd5_t md5;
-#endif
-#ifdef USE_HMAC_SHA1
- psHmacSha1_t sha1;
-#endif
-#ifdef USE_HMAC_SHA256
- psHmacSha256_t sha256;
-#endif
-#ifdef USE_HMAC_SHA384
- psHmacSha384_t sha384;
-#endif
- } u;
- uint8_t type; /* psCipherType_e */
+typedef struct
+{
+ union
+ {
+# ifdef USE_HMAC_MD5
+ psHmacMd5_t md5;
+# endif
+# ifdef USE_HMAC_SHA1
+ psHmacSha1_t sha1;
+# endif
+# ifdef USE_HMAC_SHA256
+ psHmacSha256_t sha256;
+# endif
+# ifdef USE_HMAC_SHA384
+ psHmacSha384_t sha384;
+# endif
+ } u;
+ uint8_t type; /* psCipherType_e */
} psHmac_t;
#endif /* _h_CRYPTO_DIGEST */
diff --git a/crypto/digest/digest_libsodium.c b/crypto/digest/digest_libsodium.c
index a29b10b..c8bbbd0 100644
--- a/crypto/digest/digest_libsodium.c
+++ b/crypto/digest/digest_libsodium.c
@@ -1,193 +1,212 @@
/**
- * @file digest_libsodium.c
- * @version $Format:%h%d$
+ * @file digest_libsodium.c
+ * @version $Format:%h%d$
*
- * Digest compatibility layer between MatrixSSL and libsodium.
+ * Digest compatibility layer between MatrixSSL and libsodium.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
/******************************************************************************/
#ifdef USE_LIBSODIUM_SHA256
int32_t psSha256Init(psSha256_t *sha256)
{
- if (crypto_hash_sha256_init(sha256) != 0) {
- return PS_FAIL;
- }
- return PS_SUCCESS;
+ if (crypto_hash_sha256_init(sha256) != 0)
+ {
+ return PS_FAIL;
+ }
+ return PS_SUCCESS;
}
void psSha256Update(psSha256_t *sha256, const unsigned char *buf, uint32_t len)
{
- if (crypto_hash_sha256_update(sha256, buf, len) != 0) {
- memset(sha256, 0x0, sizeof(psSha256_t));
- }
+ if (crypto_hash_sha256_update(sha256, buf, len) != 0)
+ {
+ memset(sha256, 0x0, sizeof(psSha256_t));
+ }
}
void psSha256Final(psSha256_t *sha256, unsigned char hash[SHA256_HASHLEN])
{
- if (crypto_hash_sha256_final(sha256,hash) != 0) {
- memset(hash, 0x0, SHA256_HASHLEN);
- memset(sha256, 0x0, sizeof(psSha256_t));
- }
+ if (crypto_hash_sha256_final(sha256, hash) != 0)
+ {
+ memset(hash, 0x0, SHA256_HASHLEN);
+ memset(sha256, 0x0, sizeof(psSha256_t));
+ }
}
#endif /* USE_LIBSODIUM_SHA256 */
#ifdef USE_LIBSODIUM_SHA384
/**
- libsodium doesn't explicitly support sha384, but since 384 uses the
- same compression as 512, we can use it here.
- @note This uses an internal field of crypto_hash_sha512_state, which
- may change with different versions of libsodium.
-*/
+ libsodium doesn't explicitly support sha384, but since 384 uses the
+ same compression as 512, we can use it here.
+ @note This uses an internal field of crypto_hash_sha512_state, which
+ may change with different versions of libsodium.
+ */
int32_t psSha384Init(psSha384_t *sha384)
{
- static const uint64_t sha384_initstate[8] = {
- 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL,
- 0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL,
- 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
- 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL
+ static const uint64_t sha384_initstate[8] = {
+ 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL,
+ 0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL,
+ 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
+ 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL
};
- /* Sanity check libsodium hash structure for what we expect */
- if (sizeof(sha384->state) != 64) {
- psAssert(sizeof(sha384->state) == 64);
- return PS_FAIL;
- }
- if (crypto_hash_sha512_init(sha384) != 0) {
- return PS_FAIL;
- }
- /* 384 uses a different initial state than 512 */
- memcpy(sha384->state, sha384_initstate, sizeof sha384_initstate);
- return PS_SUCCESS;
+
+ /* Sanity check libsodium hash structure for what we expect */
+ if (sizeof(sha384->state) != 64)
+ {
+ psAssert(sizeof(sha384->state) == 64);
+ return PS_FAIL;
+ }
+ if (crypto_hash_sha512_init(sha384) != 0)
+ {
+ return PS_FAIL;
+ }
+ /* 384 uses a different initial state than 512 */
+ memcpy(sha384->state, sha384_initstate, sizeof sha384_initstate);
+ return PS_SUCCESS;
}
void psSha384Update(psSha384_t *sha384, const unsigned char *buf, uint32_t len)
{
- if (crypto_hash_sha512_update(sha384, buf, len) != 0) {
- memset(sha384, 0x0, sizeof(psSha384_t));
- }
+ if (crypto_hash_sha512_update(sha384, buf, len) != 0)
+ {
+ memset(sha384, 0x0, sizeof(psSha384_t));
+ }
}
void psSha384Final(psSha384_t *sha384, unsigned char hash[SHA384_HASHLEN])
{
- unsigned char buf[SHA512_HASHLEN];
- if (crypto_hash_sha512_final(sha384, buf) != 0) {
- memset(buf, 0x0, SHA512_HASHLEN);
- memset(sha384, 0x0, sizeof(psSha384_t));
- }
- memcpy(hash, buf, SHA384_HASHLEN);
- memzero_s(buf, SHA512_HASHLEN);
+ unsigned char buf[SHA512_HASHLEN];
+
+ if (crypto_hash_sha512_final(sha384, buf) != 0)
+ {
+ memset(buf, 0x0, SHA512_HASHLEN);
+ memset(sha384, 0x0, sizeof(psSha384_t));
+ }
+ memcpy(hash, buf, SHA384_HASHLEN);
+ memzero_s(buf, SHA512_HASHLEN);
}
#endif /* USE_LIBSODIUM_SHA384 */
#ifdef USE_LIBSODIUM_SHA512
int32_t psSha512Init(psSha512_t *sha512)
{
- if (crypto_hash_sha512_init(sha512) != 0) {
- return PS_FAIL;
- }
- return PS_SUCCESS;
+ if (crypto_hash_sha512_init(sha512) != 0)
+ {
+ return PS_FAIL;
+ }
+ return PS_SUCCESS;
}
void psSha512Update(psSha512_t *sha512, const unsigned char *buf, uint32_t len)
{
- if (crypto_hash_sha512_update(sha512, buf, len) != 0) {
- memset(sha512, 0x0, sizeof(psSha512_t));
- }
+ if (crypto_hash_sha512_update(sha512, buf, len) != 0)
+ {
+ memset(sha512, 0x0, sizeof(psSha512_t));
+ }
}
void psSha512Final(psSha512_t *sha512, unsigned char hash[SHA512_HASHLEN])
{
- if (crypto_hash_sha512_final(sha512,hash) != 0) {
- memset(hash, 0x0, SHA512_HASHLEN);
- memset(sha512, 0x0, sizeof(psSha512_t));
- }
+ if (crypto_hash_sha512_final(sha512, hash) != 0)
+ {
+ memset(hash, 0x0, SHA512_HASHLEN);
+ memset(sha512, 0x0, sizeof(psSha512_t));
+ }
}
#endif /* USE_LIBSODIUM_SHA512 */
/******************************************************************************/
#ifdef USE_LIBSODIUM_HMAC_SHA256
-int32_t psHmacSha256(const unsigned char *key, uint16_t keyLen,
- const unsigned char *buf, uint32_t len,
- unsigned char hash[SHA256_HASHLEN], unsigned char *hmacKey,
- uint16_t *hmacKeyLen)
+int32_t psHmacSha256(const unsigned char *key, psSize_t keyLen,
+ const unsigned char *buf, uint32_t len,
+ unsigned char hash[SHA256_HASHLEN], unsigned char *hmacKey,
+ psSize_t *hmacKeyLen)
{
- psHmacSha256_t sha256;
-
- if (crypto_auth_hmacsha256_init(&sha256,key,keyLen) != 0) {
- psAssert(0);
- return PS_FAIL;
- }
- crypto_auth_hmacsha256_update(&sha256,buf,len);
- crypto_auth_hmacsha256_final(&sha256,hash);
+ psHmacSha256_t sha256;
- if (keyLen > 64) {
- crypto_hash_sha256(hmacKey, key, keyLen);
- *hmacKeyLen = SHA256_HASHLEN;
- } else {
- hmacKey = (unsigned char*)key;
- *hmacKeyLen = keyLen;
- }
+ if (crypto_auth_hmacsha256_init(&sha256, key, keyLen) != 0)
+ {
+ psAssert(0);
+ return PS_FAIL;
+ }
+ crypto_auth_hmacsha256_update(&sha256, buf, len);
+ crypto_auth_hmacsha256_final(&sha256, hash);
- return PS_SUCCESS;
+ if (keyLen > 64)
+ {
+ crypto_hash_sha256(hmacKey, key, keyLen);
+ *hmacKeyLen = SHA256_HASHLEN;
+ }
+ else
+ {
+ hmacKey = (unsigned char *) key;
+ *hmacKeyLen = keyLen;
+ }
+
+ return PS_SUCCESS;
}
int32_t psHmacSha256Init(psHmacSha256_t *ctx,
- const unsigned char *key, uint16_t keyLen)
+ const unsigned char *key, psSize_t keyLen)
{
- if (crypto_auth_hmacsha256_init(ctx,key,keyLen) != 0) {
- memset(ctx, 0x0, sizeof(psHmacSha256_t));
- psAssert(0);
- return PS_FAIL;
- }
- return PS_SUCCESS;
+ if (crypto_auth_hmacsha256_init(ctx, key, keyLen) != 0)
+ {
+ memset(ctx, 0x0, sizeof(psHmacSha256_t));
+ psAssert(0);
+ return PS_FAIL;
+ }
+ return PS_SUCCESS;
}
void psHmacSha256Update(psHmacSha256_t *ctx,
- const unsigned char *buf, uint32_t len)
+ const unsigned char *buf, uint32_t len)
{
- if (crypto_auth_hmacsha256_update(ctx,buf,len) != 0) {
- memset(ctx, 0x0, sizeof(psHmacSha256_t));
- }
+ if (crypto_auth_hmacsha256_update(ctx, buf, len) != 0)
+ {
+ memset(ctx, 0x0, sizeof(psHmacSha256_t));
+ }
}
void psHmacSha256Final(psHmacSha256_t *ctx,
- unsigned char hash[SHA256_HASHLEN])
+ unsigned char hash[SHA256_HASHLEN])
{
- if (crypto_auth_hmacsha256_final(ctx, hash) != 0) {
- psAssert(0);
- }
- memset(ctx, 0x0, sizeof(psHmacSha256_t));
+ if (crypto_auth_hmacsha256_final(ctx, hash) != 0)
+ {
+ psAssert(0);
+ }
+ memset(ctx, 0x0, sizeof(psHmacSha256_t));
}
#endif /* USE_LIBSODIUM_HMAC_SHA256 */
diff --git a/crypto/digest/digest_libsodium.h b/crypto/digest/digest_libsodium.h
index deb23b9..723aaf4 100644
--- a/crypto/digest/digest_libsodium.h
+++ b/crypto/digest/digest_libsodium.h
@@ -1,63 +1,63 @@
/**
- * @file digest_sodium.h
- * @version $Format:%h%d$
+ * @file digest_sodium.h
+ * @version $Format:%h%d$
*
- * Header for libsodium crypto Layer.
+ * Header for libsodium crypto Layer.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_LIBSODIUM_DIGEST
-#define _h_LIBSODIUM_DIGEST
+# define _h_LIBSODIUM_DIGEST
/******************************************************************************/
-#ifdef USE_LIBSODIUM_SHA256
-#include "sodium/crypto_hash_sha256.h"
-typedef crypto_hash_sha256_state psSha256_t;
-#endif
+# ifdef USE_LIBSODIUM_SHA256
+# include "sodium/crypto_hash_sha256.h"
+typedef crypto_hash_sha256_state psSha256_t;
+# endif
-#ifdef USE_LIBSODIUM_SHA512
-#include "sodium/crypto_hash_sha512.h"
-#ifdef USE_LIBSODIUM_SHA384
-typedef crypto_hash_sha512_state psSha384_t;
-#endif
-typedef crypto_hash_sha512_state psSha512_t;
-#endif
+# ifdef USE_LIBSODIUM_SHA512
+# include "sodium/crypto_hash_sha512.h"
+# ifdef USE_LIBSODIUM_SHA384
+typedef crypto_hash_sha512_state psSha384_t;
+# endif
+typedef crypto_hash_sha512_state psSha512_t;
+# endif
/******************************************************************************/
-#ifdef USE_LIBSODIUM_HMAC_SHA256
-#include "sodium/crypto_auth_hmacsha256.h"
-typedef crypto_auth_hmacsha256_state psHmacSha256_t;
-#endif
+# ifdef USE_LIBSODIUM_HMAC_SHA256
+# include "sodium/crypto_auth_hmacsha256.h"
+typedef crypto_auth_hmacsha256_state psHmacSha256_t;
+# endif
/******************************************************************************/
diff --git a/crypto/digest/digest_matrix.h b/crypto/digest/digest_matrix.h
index 82fcb61..1c48554 100644
--- a/crypto/digest/digest_matrix.h
+++ b/crypto/digest/digest_matrix.h
@@ -1,153 +1,164 @@
/**
- * @file digest_matrix.h
- * @version $Format:%h%d$
+ * @file digest_matrix.h
+ * @version $Format:%h%d$
*
- * Header for internal digest support.
+ * Header for internal digest support.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_MATRIX_DIGEST
-#define _h_MATRIX_DIGEST
+# define _h_MATRIX_DIGEST
/******************************************************************************/
-#ifdef USE_MATRIX_SHA1
-typedef struct {
-#ifdef HAVE_NATIVE_INT64
- uint64 length;
-#else
- uint32 lengthHi;
- uint32 lengthLo;
-#endif /* HAVE_NATIVE_INT64 */
- uint32 state[5], curlen;
- unsigned char buf[64];
+# ifdef USE_MATRIX_SHA1
+typedef struct
+{
+# ifdef HAVE_NATIVE_INT64
+ uint64 length;
+# else
+ uint32 lengthHi;
+ uint32 lengthLo;
+# endif /* HAVE_NATIVE_INT64 */
+ uint32 state[5], curlen;
+ unsigned char buf[64];
} psSha1_t;
-#endif
+# endif
-#ifdef USE_MATRIX_SHA256
-typedef struct {
-#ifdef HAVE_NATIVE_INT64
- uint64 length;
-#else
- uint32 lengthHi;
- uint32 lengthLo;
-#endif /* HAVE_NATIVE_INT64 */
- uint32 state[8], curlen;
- unsigned char buf[64];
+# ifdef USE_MATRIX_SHA256
+typedef struct
+{
+# ifdef HAVE_NATIVE_INT64
+ uint64 length;
+# else
+ uint32 lengthHi;
+ uint32 lengthLo;
+# endif /* HAVE_NATIVE_INT64 */
+ uint32 state[8], curlen;
+ unsigned char buf[64];
} psSha256_t;
-#endif
+# endif
-#ifdef USE_MATRIX_SHA512
-typedef struct {
- uint64 length, state[8];
- unsigned long curlen;
- unsigned char buf[128];
+# ifdef USE_MATRIX_SHA512
+typedef struct
+{
+ uint64 length, state[8];
+ unsigned long curlen;
+ unsigned char buf[128];
} psSha512_t;
-#endif
+# endif
-#ifdef USE_MATRIX_SHA384
-#ifndef USE_MATRIX_SHA512
-#error "USE_MATRIX_SHA512 must be enabled if USE_MATRIX_SHA384 is enabled"
-#endif
+# ifdef USE_MATRIX_SHA384
+# ifndef USE_MATRIX_SHA512
+# error "USE_MATRIX_SHA512 must be enabled if USE_MATRIX_SHA384 is enabled"
+# endif
typedef psSha512_t psSha384_t;
-#endif
+# endif
-#ifdef USE_MATRIX_MD5
-typedef struct {
-#ifdef HAVE_NATIVE_INT64
- uint64 length;
-#else
- uint32 lengthHi;
- uint32 lengthLo;
-#endif /* HAVE_NATIVE_INT64 */
- uint32 state[4], curlen;
- unsigned char buf[64];
+# ifdef USE_MATRIX_MD5
+typedef struct
+{
+# ifdef HAVE_NATIVE_INT64
+ uint64 length;
+# else
+ uint32 lengthHi;
+ uint32 lengthLo;
+# endif /* HAVE_NATIVE_INT64 */
+ uint32 state[4], curlen;
+ unsigned char buf[64];
} psMd5_t;
-#endif
+# endif
-#ifdef USE_MATRIX_MD5SHA1
-typedef struct {
- psMd5_t md5;
- psSha1_t sha1;
+# ifdef USE_MATRIX_MD5SHA1
+typedef struct
+{
+ psMd5_t md5;
+ psSha1_t sha1;
} psMd5Sha1_t;
-#endif
+# endif
-#ifdef USE_MATRIX_MD4
-typedef struct {
-#ifdef HAVE_NATIVE_INT64
- uint64 length;
-#else
- uint32 lengthHi;
- uint32 lengthLo;
-#endif /* HAVE_NATIVE_INT64 */
- uint32 state[4], curlen;
- unsigned char buf[64];
+# ifdef USE_MATRIX_MD4
+typedef struct
+{
+# ifdef HAVE_NATIVE_INT64
+ uint64 length;
+# else
+ uint32 lengthHi;
+ uint32 lengthLo;
+# endif /* HAVE_NATIVE_INT64 */
+ uint32 state[4], curlen;
+ unsigned char buf[64];
} psMd4_t;
-#endif
+# endif
-#ifdef USE_MATRIX_MD2
-typedef struct {
- unsigned char chksum[16], X[48], buf[16];
- uint32 curlen;
+# ifdef USE_MATRIX_MD2
+typedef struct
+{
+ unsigned char chksum[16], X[48], buf[16];
+ uint32 curlen;
} psMd2_t;
-#endif
+# endif
/******************************************************************************/
-#ifdef USE_MATRIX_HMAC_MD5
-typedef struct {
- unsigned char pad[64];
- psMd5_t md5;
+# ifdef USE_MATRIX_HMAC_MD5
+typedef struct
+{
+ unsigned char pad[64];
+ psMd5_t md5;
} psHmacMd5_t;
-#endif
+# endif
-#ifdef USE_MATRIX_HMAC_SHA1
-typedef struct {
- unsigned char pad[64];
- psSha1_t sha1;
+# ifdef USE_MATRIX_HMAC_SHA1
+typedef struct
+{
+ unsigned char pad[64];
+ psSha1_t sha1;
} psHmacSha1_t;
-#endif
+# endif
-#ifdef USE_MATRIX_HMAC_SHA256
-typedef struct {
- unsigned char pad[64];
- psSha256_t sha256;
+# ifdef USE_MATRIX_HMAC_SHA256
+typedef struct
+{
+ unsigned char pad[64];
+ psSha256_t sha256;
} psHmacSha256_t;
-#endif
+# endif
-#ifdef USE_MATRIX_HMAC_SHA384
-typedef struct {
- unsigned char pad[128];
- psSha384_t sha384;
+# ifdef USE_MATRIX_HMAC_SHA384
+typedef struct
+{
+ unsigned char pad[128];
+ psSha384_t sha384;
} psHmacSha384_t;
-#endif
+# endif
#endif /* _h_MATRIX_DIGEST */
diff --git a/crypto/digest/digest_openssl.c b/crypto/digest/digest_openssl.c
index 6459217..8bf110f 100644
--- a/crypto/digest/digest_openssl.c
+++ b/crypto/digest/digest_openssl.c
@@ -1,92 +1,98 @@
/**
- * @file digest_openssl.c
- * @version $Format:%h%d$
+ * @file digest_openssl.c
+ * @version $Format:%h%d$
*
- * Digest compatibility layer between MatrixSSL and OpenSSL.
+ * Digest compatibility layer between MatrixSSL and OpenSSL.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
/******************************************************************************/
#ifdef USE_OPENSSL_HMAC_MD5
-int32_t psHmacMd5(const unsigned char *key, uint16_t keyLen,
- const unsigned char *buf, uint32_t len,
- unsigned char hash[MD5_HASHLEN], unsigned char *hmacKey,
- uint16_t *hmacKeyLen)
+int32_t psHmacMd5(const unsigned char *key, psSize_t keyLen,
+ const unsigned char *buf, uint32_t len,
+ unsigned char hash[MD5_HASHLEN], unsigned char *hmacKey,
+ psSize_t *hmacKeyLen)
{
- psMd5_t md;
- /*
- Support for keys larger than 64 bytes. In this case, we take the
- hash of the key itself and use that instead. Inform the caller by
- updating the hmacKey and hmacKeyLen outputs
- */
- if (keyLen > 64) {
- psMd5Init(&md);
- psMd5Update(&md, key, keyLen);
- psMd5Final(&md, hash);
- *hmacKeyLen = MD5_HASHLEN;
- memcpy(hmacKey, hash, *hmacKeyLen);
- } else {
- hmacKey = (unsigned char*)key;
- *hmacKeyLen = keyLen;
- }
- if (HMAC(EVP_md5(), hmacKey, *hmacKeyLen, buf, len, hash, NULL) != NULL) {
- return PS_SUCCESS;
- }
- return PS_FAIL;
+ psMd5_t md;
+
+ /*
+ Support for keys larger than 64 bytes. In this case, we take the
+ hash of the key itself and use that instead. Inform the caller by
+ updating the hmacKey and hmacKeyLen outputs
+ */
+ if (keyLen > 64)
+ {
+ psMd5Init(&md);
+ psMd5Update(&md, key, keyLen);
+ psMd5Final(&md, hash);
+ *hmacKeyLen = MD5_HASHLEN;
+ memcpy(hmacKey, hash, *hmacKeyLen);
+ }
+ else
+ {
+ hmacKey = (unsigned char *) key;
+ *hmacKeyLen = keyLen;
+ }
+ if (HMAC(EVP_md5(), hmacKey, *hmacKeyLen, buf, len, hash, NULL) != NULL)
+ {
+ return PS_SUCCESS;
+ }
+ return PS_FAIL;
}
int32_t psHmacMd5Init(psHmacMd5_t *ctx, const unsigned char *key,
- uint16_t keyLen)
+ psSize_t keyLen)
{
- HMAC_CTX_init(ctx);
- if (HMAC_Init_ex(ctx, key, keyLen, EVP_md5(), NULL) == 1) {
- return PS_SUCCESS;
- }
- HMAC_CTX_cleanup(ctx);
- psAssert(0);
- return PS_FAIL;
+ HMAC_CTX_init(ctx);
+ if (HMAC_Init_ex(ctx, key, keyLen, EVP_md5(), NULL) == 1)
+ {
+ return PS_SUCCESS;
+ }
+ HMAC_CTX_cleanup(ctx);
+ psAssert(0);
+ return PS_FAIL;
}
void psHmacMd5Update(psHmacMd5_t *ctx, const unsigned char *buf,
- uint32_t len)
+ uint32_t len)
{
- HMAC_Update(ctx, buf, len);
+ HMAC_Update(ctx, buf, len);
}
void psHmacMd5Final(psHmacMd5_t *ctx, unsigned char hash[MD5_HASHLEN])
{
- HMAC_Final(ctx, hash, NULL);
- HMAC_CTX_cleanup(ctx);
+ HMAC_Final(ctx, hash, NULL);
+ HMAC_CTX_cleanup(ctx);
}
#endif /* USE_OPENSSL_HMAC_MD5 */
@@ -95,167 +101,187 @@ void psHmacMd5Final(psHmacMd5_t *ctx, unsigned char hash[MD5_HASHLEN])
#ifdef USE_OPENSSL_SHA1
-int32_t psHmacSha1(const unsigned char *key, uint16_t keyLen,
- const unsigned char *buf, uint32_t len,
- unsigned char hash[SHA1_HASHLEN], unsigned char *hmacKey,
- uint16_t *hmacKeyLen)
+int32_t psHmacSha1(const unsigned char *key, psSize_t keyLen,
+ const unsigned char *buf, uint32_t len,
+ unsigned char hash[SHA1_HASHLEN], unsigned char *hmacKey,
+ psSize_t *hmacKeyLen)
{
- psSha1_t sha;
+ psSha1_t sha;
+
/*
- Support for keys larger than 64 bytes. In this case, we take the
- hash of the key itself and use that instead. Inform the caller by
- updating the hmacKey and hmacKeyLen outputs
-*/
- if (keyLen > 64) {
- psSha1Init(&sha);
- psSha1Update(&sha, key, keyLen);
- psSha1Final(&sha, hash);
- *hmacKeyLen = SHA1_HASHLEN;
- memcpy(hmacKey, hash, *hmacKeyLen);
- } else {
- hmacKey = (unsigned char*)key;
- *hmacKeyLen = keyLen;
- }
- if (HMAC(EVP_sha1(), hmacKey, *hmacKeyLen, buf, len, hash, NULL) != NULL) {
- return PS_SUCCESS;
- }
- return PS_FAIL;
+ Support for keys larger than 64 bytes. In this case, we take the
+ hash of the key itself and use that instead. Inform the caller by
+ updating the hmacKey and hmacKeyLen outputs
+ */
+ if (keyLen > 64)
+ {
+ psSha1Init(&sha);
+ psSha1Update(&sha, key, keyLen);
+ psSha1Final(&sha, hash);
+ *hmacKeyLen = SHA1_HASHLEN;
+ memcpy(hmacKey, hash, *hmacKeyLen);
+ }
+ else
+ {
+ hmacKey = (unsigned char *) key;
+ *hmacKeyLen = keyLen;
+ }
+ if (HMAC(EVP_sha1(), hmacKey, *hmacKeyLen, buf, len, hash, NULL) != NULL)
+ {
+ return PS_SUCCESS;
+ }
+ return PS_FAIL;
}
int32_t psHmacSha1Init(psHmacSha1_t *ctx, const unsigned char *key,
- uint16_t keyLen)
+ psSize_t keyLen)
{
- HMAC_CTX_init(ctx);
- if (HMAC_Init_ex(ctx, key, keyLen, EVP_sha1(), NULL) == 1) {
- return PS_SUCCESS;
- }
- HMAC_CTX_cleanup(ctx);
- return PS_FAIL;
+ HMAC_CTX_init(ctx);
+ if (HMAC_Init_ex(ctx, key, keyLen, EVP_sha1(), NULL) == 1)
+ {
+ return PS_SUCCESS;
+ }
+ HMAC_CTX_cleanup(ctx);
+ return PS_FAIL;
}
void psHmacSha1Update(psHmacSha1_t *ctx, const unsigned char *buf,
- uint32_t len)
+ uint32_t len)
{
- HMAC_Update(ctx, buf, len);
+ HMAC_Update(ctx, buf, len);
}
void psHmacSha1Final(psHmacSha1_t *ctx, unsigned char hash[SHA1_HASHLEN])
{
- HMAC_Final(ctx, hash, NULL);
- HMAC_CTX_cleanup(ctx);
+ HMAC_Final(ctx, hash, NULL);
+ HMAC_CTX_cleanup(ctx);
}
#endif /* USE_OPENSSL_HMAC_SHA1 */
/******************************************************************************/
#ifdef USE_OPENSSL_HMAC_SHA256
-int32_t psHmacSha256(const unsigned char *key, uint16_t keyLen,
- const unsigned char *buf, uint32_t len,
- unsigned char hash[SHA256_HASHLEN], unsigned char *hmacKey,
- uint16_t *hmacKeyLen)
+int32_t psHmacSha256(const unsigned char *key, psSize_t keyLen,
+ const unsigned char *buf, uint32_t len,
+ unsigned char hash[SHA256_HASHLEN], unsigned char *hmacKey,
+ psSize_t *hmacKeyLen)
{
- psSha256_t sha;
-
- if (keyLen > 64) {
- psSha256Init(&sha);
- psSha256Update(&sha, key, keyLen);
- psSha256Final(&sha, hash);
- *hmacKeyLen = SHA256_HASHLEN;
- memcpy(hmacKey, hash, *hmacKeyLen);
- } else {
- hmacKey = (unsigned char*)key;
- *hmacKeyLen = keyLen;
- }
- if (HMAC(EVP_sha256(), hmacKey, *hmacKeyLen, buf, len, hash, NULL) != NULL){
- return PS_SUCCESS;
- }
- psAssert(0);
- return PS_FAIL;
+ psSha256_t sha;
+
+ if (keyLen > 64)
+ {
+ psSha256Init(&sha);
+ psSha256Update(&sha, key, keyLen);
+ psSha256Final(&sha, hash);
+ *hmacKeyLen = SHA256_HASHLEN;
+ memcpy(hmacKey, hash, *hmacKeyLen);
+ }
+ else
+ {
+ hmacKey = (unsigned char *) key;
+ *hmacKeyLen = keyLen;
+ }
+ if (HMAC(EVP_sha256(), hmacKey, *hmacKeyLen, buf, len, hash, NULL) != NULL)
+ {
+ return PS_SUCCESS;
+ }
+ psAssert(0);
+ return PS_FAIL;
}
int32_t psHmacSha256Init(psHmacSha256_t *ctx,
- const unsigned char *key, uint16_t keyLen)
+ const unsigned char *key, psSize_t keyLen)
{
- HMAC_CTX_init(ctx);
- if (HMAC_Init_ex(ctx, key, keyLen, EVP_sha256(), NULL) == 1) {
- return PS_SUCCESS;
- }
- HMAC_CTX_cleanup(ctx);
- psAssert(0);
- return PS_FAIL;
+ HMAC_CTX_init(ctx);
+ if (HMAC_Init_ex(ctx, key, keyLen, EVP_sha256(), NULL) == 1)
+ {
+ return PS_SUCCESS;
+ }
+ HMAC_CTX_cleanup(ctx);
+ psAssert(0);
+ return PS_FAIL;
}
void psHmacSha256Update(psHmacSha256_t *ctx,
- const unsigned char *buf, uint32_t len)
+ const unsigned char *buf, uint32_t len)
{
- if (HMAC_Update(ctx, buf, len) != 1) {
- HMAC_CTX_cleanup(ctx);
- }
+ if (HMAC_Update(ctx, buf, len) != 1)
+ {
+ HMAC_CTX_cleanup(ctx);
+ }
}
void psHmacSha256Final(psHmacSha256_t *ctx,
- unsigned char hash[SHA256_HASHLEN])
+ unsigned char hash[SHA256_HASHLEN])
{
- if (HMAC_Final(ctx, hash, NULL) != 1) {
- psAssert(0);
- }
- HMAC_CTX_cleanup(ctx);
+ if (HMAC_Final(ctx, hash, NULL) != 1)
+ {
+ psAssert(0);
+ }
+ HMAC_CTX_cleanup(ctx);
}
#endif /* USE_OPENSSL_HMAC_SHA256 */
#ifdef USE_OPENSSL_HMAC_SHA384
-int32_t psHmacSha384(const unsigned char *key, uint16_t keyLen,
- const unsigned char *buf, uint32_t len,
- unsigned char hash[SHA384_HASHLEN], unsigned char *hmacKey,
- uint16_t *hmacKeyLen)
+int32_t psHmacSha384(const unsigned char *key, psSize_t keyLen,
+ const unsigned char *buf, uint32_t len,
+ unsigned char hash[SHA384_HASHLEN], unsigned char *hmacKey,
+ psSize_t *hmacKeyLen)
{
- psSha384_t sha;
-
- if (keyLen > 64) {
- psSha384Init(&sha);
- psSha384Update(&sha, key, keyLen);
- psSha384Final(&sha, hash);
- *hmacKeyLen = SHA384_HASHLEN;
- memcpy(hmacKey, hash, *hmacKeyLen);
- } else {
- hmacKey = (unsigned char*)key;
- *hmacKeyLen = keyLen;
- }
-
- if (HMAC(EVP_sha384(), hmacKey, *hmacKeyLen, buf, len, hash, NULL) != NULL){
- return PS_SUCCESS;
- }
- psAssert(0);
- return PS_FAIL;
+ psSha384_t sha;
+
+ if (keyLen > 64)
+ {
+ psSha384Init(&sha);
+ psSha384Update(&sha, key, keyLen);
+ psSha384Final(&sha, hash);
+ *hmacKeyLen = SHA384_HASHLEN;
+ memcpy(hmacKey, hash, *hmacKeyLen);
+ }
+ else
+ {
+ hmacKey = (unsigned char *) key;
+ *hmacKeyLen = keyLen;
+ }
+
+ if (HMAC(EVP_sha384(), hmacKey, *hmacKeyLen, buf, len, hash, NULL) != NULL)
+ {
+ return PS_SUCCESS;
+ }
+ psAssert(0);
+ return PS_FAIL;
}
int32_t psHmacSha384Init(psHmacSha384_t *ctx,
- const unsigned char *key, uint16_t keyLen)
+ const unsigned char *key, psSize_t keyLen)
{
- HMAC_CTX_init(ctx);
- if (HMAC_Init_ex(ctx, key, keyLen, EVP_sha384(), NULL) == 1) {
- return PS_SUCCESS;
- }
- HMAC_CTX_cleanup(ctx);
- psAssert(0);
- return PS_FAIL;
+ HMAC_CTX_init(ctx);
+ if (HMAC_Init_ex(ctx, key, keyLen, EVP_sha384(), NULL) == 1)
+ {
+ return PS_SUCCESS;
+ }
+ HMAC_CTX_cleanup(ctx);
+ psAssert(0);
+ return PS_FAIL;
}
void psHmacSha384Update(psHmacSha384_t *ctx,
- const unsigned char *buf, uint32_t len)
+ const unsigned char *buf, uint32_t len)
{
- if (HMAC_Update(ctx, buf, len) != 1) {
- HMAC_CTX_cleanup(ctx);
- }
+ if (HMAC_Update(ctx, buf, len) != 1)
+ {
+ HMAC_CTX_cleanup(ctx);
+ }
}
void psHmacSha384Final(psHmacSha384_t *ctx,
- unsigned char hash[SHA384_HASHLEN])
+ unsigned char hash[SHA384_HASHLEN])
{
- if (HMAC_Final(ctx, hash, NULL) != 1) {
- psAssert(0);
- }
- HMAC_CTX_cleanup(ctx);
+ if (HMAC_Final(ctx, hash, NULL) != 1)
+ {
+ psAssert(0);
+ }
+ HMAC_CTX_cleanup(ctx);
}
#endif /* USE_OPENSSL_HMAC_SHA384 */
@@ -263,144 +289,162 @@ void psHmacSha384Final(psHmacSha384_t *ctx,
#ifdef USE_OPENSSL_MD5
int32_t psMd5Init(psMd5_t *md5)
{
- if (MD5_Init(md5) != 1) {
- return PS_FAIL;
- }
- return PS_SUCCESS;
+ if (MD5_Init(md5) != 1)
+ {
+ return PS_FAIL;
+ }
+ return PS_SUCCESS;
}
void psMd5Update(psMd5_t *md5, const unsigned char *buf, uint32_t len)
{
- if (MD5_Update(md5, buf, len) != 1) {
- memset(md5, 0x0, sizeof(psMd5_t));
- }
+ if (MD5_Update(md5, buf, len) != 1)
+ {
+ memset(md5, 0x0, sizeof(psMd5_t));
+ }
}
void psMd5Final(psMd5_t *md5, unsigned char hash[MD5_HASHLEN])
{
- if (MD5_Final(hash, md5) != 1) {
- memset(hash, 0x0, MD5_HASHLEN);
- memset(md5, 0x0, sizeof(psMd5_t));
- }
+ if (MD5_Final(hash, md5) != 1)
+ {
+ memset(hash, 0x0, MD5_HASHLEN);
+ memset(md5, 0x0, sizeof(psMd5_t));
+ }
}
#endif
#ifdef USE_OPENSSL_MD5SHA1
int32_t psMd5Sha1Init(psMd5Sha1_t *md)
{
- if (MD5_Init(&md->md5) != 1 || SHA1_Init(&md->sha1) != 1) {
- memset(md, 0x0, sizeof(psMd5Sha1_t));
- return PS_FAIL;
- }
- return PS_SUCCESS;
+ if (MD5_Init(&md->md5) != 1 || SHA1_Init(&md->sha1) != 1)
+ {
+ memset(md, 0x0, sizeof(psMd5Sha1_t));
+ return PS_FAIL;
+ }
+ return PS_SUCCESS;
}
-void psMd5Sha1Update(psMd5Sha1_t *md,
- const unsigned char *buf, uint32_t len)
+void psMd5Sha1Update(psMd5Sha1_t *md,
+ const unsigned char *buf, uint32_t len)
{
- if (MD5_Update(&md->md5, buf, len) != 1 || SHA1_Update(&md->sha1, buf, len) != 1 ) {
- memset(md, 0x0, sizeof(psMd5Sha1_t));
- }
+ if (MD5_Update(&md->md5, buf, len) != 1 || SHA1_Update(&md->sha1, buf, len) != 1 )
+ {
+ memset(md, 0x0, sizeof(psMd5Sha1_t));
+ }
}
void psMd5Sha1Final(psMd5Sha1_t *md,
- unsigned char hash[MD5SHA1_HASHLEN])
+ unsigned char hash[MD5SHA1_HASHLEN])
{
- if (MD5_Final(hash, &md->md5) != 1 ||
- SHA1_Final(hash + MD5_HASHLEN, &md->sha1) != 1 ) {
- memset(hash, 0x0, MD5SHA1_HASHLEN);
- memset(md, 0x0, sizeof(psMd5Sha1_t));
- }
+ if (MD5_Final(hash, &md->md5) != 1 ||
+ SHA1_Final(hash + MD5_HASHLEN, &md->sha1) != 1 )
+ {
+ memset(hash, 0x0, MD5SHA1_HASHLEN);
+ memset(md, 0x0, sizeof(psMd5Sha1_t));
+ }
}
#endif
#ifdef USE_OPENSSL_SHA1
int32_t psSha1Init(psSha1_t *sha1)
{
- if (SHA1_Init(sha1) != 1) {
- return PS_FAIL;
- }
- return PS_SUCCESS;
+ if (SHA1_Init(sha1) != 1)
+ {
+ return PS_FAIL;
+ }
+ return PS_SUCCESS;
}
void psSha1Update(psSha1_t *sha1, const unsigned char *buf, uint32_t len)
{
- if (SHA1_Update(sha1, buf, len) != 1) {
- memset(sha1, 0x0, sizeof(psSha1_t));
- }
+ if (SHA1_Update(sha1, buf, len) != 1)
+ {
+ memset(sha1, 0x0, sizeof(psSha1_t));
+ }
}
void psSha1Final(psSha1_t *sha1, unsigned char hash[SHA1_HASHLEN])
{
- if (SHA1_Final(hash, sha1) != 1) {
- memset(hash, 0x0, SHA1_HASHLEN);
- memset(sha1, 0x0, sizeof(psSha1_t));
- }
+ if (SHA1_Final(hash, sha1) != 1)
+ {
+ memset(hash, 0x0, SHA1_HASHLEN);
+ memset(sha1, 0x0, sizeof(psSha1_t));
+ }
}
#endif
#ifdef USE_OPENSSL_SHA256
int32_t psSha256Init(psSha256_t *sha256)
{
- if (SHA256_Init(sha256) != 1) {
- return PS_FAIL;
- }
- return PS_SUCCESS;
+ if (SHA256_Init(sha256) != 1)
+ {
+ return PS_FAIL;
+ }
+ return PS_SUCCESS;
}
void psSha256Update(psSha256_t *sha256, const unsigned char *buf, uint32_t len)
{
- if (SHA256_Update(sha256, buf, len) != 1) {
- memset(sha256, 0x0, sizeof(psSha256_t));
- }
+ if (SHA256_Update(sha256, buf, len) != 1)
+ {
+ memset(sha256, 0x0, sizeof(psSha256_t));
+ }
}
void psSha256Final(psSha256_t *sha256, unsigned char hash[SHA256_HASHLEN])
{
- if (SHA256_Final(hash, sha256) != 1) {
- memset(hash, 0x0, SHA256_HASHLEN);
- memset(sha256, 0x0, sizeof(psSha256_t));
- }
+ if (SHA256_Final(hash, sha256) != 1)
+ {
+ memset(hash, 0x0, SHA256_HASHLEN);
+ memset(sha256, 0x0, sizeof(psSha256_t));
+ }
}
#endif
#ifdef USE_OPENSSL_SHA384
int32_t psSha384Init(psSha384_t *sha384)
{
- if (SHA384_Init(sha384) != 1) {
- return PS_FAIL;
- }
- return PS_SUCCESS;
+ if (SHA384_Init(sha384) != 1)
+ {
+ return PS_FAIL;
+ }
+ return PS_SUCCESS;
}
void psSha384Update(psSha384_t *sha384, const unsigned char *buf, uint32_t len)
{
- if (SHA384_Update(sha384, buf, len) != 1) {
- memset(sha384, 0x0, sizeof(psSha384_t));
- }
+ if (SHA384_Update(sha384, buf, len) != 1)
+ {
+ memset(sha384, 0x0, sizeof(psSha384_t));
+ }
}
void psSha384Final(psSha384_t *sha384, unsigned char hash[SHA384_HASHLEN])
{
- if (SHA384_Final(hash, sha384) != 1) {
- memset(hash, 0x0, SHA384_HASHLEN);
- memset(sha384, 0x0, sizeof(psSha384_t));
- }
+ if (SHA384_Final(hash, sha384) != 1)
+ {
+ memset(hash, 0x0, SHA384_HASHLEN);
+ memset(sha384, 0x0, sizeof(psSha384_t));
+ }
}
#endif
#ifdef USE_OPENSSL_SHA512
int32_t psSha512Init(psSha512_t *sha512)
{
- if (SHA512_Init(sha512) != 1) {
- return PS_FAIL;
- }
- return PS_SUCCESS;
+ if (SHA512_Init(sha512) != 1)
+ {
+ return PS_FAIL;
+ }
+ return PS_SUCCESS;
}
void psSha512Update(psSha512_t *sha512, const unsigned char *buf, uint32_t len)
{
- if (SHA512_Update(sha512, buf, len) != 1) {
- memset(sha512, 0x0, sizeof(psSha512_t));
- }
+ if (SHA512_Update(sha512, buf, len) != 1)
+ {
+ memset(sha512, 0x0, sizeof(psSha512_t));
+ }
}
void psSha512Final(psSha512_t *sha512, unsigned char hash[SHA512_HASHLEN])
{
- if (SHA512_Final(hash, sha512) != 1) {
- memset(hash, 0x0, SHA512_HASHLEN);
- memset(sha512, 0x0, sizeof(psSha512_t));
- }
+ if (SHA512_Final(hash, sha512) != 1)
+ {
+ memset(hash, 0x0, SHA512_HASHLEN);
+ memset(sha512, 0x0, sizeof(psSha512_t));
+ }
}
#endif
diff --git a/crypto/digest/digest_openssl.h b/crypto/digest/digest_openssl.h
index bdd706d..f50465c 100644
--- a/crypto/digest/digest_openssl.h
+++ b/crypto/digest/digest_openssl.h
@@ -1,93 +1,94 @@
/**
- * @file digest_openssl.h
- * @version $Format:%h%d$
+ * @file digest_openssl.h
+ * @version $Format:%h%d$
*
- * Header for OpenSSL Crypto Layer.
+ * Header for OpenSSL Crypto Layer.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_OPENSSL_DIGEST
-#define _h_OPENSSL_DIGEST
+# define _h_OPENSSL_DIGEST
/******************************************************************************/
-#if defined(USE_OPENSSL_MD5) || defined(USE_OPENSSL_MD5SHA1)
-#include
-#endif
+# if defined(USE_OPENSSL_MD5) || defined(USE_OPENSSL_MD5SHA1)
+# include
+# endif
-#if defined(USE_OPENSSL_SHA1) || defined(USE_OPENSSL_SHA256) || \
- defined(USE_OPENSSL_SHA384) || defined(USE_OPENSSL_SHA512)
-#include
-#endif
+# if defined(USE_OPENSSL_SHA1) || defined(USE_OPENSSL_SHA256) || \
+ defined(USE_OPENSSL_SHA384) || defined(USE_OPENSSL_SHA512)
+# include
+# endif
-#ifdef USE_OPENSSL_MD5
-typedef MD5_CTX psMd5_t;
-#endif
+# ifdef USE_OPENSSL_MD5
+typedef MD5_CTX psMd5_t;
+# endif
-#ifdef USE_OPENSSL_MD5SHA1
-typedef struct {
- MD5_CTX md5;
- SHA_CTX sha1;
+# ifdef USE_OPENSSL_MD5SHA1
+typedef struct
+{
+ MD5_CTX md5;
+ SHA_CTX sha1;
} psMd5Sha1_t;
-#endif
+# endif
-#ifdef USE_OPENSSL_SHA1
-typedef SHA_CTX psSha1_t;
-#endif
+# ifdef USE_OPENSSL_SHA1
+typedef SHA_CTX psSha1_t;
+# endif
-#ifdef USE_OPENSSL_SHA256
-typedef SHA256_CTX psSha256_t;
-#endif
+# ifdef USE_OPENSSL_SHA256
+typedef SHA256_CTX psSha256_t;
+# endif
-#ifdef USE_OPENSSL_SHA384
-typedef SHA512_CTX psSha384_t;
-#endif
+# ifdef USE_OPENSSL_SHA384
+typedef SHA512_CTX psSha384_t;
+# endif
-#ifdef USE_OPENSSL_SHA512
-typedef SHA512_CTX psSha512_t;
-#endif
+# ifdef USE_OPENSSL_SHA512
+typedef SHA512_CTX psSha512_t;
+# endif
/******************************************************************************/
-#if defined(USE_OPENSSL_HMAC_SHA1) || defined(USE_OPENSSL_HMAC_SHA256) || \
- defined(USE_OPENSSL_HMAC_SHA384) || defined(USE_OPENSSL_HMAC_SHA512)
+# if defined(USE_OPENSSL_HMAC_SHA1) || defined(USE_OPENSSL_HMAC_SHA256) || \
+ defined(USE_OPENSSL_HMAC_SHA384) || defined(USE_OPENSSL_HMAC_SHA512)
-#include
-#include
+# include
+# include
-typedef HMAC_CTX psHmacMd5_t;
-typedef HMAC_CTX psHmacSha1_t;
-typedef HMAC_CTX psHmacSha256_t;
-typedef HMAC_CTX psHmacSha384_t;
+typedef HMAC_CTX psHmacMd5_t;
+typedef HMAC_CTX psHmacSha1_t;
+typedef HMAC_CTX psHmacSha256_t;
+typedef HMAC_CTX psHmacSha384_t;
-#endif
+# endif
/******************************************************************************/
diff --git a/crypto/digest/hmac.c b/crypto/digest/hmac.c
index cb31b94..b92a172 100644
--- a/crypto/digest/hmac.c
+++ b/crypto/digest/hmac.c
@@ -1,241 +1,259 @@
/**
- * @file hmac.c
- * @version $Format:%h%d$
+ * @file hmac.c
+ * @version $Format:%h%d$
*
- * HMAC implementation.
+ * HMAC implementation.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
int32_t psHmacInit(psHmac_t *ctx, psCipherType_e type,
- const unsigned char *key, uint16_t keyLen)
+ const unsigned char *key, psSize_t keyLen)
{
- ctx->type = (uint8_t)type;
- switch(type) {
+ ctx->type = (uint8_t) type;
+ switch (type)
+ {
#ifdef USE_HMAC_MD5
- case HMAC_MD5:
- return psHmacMd5Init(&ctx->u.md5, key, keyLen);
+ case HMAC_MD5:
+ return psHmacMd5Init(&ctx->u.md5, key, keyLen);
#endif
#ifdef USE_HMAC_SHA1
- case HMAC_SHA1:
- return psHmacSha1Init(&ctx->u.sha1, key, keyLen);
+ case HMAC_SHA1:
+ return psHmacSha1Init(&ctx->u.sha1, key, keyLen);
#endif
#ifdef USE_HMAC_SHA256
- case HMAC_SHA256:
- return psHmacSha256Init(&ctx->u.sha256, key, keyLen);
+ case HMAC_SHA256:
+ return psHmacSha256Init(&ctx->u.sha256, key, keyLen);
#endif
#ifdef USE_HMAC_SHA384
- case HMAC_SHA384:
- return psHmacSha384Init(&ctx->u.sha384, key, keyLen);
+ case HMAC_SHA384:
+ return psHmacSha384Init(&ctx->u.sha384, key, keyLen);
#endif
- default:
- return PS_ARG_FAIL;
- }
- /* Redundant return */
- return PS_ARG_FAIL;
+ default:
+ return PS_ARG_FAIL;
+ }
+ /* Redundant return */
+ return PS_ARG_FAIL;
}
void psHmacUpdate(psHmac_t *ctx, const unsigned char *buf, uint32_t len)
{
- switch((psCipherType_e)ctx->type) {
+ switch ((psCipherType_e) ctx->type)
+ {
#ifdef USE_HMAC_MD5
- case HMAC_MD5:
- psHmacMd5Update(&ctx->u.md5, buf, len);
- break;
+ case HMAC_MD5:
+ psHmacMd5Update(&ctx->u.md5, buf, len);
+ break;
#endif
#ifdef USE_HMAC_SHA1
- case HMAC_SHA1:
- psHmacSha1Update(&ctx->u.sha1, buf, len);
- break;
+ case HMAC_SHA1:
+ psHmacSha1Update(&ctx->u.sha1, buf, len);
+ break;
#endif
#ifdef USE_HMAC_SHA256
- case HMAC_SHA256:
- psHmacSha256Update(&ctx->u.sha256, buf, len);
- break;
+ case HMAC_SHA256:
+ psHmacSha256Update(&ctx->u.sha256, buf, len);
+ break;
#endif
#ifdef USE_HMAC_SHA384
- case HMAC_SHA384:
- psHmacSha384Update(&ctx->u.sha384, buf, len);
- break;
+ case HMAC_SHA384:
+ psHmacSha384Update(&ctx->u.sha384, buf, len);
+ break;
#endif
- default:
- break;
- }
+ default:
+ break;
+ }
}
void psHmacFinal(psHmac_t *ctx, unsigned char hash[MAX_HASHLEN])
{
- switch((psCipherType_e)ctx->type) {
+ switch ((psCipherType_e) ctx->type)
+ {
#ifdef USE_HMAC_MD5
- case HMAC_MD5:
- psHmacMd5Final(&ctx->u.md5, hash);
- break;
+ case HMAC_MD5:
+ psHmacMd5Final(&ctx->u.md5, hash);
+ break;
#endif
#ifdef USE_HMAC_SHA1
- case HMAC_SHA1:
- psHmacSha1Final(&ctx->u.sha1, hash);
- break;
+ case HMAC_SHA1:
+ psHmacSha1Final(&ctx->u.sha1, hash);
+ break;
#endif
#ifdef USE_HMAC_SHA256
- case HMAC_SHA256:
- psHmacSha256Final(&ctx->u.sha256, hash);
- break;
+ case HMAC_SHA256:
+ psHmacSha256Final(&ctx->u.sha256, hash);
+ break;
#endif
#ifdef USE_HMAC_SHA384
- case HMAC_SHA384:
- psHmacSha384Final(&ctx->u.sha384, hash);
- break;
+ case HMAC_SHA384:
+ psHmacSha384Final(&ctx->u.sha384, hash);
+ break;
#endif
- default:
- break;
- }
- ctx->type = 0;
+ default:
+ break;
+ }
+ ctx->type = 0;
}
#ifdef USE_MATRIX_HMAC_MD5
/******************************************************************************/
/*
- HMAC-MD5
- http://www.faqs.org/rfcs/rfc2104.html
+ HMAC-MD5
+ http://www.faqs.org/rfcs/rfc2104.html
- the HMAC_MD5 transform looks like:
+ the HMAC_MD5 transform looks like:
- MD5(K XOR opad, MD5(K XOR ipad, text))
+ MD5(K XOR opad, MD5(K XOR ipad, text))
- where K is an n byte key
- ipad is the byte 0x36 repeated 64 times
+ where K is an n byte key
+ ipad is the byte 0x36 repeated 64 times
- opad is the byte 0x5c repeated 64 times
- and text is the data being protected
+ opad is the byte 0x5c repeated 64 times
+ and text is the data being protected
- If the keyLen is > 64 bytes, we hash the key and use it instead
-*/
-#if !defined(USE_MATRIX_MD5) && !defined(USE_CL_DIGESTS)
-#error USE_MATRIX_MD5 or USE_CL_DIGESTS required
-#endif
-int32_t psHmacMd5(const unsigned char *key, uint16_t keyLen,
- const unsigned char *buf, uint32_t len,
- unsigned char hash[MD5_HASHLEN],
- unsigned char *hmacKey, uint16_t *hmacKeyLen)
+ If the keyLen is > 64 bytes, we hash the key and use it instead
+ */
+# if !defined(USE_MATRIX_MD5) && !defined(USE_CL_DIGESTS)
+# error USE_MATRIX_MD5 or USE_CL_DIGESTS required
+# endif
+int32_t psHmacMd5(const unsigned char *key, psSize_t keyLen,
+ const unsigned char *buf, uint32_t len,
+ unsigned char hash[MD5_HASHLEN],
+ unsigned char *hmacKey, psSize_t *hmacKeyLen)
{
- int32_t rc;
- union {
- psHmacMd5_t mac;
- psMd5_t md;
- } u;
- psHmacMd5_t *mac = &u.mac;
- psMd5_t *md = &u.md;
+ int32_t rc;
+
+ union
+ {
+ psHmacMd5_t mac;
+ psMd5_t md;
+ } u;
+ psHmacMd5_t *mac = &u.mac;
+ psMd5_t *md = &u.md;
/*
- Support for keys larger than 64 bytes. In this case, we take the
- hash of the key itself and use that instead. Inform the caller by
- updating the hmacKey and hmacKeyLen outputs
-*/
- if (keyLen > 64) {
- if ((rc = psMd5Init(md)) < 0) {
- return rc;
- }
- psMd5Update(md, key, keyLen);
- psMd5Final(md, hash);
- *hmacKeyLen = MD5_HASHLEN;
- memcpy(hmacKey, hash, *hmacKeyLen);
- } else {
- hmacKey = (unsigned char *)key; /* @note typecasting from const */
- *hmacKeyLen = keyLen;
- }
- if ((rc = psHmacMd5Init(mac, hmacKey, *hmacKeyLen)) < 0) {
- return rc;
- }
- psHmacMd5Update(mac, buf, len);
- psHmacMd5Final(mac, hash);
- return PS_SUCCESS;
+ Support for keys larger than 64 bytes. In this case, we take the
+ hash of the key itself and use that instead. Inform the caller by
+ updating the hmacKey and hmacKeyLen outputs
+ */
+ if (keyLen > 64)
+ {
+ if ((rc = psMd5Init(md)) < 0)
+ {
+ return rc;
+ }
+ psMd5Update(md, key, keyLen);
+ psMd5Final(md, hash);
+ *hmacKeyLen = MD5_HASHLEN;
+ memcpy(hmacKey, hash, *hmacKeyLen);
+ }
+ else
+ {
+ hmacKey = (unsigned char *) key; /* @note typecasting from const */
+ *hmacKeyLen = keyLen;
+ }
+ if ((rc = psHmacMd5Init(mac, hmacKey, *hmacKeyLen)) < 0)
+ {
+ return rc;
+ }
+ psHmacMd5Update(mac, buf, len);
+ psHmacMd5Final(mac, hash);
+ return PS_SUCCESS;
}
int32_t psHmacMd5Init(psHmacMd5_t *ctx,
- const unsigned char *key, uint16_t keyLen)
+ const unsigned char *key, psSize_t keyLen)
{
- int32_t rc, i;
+ int32_t rc, i;
-#ifdef CRYPTO_ASSERT
- psAssert(keyLen <= 64);
-#endif
- for (i = 0; (uint32)i < keyLen; i++) {
- ctx->pad[i] = key[i] ^ 0x36;
- }
- for (i = keyLen; i < 64; i++) {
- ctx->pad[i] = 0x36;
- }
- if ((rc = psMd5Init(&ctx->md5)) < 0) {
- return rc;
- }
- psMd5Update(&ctx->md5, ctx->pad, 64);
- for (i = 0; (uint32)i < keyLen; i++) {
- ctx->pad[i] = key[i] ^ 0x5c;
- }
- for (i = keyLen; i < 64; i++) {
- ctx->pad[i] = 0x5c;
- }
- return PS_SUCCESS;
+# ifdef CRYPTO_ASSERT
+ psAssert(keyLen <= 64);
+# endif
+ for (i = 0; (uint32) i < keyLen; i++)
+ {
+ ctx->pad[i] = key[i] ^ 0x36;
+ }
+ for (i = keyLen; i < 64; i++)
+ {
+ ctx->pad[i] = 0x36;
+ }
+ if ((rc = psMd5Init(&ctx->md5)) < 0)
+ {
+ return rc;
+ }
+ psMd5Update(&ctx->md5, ctx->pad, 64);
+ for (i = 0; (uint32) i < keyLen; i++)
+ {
+ ctx->pad[i] = key[i] ^ 0x5c;
+ }
+ for (i = keyLen; i < 64; i++)
+ {
+ ctx->pad[i] = 0x5c;
+ }
+ return PS_SUCCESS;
}
void psHmacMd5Update(psHmacMd5_t *ctx,
- const unsigned char *buf, uint32_t len)
+ const unsigned char *buf, uint32_t len)
{
-#ifdef CRYPTO_ASSERT
- psAssert(ctx != NULL && buf != NULL);
-#endif
- psMd5Update(&ctx->md5, buf, len);
+# ifdef CRYPTO_ASSERT
+ psAssert(ctx != NULL && buf != NULL);
+# endif
+ psMd5Update(&ctx->md5, buf, len);
}
void psHmacMd5Final(psHmacMd5_t *ctx, unsigned char hash[MD5_HASHLEN])
{
- int32_t rc;
-#ifdef CRYPTO_ASSERT
- psAssert(ctx != NULL);
- if (hash == NULL) {
- psTraceCrypto("NULL hash storage passed to psHmacMd5Final\n");
- return;
- }
-#endif
- psMd5Final(&ctx->md5, hash);
+ int32_t rc;
- /* This Init should succeed, even if it allocates memory since an
- psMd5_t was just Finalized the line above */
- if ((rc = psMd5Init(&ctx->md5)) < 0) {
- psAssert(rc >= 0);
- return;
- }
- psMd5Update(&ctx->md5, ctx->pad, 64);
- psMd5Update(&ctx->md5, hash, MD5_HASHLEN);
- psMd5Final(&ctx->md5, hash);
+# ifdef CRYPTO_ASSERT
+ psAssert(ctx != NULL);
+ if (hash == NULL)
+ {
+ psTraceCrypto("NULL hash storage passed to psHmacMd5Final\n");
+ return;
+ }
+# endif
+ psMd5Final(&ctx->md5, hash);
- memset(ctx->pad, 0x0, sizeof(ctx->pad));
+ /* This Init should succeed, even if it allocates memory since an
+ psMd5_t was just Finalized the line above */
+ if ((rc = psMd5Init(&ctx->md5)) < 0)
+ {
+ psAssert(rc >= 0);
+ return;
+ }
+ psMd5Update(&ctx->md5, ctx->pad, 64);
+ psMd5Update(&ctx->md5, hash, MD5_HASHLEN);
+ psMd5Final(&ctx->md5, hash);
+
+ memset(ctx->pad, 0x0, sizeof(ctx->pad));
}
#endif /* USE_MATRIX_HMAC_MD5 */
@@ -243,107 +261,123 @@ void psHmacMd5Final(psHmacMd5_t *ctx, unsigned char hash[MD5_HASHLEN])
#ifdef USE_MATRIX_HMAC_SHA1
/******************************************************************************/
/*
- HMAC-SHA1
- @see http://www.faqs.org/rfcs/rfc2104.html
-*/
-#ifndef USE_SHA1
-#error USE_SHA1 required
-#endif
+ HMAC-SHA1
+ @see http://www.faqs.org/rfcs/rfc2104.html
+ */
+# ifndef USE_SHA1
+# error USE_SHA1 required
+# endif
-int32_t psHmacSha1(const unsigned char *key, uint16_t keyLen,
- const unsigned char *buf, uint32_t len,
- unsigned char hash[SHA1_HASHLEN],
- unsigned char *hmacKey, uint16_t *hmacKeyLen)
+int32_t psHmacSha1(const unsigned char *key, psSize_t keyLen,
+ const unsigned char *buf, uint32_t len,
+ unsigned char hash[SHA1_HASHLEN],
+ unsigned char *hmacKey, psSize_t *hmacKeyLen)
{
- int32_t rc;
- union {
- psHmacSha1_t mac;
- psSha1_t md;
- } u;
- psHmacSha1_t *mac = &u.mac;
- psSha1_t *md = &u.md;
-/*
- Support for keys larger than 64 bytes. In this case, we take the
- hash of the key itself and use that instead. Inform the caller by
- updating the hmacKey and hmacKeyLen outputs
-*/
- if (keyLen > 64) {
- if ((rc = psSha1Init(md)) < 0) {
- return rc;
- }
- psSha1Update(md, key, keyLen);
- psSha1Final(md, hash);
- *hmacKeyLen = SHA1_HASHLEN;
- memcpy(hmacKey, hash, *hmacKeyLen);
- } else {
- hmacKey = (unsigned char *)key; /* @note typecasting from const */
- *hmacKeyLen = keyLen;
- }
+ int32_t rc;
- if ((rc = psHmacSha1Init(mac, hmacKey, *hmacKeyLen)) < 0) {
- return rc;
- }
- psHmacSha1Update(mac, buf, len);
- psHmacSha1Final(mac, hash);
- return PS_SUCCESS;
+ union
+ {
+ psHmacSha1_t mac;
+ psSha1_t md;
+ } u;
+ psHmacSha1_t *mac = &u.mac;
+ psSha1_t *md = &u.md;
+/*
+ Support for keys larger than 64 bytes. In this case, we take the
+ hash of the key itself and use that instead. Inform the caller by
+ updating the hmacKey and hmacKeyLen outputs
+ */
+ if (keyLen > 64)
+ {
+ if ((rc = psSha1Init(md)) < 0)
+ {
+ return rc;
+ }
+ psSha1Update(md, key, keyLen);
+ psSha1Final(md, hash);
+ *hmacKeyLen = SHA1_HASHLEN;
+ memcpy(hmacKey, hash, *hmacKeyLen);
+ }
+ else
+ {
+ hmacKey = (unsigned char *) key; /* @note typecasting from const */
+ *hmacKeyLen = keyLen;
+ }
+
+ if ((rc = psHmacSha1Init(mac, hmacKey, *hmacKeyLen)) < 0)
+ {
+ return rc;
+ }
+ psHmacSha1Update(mac, buf, len);
+ psHmacSha1Final(mac, hash);
+ return PS_SUCCESS;
}
int32_t psHmacSha1Init(psHmacSha1_t *ctx,
- const unsigned char *key, uint16_t keyLen)
+ const unsigned char *key, psSize_t keyLen)
{
- int32_t rc, i;
-#ifdef CRYPTO_ASSERT
- psAssert(keyLen <= 64);
-#endif
- for (i = 0; (uint32)i < keyLen; i++) {
- ctx->pad[i] = key[i] ^ 0x36;
- }
- for (i = keyLen; (uint32)i < 64; i++) {
- ctx->pad[i] = 0x36;
- }
- if ((rc = psSha1Init(&ctx->sha1)) < 0) {
- return rc;
- }
- psSha1Update(&ctx->sha1, ctx->pad, 64);
- for (i = 0; (uint32)i < keyLen; i++) {
- ctx->pad[i] = key[i] ^ 0x5c;
- }
- for (i = keyLen; i < 64; i++) {
- ctx->pad[i] = 0x5c;
- }
- return PS_SUCCESS;
+ int32_t rc, i;
+
+# ifdef CRYPTO_ASSERT
+ psAssert(keyLen <= 64);
+# endif
+ for (i = 0; (uint32) i < keyLen; i++)
+ {
+ ctx->pad[i] = key[i] ^ 0x36;
+ }
+ for (i = keyLen; (uint32) i < 64; i++)
+ {
+ ctx->pad[i] = 0x36;
+ }
+ if ((rc = psSha1Init(&ctx->sha1)) < 0)
+ {
+ return rc;
+ }
+ psSha1Update(&ctx->sha1, ctx->pad, 64);
+ for (i = 0; (uint32) i < keyLen; i++)
+ {
+ ctx->pad[i] = key[i] ^ 0x5c;
+ }
+ for (i = keyLen; i < 64; i++)
+ {
+ ctx->pad[i] = 0x5c;
+ }
+ return PS_SUCCESS;
}
void psHmacSha1Update(psHmacSha1_t *ctx,
- const unsigned char *buf, uint32_t len)
+ const unsigned char *buf, uint32_t len)
{
-#ifdef CRYPTO_ASSERT
- psAssert(ctx != NULL && buf != NULL);
-#endif
- psSha1Update(&ctx->sha1, buf, len);
+# ifdef CRYPTO_ASSERT
+ psAssert(ctx != NULL && buf != NULL);
+# endif
+ psSha1Update(&ctx->sha1, buf, len);
}
void psHmacSha1Final(psHmacSha1_t *ctx, unsigned char hash[SHA1_HASHLEN])
{
- int32_t rc;
-#ifdef CRYPTO_ASSERT
- psAssert(ctx != NULL);
- if (hash == NULL) {
- psTraceCrypto("NULL hash storage passed to psHmacSha1Final\n");
- return;
- }
-#endif
- psSha1Final(&ctx->sha1, hash);
+ int32_t rc;
- if ((rc = psSha1Init(&ctx->sha1)) < 0) {
- psAssert(rc >= 0);
- return;
- }
- psSha1Update(&ctx->sha1, ctx->pad, 64);
- psSha1Update(&ctx->sha1, hash, SHA1_HASHLEN);
- psSha1Final(&ctx->sha1, hash);
+# ifdef CRYPTO_ASSERT
+ psAssert(ctx != NULL);
+ if (hash == NULL)
+ {
+ psTraceCrypto("NULL hash storage passed to psHmacSha1Final\n");
+ return;
+ }
+# endif
+ psSha1Final(&ctx->sha1, hash);
- memset(ctx->pad, 0x0, sizeof(ctx->pad));
+ if ((rc = psSha1Init(&ctx->sha1)) < 0)
+ {
+ psAssert(rc >= 0);
+ return;
+ }
+ psSha1Update(&ctx->sha1, ctx->pad, 64);
+ psSha1Update(&ctx->sha1, hash, SHA1_HASHLEN);
+ psSha1Final(&ctx->sha1, hash);
+
+ memset(ctx->pad, 0x0, sizeof(ctx->pad));
}
#endif /* USE_MATRIX_HMAC_SHA1 */
@@ -351,218 +385,248 @@ void psHmacSha1Final(psHmacSha1_t *ctx, unsigned char hash[SHA1_HASHLEN])
#ifdef USE_MATRIX_HMAC_SHA256
/******************************************************************************/
/*
- HMAC-SHA256
-*/
-int32_t psHmacSha256(const unsigned char *key, uint16_t keyLen,
- const unsigned char *buf, uint32_t len,
- unsigned char hash[SHA256_HASHLEN], unsigned char *hmacKey,
- uint16_t *hmacKeyLen)
+ HMAC-SHA256
+ */
+int32_t psHmacSha256(const unsigned char *key, psSize_t keyLen,
+ const unsigned char *buf, uint32_t len,
+ unsigned char hash[SHA256_HASHLEN], unsigned char *hmacKey,
+ psSize_t *hmacKeyLen)
{
- int32 rc, padLen;
- union {
- psHmacSha256_t mac;
- psSha256_t md;
- } u;
- psHmacSha256_t *mac = &u.mac;
- psSha256_t *md = &u.md;
+ int32 rc, padLen;
- padLen = 64;
+ union
+ {
+ psHmacSha256_t mac;
+ psSha256_t md;
+ } u;
+ psHmacSha256_t *mac = &u.mac;
+ psSha256_t *md = &u.md;
+
+ padLen = 64;
/*
- Support for keys larger than hash block size. In this case, we take the
- hash of the key itself and use that instead. Inform the caller by
- updating the hmacKey and hmacKeyLen outputs
-*/
- if (keyLen > (uint32)padLen) {
- if ((rc = psSha256Init(md)) < 0) {
- return rc;
- }
- psSha256Update(md, key, keyLen);
- psSha256Final(md, hash);
- memcpy(hmacKey, hash, SHA256_HASHLEN);
- *hmacKeyLen = SHA256_HASHLEN;
- } else {
- hmacKey = (unsigned char *)key; /* @note typecasting from const */
- *hmacKeyLen = keyLen;
- }
+ Support for keys larger than hash block size. In this case, we take the
+ hash of the key itself and use that instead. Inform the caller by
+ updating the hmacKey and hmacKeyLen outputs
+ */
+ if (keyLen > (uint32) padLen)
+ {
+ if ((rc = psSha256Init(md)) < 0)
+ {
+ return rc;
+ }
+ psSha256Update(md, key, keyLen);
+ psSha256Final(md, hash);
+ memcpy(hmacKey, hash, SHA256_HASHLEN);
+ *hmacKeyLen = SHA256_HASHLEN;
+ }
+ else
+ {
+ hmacKey = (unsigned char *) key; /* @note typecasting from const */
+ *hmacKeyLen = keyLen;
+ }
- if ((rc = psHmacSha256Init(mac, hmacKey, *hmacKeyLen)) < 0) {
- return rc;
- }
- psHmacSha256Update(mac, buf, len);
- psHmacSha256Final(mac, hash);
- return PS_SUCCESS;
+ if ((rc = psHmacSha256Init(mac, hmacKey, *hmacKeyLen)) < 0)
+ {
+ return rc;
+ }
+ psHmacSha256Update(mac, buf, len);
+ psHmacSha256Final(mac, hash);
+ return PS_SUCCESS;
}
int32_t psHmacSha256Init(psHmacSha256_t *ctx,
- const unsigned char *key, uint16_t keyLen)
+ const unsigned char *key, psSize_t keyLen)
{
- int32_t rc, i, padLen = 64;
+ int32_t rc, i, padLen = 64;
-#ifdef CRYPTO_ASSERT
- psAssert(keyLen <= (uint32)padLen);
-#endif
- for (i = 0; (uint32)i < keyLen; i++) {
- ctx->pad[i] = key[i] ^ 0x36;
- }
- for (i = keyLen; i < padLen; i++) {
- ctx->pad[i] = 0x36;
- }
- if ((rc = psSha256Init(&ctx->sha256)) < 0) {
- return rc;
- }
- psSha256Update(&ctx->sha256, ctx->pad, padLen);
- for (i = 0; (uint32)i < keyLen; i++) {
- ctx->pad[i] = key[i] ^ 0x5c;
- }
- for (i = keyLen; i < padLen; i++) {
- ctx->pad[i] = 0x5c;
- }
- return PS_SUCCESS;
+# ifdef CRYPTO_ASSERT
+ psAssert(keyLen <= (uint32) padLen);
+# endif
+ for (i = 0; (uint32) i < keyLen; i++)
+ {
+ ctx->pad[i] = key[i] ^ 0x36;
+ }
+ for (i = keyLen; i < padLen; i++)
+ {
+ ctx->pad[i] = 0x36;
+ }
+ if ((rc = psSha256Init(&ctx->sha256)) < 0)
+ {
+ return rc;
+ }
+ psSha256Update(&ctx->sha256, ctx->pad, padLen);
+ for (i = 0; (uint32) i < keyLen; i++)
+ {
+ ctx->pad[i] = key[i] ^ 0x5c;
+ }
+ for (i = keyLen; i < padLen; i++)
+ {
+ ctx->pad[i] = 0x5c;
+ }
+ return PS_SUCCESS;
}
void psHmacSha256Update(psHmacSha256_t *ctx,
- const unsigned char *buf, uint32_t len)
+ const unsigned char *buf, uint32_t len)
{
-#ifdef CRYPTO_ASSERT
- psAssert(ctx != NULL && buf != NULL);
-#endif
- psSha256Update(&ctx->sha256, buf, len);
+# ifdef CRYPTO_ASSERT
+ psAssert(ctx != NULL && buf != NULL);
+# endif
+ psSha256Update(&ctx->sha256, buf, len);
}
void psHmacSha256Final(psHmacSha256_t *ctx,
- unsigned char hash[SHA256_HASHLEN])
+ unsigned char hash[SHA256_HASHLEN])
{
- int32_t rc;
-#ifdef CRYPTO_ASSERT
- psAssert(ctx != NULL);
- if (hash == NULL) {
- psTraceCrypto("NULL hash storage passed to psHmacSha256Final\n");
- return;
- }
-#endif
+ int32_t rc;
- psSha256Final(&ctx->sha256, hash);
+# ifdef CRYPTO_ASSERT
+ psAssert(ctx != NULL);
+ if (hash == NULL)
+ {
+ psTraceCrypto("NULL hash storage passed to psHmacSha256Final\n");
+ return;
+ }
+# endif
- if ((rc = psSha256Init(&ctx->sha256)) < 0) {
- psAssert(rc >= 0);
- return;
- }
- psSha256Update(&ctx->sha256, ctx->pad, 64);
- psSha256Update(&ctx->sha256, hash, SHA256_HASHLEN);
- psSha256Final(&ctx->sha256, hash);
- memset(ctx->pad, 0x0, sizeof(ctx->pad));
+ psSha256Final(&ctx->sha256, hash);
+
+ if ((rc = psSha256Init(&ctx->sha256)) < 0)
+ {
+ psAssert(rc >= 0);
+ return;
+ }
+ psSha256Update(&ctx->sha256, ctx->pad, 64);
+ psSha256Update(&ctx->sha256, hash, SHA256_HASHLEN);
+ psSha256Final(&ctx->sha256, hash);
+ memset(ctx->pad, 0x0, sizeof(ctx->pad));
}
#endif /* USE_MATRIX_HMAC_SHA256 */
#ifdef USE_MATRIX_HMAC_SHA384
/******************************************************************************/
/*
- HMAC-SHA384
-*/
-int32_t psHmacSha384(const unsigned char *key, uint16_t keyLen,
- const unsigned char *buf, uint32_t len,
- unsigned char hash[SHA384_HASHLEN],
- unsigned char *hmacKey, uint16_t *hmacKeyLen)
+ HMAC-SHA384
+ */
+int32_t psHmacSha384(const unsigned char *key, psSize_t keyLen,
+ const unsigned char *buf, uint32_t len,
+ unsigned char hash[SHA384_HASHLEN],
+ unsigned char *hmacKey, psSize_t *hmacKeyLen)
{
- int32 rc, padLen;
- union {
- psHmacSha384_t mac;
- psSha384_t md;
- } u;
- psHmacSha384_t *mac = &u.mac;
- psSha384_t *md = &u.md;
+ int32 rc, padLen;
- padLen = 128;
+ union
+ {
+ psHmacSha384_t mac;
+ psSha384_t md;
+ } u;
+ psHmacSha384_t *mac = &u.mac;
+ psSha384_t *md = &u.md;
+
+ padLen = 128;
/*
- Support for keys larger than hash block size. In this case, we take the
- hash of the key itself and use that instead. Inform the caller by
- updating the hmacKey and hmacKeyLen outputs
-*/
- if (keyLen > (uint32)padLen) {
- if ((rc = psSha384Init(md)) < 0) {
- return rc;
- }
- psSha384Update(md, key, keyLen);
- psSha384Final(md, hash);
- memcpy(hmacKey, hash, SHA384_HASHLEN);
- *hmacKeyLen = SHA384_HASHLEN;
- } else {
- hmacKey = (unsigned char *)key; /* @note typecasting from const */
- *hmacKeyLen = keyLen;
- }
+ Support for keys larger than hash block size. In this case, we take the
+ hash of the key itself and use that instead. Inform the caller by
+ updating the hmacKey and hmacKeyLen outputs
+ */
+ if (keyLen > (uint32) padLen)
+ {
+ if ((rc = psSha384Init(md)) < 0)
+ {
+ return rc;
+ }
+ psSha384Update(md, key, keyLen);
+ psSha384Final(md, hash);
+ memcpy(hmacKey, hash, SHA384_HASHLEN);
+ *hmacKeyLen = SHA384_HASHLEN;
+ }
+ else
+ {
+ hmacKey = (unsigned char *) key; /* @note typecasting from const */
+ *hmacKeyLen = keyLen;
+ }
- if ((rc = psHmacSha384Init(mac, hmacKey, *hmacKeyLen)) < 0) {
- return rc;
- }
- psHmacSha384Update(mac, buf, len);
- psHmacSha384Final(mac, hash);
- return PS_SUCCESS;
+ if ((rc = psHmacSha384Init(mac, hmacKey, *hmacKeyLen)) < 0)
+ {
+ return rc;
+ }
+ psHmacSha384Update(mac, buf, len);
+ psHmacSha384Final(mac, hash);
+ return PS_SUCCESS;
}
int32_t psHmacSha384Init(psHmacSha384_t *ctx,
- const unsigned char *key, uint16_t keyLen)
+ const unsigned char *key, psSize_t keyLen)
{
- int32_t rc, i, padLen;
+ int32_t rc, i, padLen;
- padLen = 128;
+ padLen = 128;
-#ifdef CRYPTO_ASSERT
- psAssert(keyLen <= (uint32)padLen);
-#endif
- for (i = 0; (uint32)i < keyLen; i++) {
- ctx->pad[i] = key[i] ^ 0x36;
- }
- for (i = keyLen; i < padLen; i++) {
- ctx->pad[i] = 0x36;
- }
- if ((rc = psSha384Init(&ctx->sha384)) < 0) {
- return rc;
- }
- psSha384Update(&ctx->sha384, ctx->pad, padLen);
+# ifdef CRYPTO_ASSERT
+ psAssert(keyLen <= (uint32) padLen);
+# endif
+ for (i = 0; (uint32) i < keyLen; i++)
+ {
+ ctx->pad[i] = key[i] ^ 0x36;
+ }
+ for (i = keyLen; i < padLen; i++)
+ {
+ ctx->pad[i] = 0x36;
+ }
+ if ((rc = psSha384Init(&ctx->sha384)) < 0)
+ {
+ return rc;
+ }
+ psSha384Update(&ctx->sha384, ctx->pad, padLen);
- for (i = 0; (uint32)i < keyLen; i++) {
- ctx->pad[i] = key[i] ^ 0x5c;
- }
- for (i = keyLen; i < padLen; i++) {
- ctx->pad[i] = 0x5c;
- }
- return PS_SUCCESS;
+ for (i = 0; (uint32) i < keyLen; i++)
+ {
+ ctx->pad[i] = key[i] ^ 0x5c;
+ }
+ for (i = keyLen; i < padLen; i++)
+ {
+ ctx->pad[i] = 0x5c;
+ }
+ return PS_SUCCESS;
}
void psHmacSha384Update(psHmacSha384_t *ctx,
- const unsigned char *buf, uint32_t len)
+ const unsigned char *buf, uint32_t len)
{
-#ifdef CRYPTO_ASSERT
- psAssert(ctx != NULL && buf != NULL);
-#endif
- psSha384Update(&ctx->sha384, buf, len);
+# ifdef CRYPTO_ASSERT
+ psAssert(ctx != NULL && buf != NULL);
+# endif
+ psSha384Update(&ctx->sha384, buf, len);
}
void psHmacSha384Final(psHmacSha384_t *ctx,
- unsigned char hash[SHA384_HASHLEN])
+ unsigned char hash[SHA384_HASHLEN])
{
- int32_t rc;
-#ifdef CRYPTO_ASSERT
- psAssert(ctx != NULL);
- if (hash == NULL) {
- psTraceCrypto("NULL hash storage passed to psHmacSha256Final\n");
- return;
- }
-#endif
+ int32_t rc;
- psSha384Final(&ctx->sha384, hash);
+# ifdef CRYPTO_ASSERT
+ psAssert(ctx != NULL);
+ if (hash == NULL)
+ {
+ psTraceCrypto("NULL hash storage passed to psHmacSha256Final\n");
+ return;
+ }
+# endif
- if ((rc = psSha384Init(&ctx->sha384)) < 0) {
- psAssert(rc >= 0);
- return;
- }
- psSha384Update(&ctx->sha384, ctx->pad, 128);
- psSha384Update(&ctx->sha384, hash, SHA384_HASHLEN);
- psSha384Final(&ctx->sha384, hash);
+ psSha384Final(&ctx->sha384, hash);
- memset(ctx->pad, 0x0, sizeof(ctx->pad));
+ if ((rc = psSha384Init(&ctx->sha384)) < 0)
+ {
+ psAssert(rc >= 0);
+ return;
+ }
+ psSha384Update(&ctx->sha384, ctx->pad, 128);
+ psSha384Update(&ctx->sha384, hash, SHA384_HASHLEN);
+ psSha384Final(&ctx->sha384, hash);
+
+ memset(ctx->pad, 0x0, sizeof(ctx->pad));
}
#endif /* USE_MATRIX_HMAC_SHA384 */
diff --git a/crypto/digest/md2.c b/crypto/digest/md2.c
index 8ad5d0d..83e6cd0 100644
--- a/crypto/digest/md2.c
+++ b/crypto/digest/md2.c
@@ -1,177 +1,187 @@
/**
- * @file md2.c
- * @version $Format:%h%d$
+ * @file md2.c
+ * @version $Format:%h%d$
*
- * MD2 hash implementation.
+ * MD2 hash implementation.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
#ifdef USE_MATRIX_MD2
/******************************************************************************/
static const 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
+ 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
};
/* adds 16 bytes to the checksum */
static void md2_update_chksum(psMd2_t *md)
{
- int32 j;
- unsigned char L;
- L = md->chksum[15];
- for (j = 0; j < 16; j++) {
+ int32 j;
+ unsigned char L;
+
+ L = md->chksum[15];
+ for (j = 0; j < 16; j++)
+ {
/*
- caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference
- source code [and test vectors] say otherwise.
-*/
- L = (md->chksum[j] ^= PI_SUBST[(int32)(md->buf[j] ^ L)] & 255);
- }
+ caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference
+ source code [and test vectors] say otherwise.
+ */
+ L = (md->chksum[j] ^= PI_SUBST[(int32) (md->buf[j] ^ L)] & 255);
+ }
}
static void md2_compress(psMd2_t *md)
{
- int32 j, k;
- unsigned char t;
+ int32 j, k;
+ unsigned char t;
- /* copy block */
- for (j = 0; j < 16; j++) {
- md->X[16+j] = md->buf[j];
- md->X[32+j] = md->X[j] ^ md->X[16+j];
- }
+ /* copy block */
+ for (j = 0; j < 16; j++)
+ {
+ md->X[16 + j] = md->buf[j];
+ md->X[32 + j] = md->X[j] ^ md->X[16 + j];
+ }
- t = (unsigned char)0;
+ t = (unsigned char) 0;
- /* do 18 rounds */
- for (j = 0; j < 18; j++) {
- for (k = 0; k < 48; k++) {
- t = (md->X[k] ^= PI_SUBST[(int32)(t & 255)]);
- }
- t = (t + (unsigned char)j) & 255;
- }
+ /* do 18 rounds */
+ for (j = 0; j < 18; j++)
+ {
+ for (k = 0; k < 48; k++)
+ {
+ t = (md->X[k] ^= PI_SUBST[(int32) (t & 255)]);
+ }
+ t = (t + (unsigned char) j) & 255;
+ }
}
void psMd2Init(psMd2_t *md)
{
-#ifdef CRYPTO_ASSERT
- psAssert(md != NULL);
-#endif
+# ifdef CRYPTO_ASSERT
+ psAssert(md != NULL);
+# endif
- /* MD2 uses a zero'ed state... */
- memset(md->X, 0x0, sizeof(md->X));
- memset(md->chksum, 0x0, sizeof(md->chksum));
- memset(md->buf, 0x0, sizeof(md->buf));
- md->curlen = 0;
+ /* MD2 uses a zero'ed state... */
+ memset(md->X, 0x0, sizeof(md->X));
+ memset(md->chksum, 0x0, sizeof(md->chksum));
+ memset(md->buf, 0x0, sizeof(md->buf));
+ md->curlen = 0;
}
int32_t psMd2Update(psMd2_t *md, const unsigned char *buf, uint32_t len)
{
- uint32_t n;
+ uint32_t n;
-#ifdef CRYPTO_ASSERT
- psAssert(md != NULL);
- psAssert(buf != NULL);
- if (md->curlen > sizeof(md->buf)) {
- psTraceCrypto("psMd2Update error\n");
- return PS_LIMIT_FAIL;
- }
-#endif
- while (len > 0) {
- n = min(len, (16 - md->curlen));
- memcpy(md->buf + md->curlen, buf, (size_t)n);
- md->curlen += n;
- buf += n;
- len -= n;
+# ifdef CRYPTO_ASSERT
+ psAssert(md != NULL);
+ psAssert(buf != NULL);
+ if (md->curlen > sizeof(md->buf))
+ {
+ psTraceCrypto("psMd2Update error\n");
+ return PS_LIMIT_FAIL;
+ }
+# endif
+ while (len > 0)
+ {
+ n = min(len, (16 - md->curlen));
+ memcpy(md->buf + md->curlen, buf, (size_t) n);
+ md->curlen += n;
+ buf += n;
+ len -= n;
- /* is 16 bytes full? */
- if (md->curlen == 16) {
- md2_compress(md);
- md2_update_chksum(md);
- md->curlen = 0;
- }
- }
- return PS_SUCCESS;
+ /* is 16 bytes full? */
+ if (md->curlen == 16)
+ {
+ md2_compress(md);
+ md2_update_chksum(md);
+ md->curlen = 0;
+ }
+ }
+ return PS_SUCCESS;
}
-int32_t psMd2Final(psMd2_t * md, unsigned char *hash)
+int32_t psMd2Final(psMd2_t *md, unsigned char *hash)
{
- uint32 i, k;
+ uint32 i, k;
-#ifdef CRYPTO_ASSERT
- psAssert(md != NULL);
- psAssert(hash != NULL);
-#endif
+# ifdef CRYPTO_ASSERT
+ psAssert(md != NULL);
+ psAssert(hash != NULL);
+# endif
- if (md->curlen >= sizeof(md->buf)) {
- psTraceCrypto("psMd2Final error\n");
- return PS_LIMIT_FAIL;
- }
+ if (md->curlen >= sizeof(md->buf))
+ {
+ psTraceCrypto("psMd2Final error\n");
+ return PS_LIMIT_FAIL;
+ }
- /* pad the message */
- k = 16 - md->curlen;
- for (i = md->curlen; i < 16; i++) {
- md->buf[i] = (unsigned char)k;
- }
+ /* pad the message */
+ k = 16 - md->curlen;
+ for (i = md->curlen; i < 16; i++)
+ {
+ md->buf[i] = (unsigned char) k;
+ }
- /* hash and update */
- md2_compress(md);
- md2_update_chksum(md);
+ /* hash and update */
+ md2_compress(md);
+ md2_update_chksum(md);
- /* hash checksum */
- memcpy(md->buf, md->chksum, 16);
- md2_compress(md);
+ /* hash checksum */
+ memcpy(md->buf, md->chksum, 16);
+ md2_compress(md);
- /* output is lower 16 bytes of X */
- memcpy(hash, md->X, 16);
+ /* output is lower 16 bytes of X */
+ memcpy(hash, md->X, 16);
- memset(md, 0x0, sizeof(psMd2_t));
- return PS_SUCCESS;
+ memset(md, 0x0, sizeof(psMd2_t));
+ return PS_SUCCESS;
}
#endif /* USE_MATRIX_MD2 */
diff --git a/crypto/digest/md4.c b/crypto/digest/md4.c
index ef8833c..67f4b0a 100644
--- a/crypto/digest/md4.c
+++ b/crypto/digest/md4.c
@@ -1,286 +1,298 @@
/**
- * @file md4.c
- * @version $Format:%h%d$
+ * @file md4.c
+ * @version $Format:%h%d$
*
- * MD4 hash implementation.
+ * MD4 hash implementation.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
#ifdef USE_MATRIX_MD4
/******************************************************************************/
-#define S11 3
-#define S12 7
-#define S13 11
-#define S14 19
-#define S21 3
-#define S22 5
-#define S23 9
-#define S24 13
-#define S31 3
-#define S32 9
-#define S33 11
-#define S34 15
+# define S11 3
+# define S12 7
+# define S13 11
+# define S14 19
+# define S21 3
+# define S22 5
+# define S23 9
+# define S24 13
+# define S31 3
+# define S32 9
+# define S33 11
+# define S34 15
/* F, G and H are basic MD4 functions. */
-#define F(x, y, z) (z ^ (x & (y ^ z)))
-#define G(x, y, z) ((x & y) | (z & (x | y)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
+# define F(x, y, z) (z ^ (x & (y ^ z)))
+# define G(x, y, z) ((x & y) | (z & (x | y)))
+# define H(x, y, z) ((x) ^ (y) ^ (z))
/* ROTATE_LEFT rotates x left n bits. */
-#define ROTATE_LEFT(x, n) ROL(x, n)
+# define ROTATE_LEFT(x, n) ROL(x, n)
/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
/* Rotation is separate from addition to prevent recomputation */
-#define FF(a, b, c, d, x, s) { \
- (a) += F ((b), (c), (d)) + (x); \
- (a) = ROTATE_LEFT ((a), (s)); \
- }
-#define GG(a, b, c, d, x, s) { \
- (a) += G ((b), (c), (d)) + (x) + 0x5a827999UL; \
- (a) = ROTATE_LEFT ((a), (s)); \
- }
-#define HH(a, b, c, d, x, s) { \
- (a) += H ((b), (c), (d)) + (x) + 0x6ed9eba1UL; \
- (a) = ROTATE_LEFT ((a), (s)); \
- }
-
-#ifdef USE_BURN_STACK
-static int32 _md4_compress(psMd4_t *md, const unsigned char *buf)
-#else
-static int32 md4_compress(psMd4_t *md, const unsigned char *buf)
-#endif
-{
- uint32 x[16], a, b, c, d, i;
-
- /* copy state */
- a = md->state[0];
- b = md->state[1];
- c = md->state[2];
- d = md->state[3];
-
- /* copy the state into 512-bits into W[0..15] */
- for (i = 0; i < 16; i++) {
- LOAD32L(x[i], buf + (4*i));
- }
-
- /* Round 1 */
- FF (a, b, c, d, x[ 0], S11); /* 1 */
- FF (d, a, b, c, x[ 1], S12); /* 2 */
- FF (c, d, a, b, x[ 2], S13); /* 3 */
- FF (b, c, d, a, x[ 3], S14); /* 4 */
- FF (a, b, c, d, x[ 4], S11); /* 5 */
- FF (d, a, b, c, x[ 5], S12); /* 6 */
- FF (c, d, a, b, x[ 6], S13); /* 7 */
- FF (b, c, d, a, x[ 7], S14); /* 8 */
- FF (a, b, c, d, x[ 8], S11); /* 9 */
- FF (d, a, b, c, x[ 9], S12); /* 10 */
- FF (c, d, a, b, x[10], S13); /* 11 */
- FF (b, c, d, a, x[11], S14); /* 12 */
- FF (a, b, c, d, x[12], S11); /* 13 */
- FF (d, a, b, c, x[13], S12); /* 14 */
- FF (c, d, a, b, x[14], S13); /* 15 */
- FF (b, c, d, a, x[15], S14); /* 16 */
-
- /* Round 2 */
- GG (a, b, c, d, x[ 0], S21); /* 17 */
- GG (d, a, b, c, x[ 4], S22); /* 18 */
- GG (c, d, a, b, x[ 8], S23); /* 19 */
- GG (b, c, d, a, x[12], S24); /* 20 */
- GG (a, b, c, d, x[ 1], S21); /* 21 */
- GG (d, a, b, c, x[ 5], S22); /* 22 */
- GG (c, d, a, b, x[ 9], S23); /* 23 */
- GG (b, c, d, a, x[13], S24); /* 24 */
- GG (a, b, c, d, x[ 2], S21); /* 25 */
- GG (d, a, b, c, x[ 6], S22); /* 26 */
- GG (c, d, a, b, x[10], S23); /* 27 */
- GG (b, c, d, a, x[14], S24); /* 28 */
- GG (a, b, c, d, x[ 3], S21); /* 29 */
- GG (d, a, b, c, x[ 7], S22); /* 30 */
- GG (c, d, a, b, x[11], S23); /* 31 */
- GG (b, c, d, a, x[15], S24); /* 32 */
-
- /* Round 3 */
- HH (a, b, c, d, x[ 0], S31); /* 33 */
- HH (d, a, b, c, x[ 8], S32); /* 34 */
- HH (c, d, a, b, x[ 4], S33); /* 35 */
- HH (b, c, d, a, x[12], S34); /* 36 */
- HH (a, b, c, d, x[ 2], S31); /* 37 */
- HH (d, a, b, c, x[10], S32); /* 38 */
- HH (c, d, a, b, x[ 6], S33); /* 39 */
- HH (b, c, d, a, x[14], S34); /* 40 */
- HH (a, b, c, d, x[ 1], S31); /* 41 */
- HH (d, a, b, c, x[ 9], S32); /* 42 */
- HH (c, d, a, b, x[ 5], S33); /* 43 */
- HH (b, c, d, a, x[13], S34); /* 44 */
- HH (a, b, c, d, x[ 3], S31); /* 45 */
- HH (d, a, b, c, x[11], S32); /* 46 */
- HH (c, d, a, b, x[ 7], S33); /* 47 */
- HH (b, c, d, a, x[15], S34); /* 48 */
-
-
- /* Update our state */
- md->state[0] = md->state[0] + a;
- md->state[1] = md->state[1] + b;
- md->state[2] = md->state[2] + c;
- md->state[3] = md->state[3] + d;
-
- return PS_SUCCESS;
+# define FF(a, b, c, d, x, s) { \
+ (a) += F((b), (c), (d)) + (x); \
+ (a) = ROTATE_LEFT((a), (s)); \
+}
+# define GG(a, b, c, d, x, s) { \
+ (a) += G((b), (c), (d)) + (x) + 0x5a827999UL; \
+ (a) = ROTATE_LEFT((a), (s)); \
+}
+# define HH(a, b, c, d, x, s) { \
+ (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL; \
+ (a) = ROTATE_LEFT((a), (s)); \
}
-#ifdef USE_BURN_STACK
+# ifdef USE_BURN_STACK
+static int32 _md4_compress(psMd4_t *md, const unsigned char *buf)
+# else
+static int32 md4_compress(psMd4_t *md, const unsigned char *buf)
+# endif
+{
+ uint32 x[16], a, b, c, d, i;
+
+ /* copy state */
+ a = md->state[0];
+ b = md->state[1];
+ c = md->state[2];
+ d = md->state[3];
+
+ /* copy the state into 512-bits into W[0..15] */
+ for (i = 0; i < 16; i++)
+ {
+ LOAD32L(x[i], buf + (4 * i));
+ }
+
+ /* Round 1 */
+ FF(a, b, c, d, x[ 0], S11); /* 1 */
+ FF(d, a, b, c, x[ 1], S12); /* 2 */
+ FF(c, d, a, b, x[ 2], S13); /* 3 */
+ FF(b, c, d, a, x[ 3], S14); /* 4 */
+ FF(a, b, c, d, x[ 4], S11); /* 5 */
+ FF(d, a, b, c, x[ 5], S12); /* 6 */
+ FF(c, d, a, b, x[ 6], S13); /* 7 */
+ FF(b, c, d, a, x[ 7], S14); /* 8 */
+ FF(a, b, c, d, x[ 8], S11); /* 9 */
+ FF(d, a, b, c, x[ 9], S12); /* 10 */
+ FF(c, d, a, b, x[10], S13); /* 11 */
+ FF(b, c, d, a, x[11], S14); /* 12 */
+ FF(a, b, c, d, x[12], S11); /* 13 */
+ FF(d, a, b, c, x[13], S12); /* 14 */
+ FF(c, d, a, b, x[14], S13); /* 15 */
+ FF(b, c, d, a, x[15], S14); /* 16 */
+
+ /* Round 2 */
+ GG(a, b, c, d, x[ 0], S21); /* 17 */
+ GG(d, a, b, c, x[ 4], S22); /* 18 */
+ GG(c, d, a, b, x[ 8], S23); /* 19 */
+ GG(b, c, d, a, x[12], S24); /* 20 */
+ GG(a, b, c, d, x[ 1], S21); /* 21 */
+ GG(d, a, b, c, x[ 5], S22); /* 22 */
+ GG(c, d, a, b, x[ 9], S23); /* 23 */
+ GG(b, c, d, a, x[13], S24); /* 24 */
+ GG(a, b, c, d, x[ 2], S21); /* 25 */
+ GG(d, a, b, c, x[ 6], S22); /* 26 */
+ GG(c, d, a, b, x[10], S23); /* 27 */
+ GG(b, c, d, a, x[14], S24); /* 28 */
+ GG(a, b, c, d, x[ 3], S21); /* 29 */
+ GG(d, a, b, c, x[ 7], S22); /* 30 */
+ GG(c, d, a, b, x[11], S23); /* 31 */
+ GG(b, c, d, a, x[15], S24); /* 32 */
+
+ /* Round 3 */
+ HH(a, b, c, d, x[ 0], S31); /* 33 */
+ HH(d, a, b, c, x[ 8], S32); /* 34 */
+ HH(c, d, a, b, x[ 4], S33); /* 35 */
+ HH(b, c, d, a, x[12], S34); /* 36 */
+ HH(a, b, c, d, x[ 2], S31); /* 37 */
+ HH(d, a, b, c, x[10], S32); /* 38 */
+ HH(c, d, a, b, x[ 6], S33); /* 39 */
+ HH(b, c, d, a, x[14], S34); /* 40 */
+ HH(a, b, c, d, x[ 1], S31); /* 41 */
+ HH(d, a, b, c, x[ 9], S32); /* 42 */
+ HH(c, d, a, b, x[ 5], S33); /* 43 */
+ HH(b, c, d, a, x[13], S34); /* 44 */
+ HH(a, b, c, d, x[ 3], S31); /* 45 */
+ HH(d, a, b, c, x[11], S32); /* 46 */
+ HH(c, d, a, b, x[ 7], S33); /* 47 */
+ HH(b, c, d, a, x[15], S34); /* 48 */
+
+
+ /* Update our state */
+ md->state[0] = md->state[0] + a;
+ md->state[1] = md->state[1] + b;
+ md->state[2] = md->state[2] + c;
+ md->state[3] = md->state[3] + d;
+
+ return PS_SUCCESS;
+}
+
+# ifdef USE_BURN_STACK
static int32 md4_compress(psMd4_t *md, const unsigned char *buf)
{
- int32 err;
- err = _md4_compress(md, buf);
- psBurnStack(sizeof(uint32) * 20 + sizeof(int32));
- return err;
-}
-#endif
+ int32 err;
-void psMd4Init(psMd4_t * md)
+ err = _md4_compress(md, buf);
+ psBurnStack(sizeof(uint32) * 20 + sizeof(int32));
+ return err;
+}
+# endif
+
+void psMd4Init(psMd4_t *md)
{
-#ifdef CRYPTO_ASSERT
- psAssert(md != NULL);
-#endif
- md->state[0] = 0x67452301UL;
- md->state[1] = 0xefcdab89UL;
- md->state[2] = 0x98badcfeUL;
- md->state[3] = 0x10325476UL;
- md->curlen = 0;
-#ifdef HAVE_NATIVE_INT64
- md->length = 0;
-#else
- md->lengthHi = 0;
- md->lengthLo = 0;
-#endif /* HAVE_NATIVE_INT64 */
+# ifdef CRYPTO_ASSERT
+ psAssert(md != NULL);
+# endif
+ md->state[0] = 0x67452301UL;
+ md->state[1] = 0xefcdab89UL;
+ md->state[2] = 0x98badcfeUL;
+ md->state[3] = 0x10325476UL;
+ md->curlen = 0;
+# ifdef HAVE_NATIVE_INT64
+ md->length = 0;
+# else
+ md->lengthHi = 0;
+ md->lengthLo = 0;
+# endif /* HAVE_NATIVE_INT64 */
}
-void psMd4Update(psMd4_t * md, const unsigned char *buf, uint32_t len)
+void psMd4Update(psMd4_t *md, const unsigned char *buf, uint32_t len)
{
- uint32 n;
+ uint32 n;
-#ifdef CRYPTO_ASSERT
- psAssert(md != NULL);
- psAssert(buf != NULL);
-#endif
- while (len > 0) {
- n = min(len, (64 - md->curlen));
- memcpy(md->buf + md->curlen, buf, (size_t)n);
- md->curlen += n;
- buf += n;
- len -= n;
+# ifdef CRYPTO_ASSERT
+ psAssert(md != NULL);
+ psAssert(buf != NULL);
+# endif
+ while (len > 0)
+ {
+ n = min(len, (64 - md->curlen));
+ memcpy(md->buf + md->curlen, buf, (size_t) n);
+ md->curlen += n;
+ buf += n;
+ len -= n;
- /* is 64 bytes full? */
- if (md->curlen == 64) {
- md4_compress(md, md->buf);
-#ifdef HAVE_NATIVE_INT64
- md->length += 512;
-#else
- n = (md->lengthLo + 512) & 0xFFFFFFFFL;
- if (n < md->lengthLo) {
- md->lengthHi++;
- }
- md->lengthLo = n;
-#endif /* HAVE_NATIVE_INT64 */
- md->curlen = 0;
- }
- }
+ /* is 64 bytes full? */
+ if (md->curlen == 64)
+ {
+ md4_compress(md, md->buf);
+# ifdef HAVE_NATIVE_INT64
+ md->length += 512;
+# else
+ n = (md->lengthLo + 512) & 0xFFFFFFFFL;
+ if (n < md->lengthLo)
+ {
+ md->lengthHi++;
+ }
+ md->lengthLo = n;
+# endif /* HAVE_NATIVE_INT64 */
+ md->curlen = 0;
+ }
+ }
}
-int32_t psMd4Final(psMd4_t * md, unsigned char *out)
+int32_t psMd4Final(psMd4_t *md, unsigned char *out)
{
- int32 i;
-#ifndef HAVE_NATIVE_INT64
- uint32 n;
-#endif
+ int32 i;
-#ifdef CRYPTO_ASSERT
- psAssert(md != NULL);
- psAssert(out != NULL);
- if (md->curlen >= sizeof(md->buf)) {
- psTraceCrypto("psMd4Final error\n");
- return PS_LIMIT_FAIL;
- }
-#endif
+# ifndef HAVE_NATIVE_INT64
+ uint32 n;
+# endif
- /* increase the length of the message */
-#ifdef HAVE_NATIVE_INT64
- md->length += md->curlen << 3;
-#else
- n = (md->lengthLo + (md->curlen << 3)) & 0xFFFFFFFFL;
- if (n < md->lengthLo) {
- md->lengthHi++;
- }
- md->lengthHi += (md->curlen >> 29);
- md->lengthLo = n;
-#endif /* HAVE_NATIVE_INT64 */
+# ifdef CRYPTO_ASSERT
+ psAssert(md != NULL);
+ psAssert(out != NULL);
+ if (md->curlen >= sizeof(md->buf))
+ {
+ psTraceCrypto("psMd4Final error\n");
+ return PS_LIMIT_FAIL;
+ }
+# endif
- /* append the '1' bit */
- md->buf[md->curlen++] = (unsigned char)0x80;
+ /* increase the length of the message */
+# ifdef HAVE_NATIVE_INT64
+ md->length += md->curlen << 3;
+# else
+ n = (md->lengthLo + (md->curlen << 3)) & 0xFFFFFFFFL;
+ if (n < md->lengthLo)
+ {
+ md->lengthHi++;
+ }
+ md->lengthHi += (md->curlen >> 29);
+ md->lengthLo = n;
+# endif /* HAVE_NATIVE_INT64 */
- /* if the length is currently above 56 bytes we append zeros
- * then compress. Then we can fall back to padding zeros and length
- * encoding like normal.
- */
- if (md->curlen > 56) {
- while (md->curlen < 64) {
- md->buf[md->curlen++] = (unsigned char)0;
- }
- md4_compress(md, md->buf);
- md->curlen = 0;
- }
+ /* append the '1' bit */
+ md->buf[md->curlen++] = (unsigned char) 0x80;
- /* pad upto 56 bytes of zeroes */
- while (md->curlen < 56) {
- md->buf[md->curlen++] = (unsigned char)0;
- }
+ /* if the length is currently above 56 bytes we append zeros
+ * then compress. Then we can fall back to padding zeros and length
+ * encoding like normal.
+ */
+ if (md->curlen > 56)
+ {
+ while (md->curlen < 64)
+ {
+ md->buf[md->curlen++] = (unsigned char) 0;
+ }
+ md4_compress(md, md->buf);
+ md->curlen = 0;
+ }
- /* store length */
-#ifdef HAVE_NATIVE_INT64
- STORE64L(md->length, md->buf+56);
-#else
- STORE32L(md->lengthLo, md->buf+56);
- STORE32L(md->lengthHi, md->buf+60);
-#endif /* HAVE_NATIVE_INT64 */
- md4_compress(md, md->buf);
+ /* pad upto 56 bytes of zeroes */
+ while (md->curlen < 56)
+ {
+ md->buf[md->curlen++] = (unsigned char) 0;
+ }
- /* copy output */
- for (i = 0; i < 4; i++) {
- STORE32L(md->state[i], out+(4*i));
- }
- memset(md, 0x0, sizeof(psMd4_t));
- return PS_SUCCESS;
+ /* store length */
+# ifdef HAVE_NATIVE_INT64
+ STORE64L(md->length, md->buf + 56);
+# else
+ STORE32L(md->lengthLo, md->buf + 56);
+ STORE32L(md->lengthHi, md->buf + 60);
+# endif /* HAVE_NATIVE_INT64 */
+ md4_compress(md, md->buf);
+
+ /* copy output */
+ for (i = 0; i < 4; i++)
+ {
+ STORE32L(md->state[i], out + (4 * i));
+ }
+ memset(md, 0x0, sizeof(psMd4_t));
+ return PS_SUCCESS;
}
#endif /* USE_MATRIX_MD4 */
diff --git a/crypto/digest/md5.c b/crypto/digest/md5.c
index 425ae22..87787aa 100644
--- a/crypto/digest/md5.c
+++ b/crypto/digest/md5.c
@@ -1,38 +1,38 @@
/**
- * @file md5.c
- * @version $Format:%h%d$
+ * @file md5.c
+ * @version $Format:%h%d$
*
- * MD5 hash implementation.
+ * MD5 hash implementation.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
#ifdef USE_MATRIX_MD5
@@ -42,325 +42,341 @@ static void md5_compress(psMd5_t *md5);
int32_t psMd5Init(psMd5_t *md5)
{
-#ifdef CRYPTO_ASSERT
- psAssert(md5 != NULL);
-#endif
- md5->state[0] = 0x67452301UL;
- md5->state[1] = 0xefcdab89UL;
- md5->state[2] = 0x98badcfeUL;
- md5->state[3] = 0x10325476UL;
- md5->curlen = 0;
-#ifdef HAVE_NATIVE_INT64
- md5->length = 0;
-#else
- md5->lengthHi = 0;
- md5->lengthLo = 0;
-#endif /* HAVE_NATIVE_INT64 */
- return PS_SUCCESS;
+# ifdef CRYPTO_ASSERT
+ psAssert(md5 != NULL);
+# endif
+ md5->state[0] = 0x67452301UL;
+ md5->state[1] = 0xefcdab89UL;
+ md5->state[2] = 0x98badcfeUL;
+ md5->state[3] = 0x10325476UL;
+ md5->curlen = 0;
+# ifdef HAVE_NATIVE_INT64
+ md5->length = 0;
+# else
+ md5->lengthHi = 0;
+ md5->lengthLo = 0;
+# endif /* HAVE_NATIVE_INT64 */
+ return PS_SUCCESS;
}
/******************************************************************************/
void psMd5Update(psMd5_t *md5, const unsigned char *buf, uint32_t len)
{
- uint32_t n;
+ uint32_t n;
-#ifdef CRYPTO_ASSERT
- psAssert(md5 != NULL);
- psAssert(buf != NULL);
-#endif
- while (len > 0) {
- n = min(len, (64 - md5->curlen));
- memcpy(md5->buf + md5->curlen, buf, (size_t)n);
- md5->curlen += n;
- buf += n;
- len -= n;
+# ifdef CRYPTO_ASSERT
+ psAssert(md5 != NULL);
+ psAssert(buf != NULL);
+# endif
+ while (len > 0)
+ {
+ n = min(len, (64 - md5->curlen));
+ memcpy(md5->buf + md5->curlen, buf, (size_t) n);
+ md5->curlen += n;
+ buf += n;
+ len -= n;
- /* is 64 bytes full? */
- if (md5->curlen == 64) {
- md5_compress(md5);
-#ifdef HAVE_NATIVE_INT64
- md5->length += 512;
-#else
- n = (md5->lengthLo + 512) & 0xFFFFFFFFL;
- if (n < md5->lengthLo) {
- md5->lengthHi++;
- }
- md5->lengthLo = n;
-#endif /* HAVE_NATIVE_INT64 */
- md5->curlen = 0;
- }
- }
+ /* is 64 bytes full? */
+ if (md5->curlen == 64)
+ {
+ md5_compress(md5);
+# ifdef HAVE_NATIVE_INT64
+ md5->length += 512;
+# else
+ n = (md5->lengthLo + 512) & 0xFFFFFFFFL;
+ if (n < md5->lengthLo)
+ {
+ md5->lengthHi++;
+ }
+ md5->lengthLo = n;
+# endif /* HAVE_NATIVE_INT64 */
+ md5->curlen = 0;
+ }
+ }
}
/******************************************************************************/
/**
- Finalize and clear/free a hash context.
- @param[in,out] md5 Hash Context
- @param[out] hash Pointer to a buffer to receive finalized hash value, or
- NULL to ignore output and just clear hash context.
-*/
+ Finalize and clear/free a hash context.
+ @param[in,out] md5 Hash Context
+ @param[out] hash Pointer to a buffer to receive finalized hash value, or
+ NULL to ignore output and just clear hash context.
+ */
void psMd5Final(psMd5_t *md5, unsigned char hash[MD5_HASHLEN])
{
- int32 i;
-#ifndef HAVE_NATIVE_INT64
- uint32 n;
-#endif
+ int32 i;
-#ifdef CRYPTO_ASSERT
- psAssert(md5);
-#endif
-
- /* If output parameter is NULL, just clear the context */
- if (!hash) {
- goto L_CLEAR;
- }
- /* increase the length of the message */
-#ifdef HAVE_NATIVE_INT64
- md5->length += md5->curlen << 3;
-#else
- n = (md5->lengthLo + (md5->curlen << 3)) & 0xFFFFFFFFL;
- if (n < md5->lengthLo) {
- md5->lengthHi++;
- }
- md5->lengthHi += (md5->curlen >> 29);
- md5->lengthLo = n;
-#endif /* HAVE_NATIVE_INT64 */
+# ifndef HAVE_NATIVE_INT64
+ uint32 n;
+# endif
- /* append the '1' bit */
- md5->buf[md5->curlen++] = 0x80;
+# ifdef CRYPTO_ASSERT
+ psAssert(md5);
+# endif
- /*
- if the length is currently above 56 bytes we append zeros then compress.
- Then we can fall back to padding zeros and length encoding like normal.
- */
- if (md5->curlen > 56) {
- while (md5->curlen < 64) {
- md5->buf[md5->curlen++] = 0x0;
- }
- md5_compress(md5);
- md5->curlen = 0;
- }
- /* pad up to 56 bytes of zeroes */
- while (md5->curlen < 56) {
- md5->buf[md5->curlen++] = 0x0;
- }
- /* store length */
-#ifdef HAVE_NATIVE_INT64
- STORE64L(md5->length, md5->buf+56);
-#else
- STORE32L(md5->lengthLo, md5->buf+56);
- STORE32L(md5->lengthHi, md5->buf+60);
-#endif /* HAVE_NATIVE_INT64 */
- md5_compress(md5);
+ /* If output parameter is NULL, just clear the context */
+ if (!hash)
+ {
+ goto L_CLEAR;
+ }
+ /* increase the length of the message */
+# ifdef HAVE_NATIVE_INT64
+ md5->length += md5->curlen << 3;
+# else
+ n = (md5->lengthLo + (md5->curlen << 3)) & 0xFFFFFFFFL;
+ if (n < md5->lengthLo)
+ {
+ md5->lengthHi++;
+ }
+ md5->lengthHi += (md5->curlen >> 29);
+ md5->lengthLo = n;
+# endif /* HAVE_NATIVE_INT64 */
- /* copy output */
- for (i = 0; i < 4; i++) {
- STORE32L(md5->state[i], hash+(4*i));
- }
+ /* append the '1' bit */
+ md5->buf[md5->curlen++] = 0x80;
+
+ /*
+ if the length is currently above 56 bytes we append zeros then compress.
+ Then we can fall back to padding zeros and length encoding like normal.
+ */
+ if (md5->curlen > 56)
+ {
+ while (md5->curlen < 64)
+ {
+ md5->buf[md5->curlen++] = 0x0;
+ }
+ md5_compress(md5);
+ md5->curlen = 0;
+ }
+ /* pad up to 56 bytes of zeroes */
+ while (md5->curlen < 56)
+ {
+ md5->buf[md5->curlen++] = 0x0;
+ }
+ /* store length */
+# ifdef HAVE_NATIVE_INT64
+ STORE64L(md5->length, md5->buf + 56);
+# else
+ STORE32L(md5->lengthLo, md5->buf + 56);
+ STORE32L(md5->lengthHi, md5->buf + 60);
+# endif /* HAVE_NATIVE_INT64 */
+ md5_compress(md5);
+
+ /* copy output */
+ for (i = 0; i < 4; i++)
+ {
+ STORE32L(md5->state[i], hash + (4 * i));
+ }
L_CLEAR:
- memset(md5, 0x0, sizeof(psMd5_t));
+ memset(md5, 0x0, sizeof(psMd5_t));
}
/******************************************************************************/
-#define F(x,y,z) (z ^ (x & (y ^ z)))
-#define G(x,y,z) (y ^ (z & (y ^ x)))
-#define H(x,y,z) (x^y^z)
-#define I(x,y,z) (y^(x|(~z)))
+# define F(x, y, z) (z ^ (x & (y ^ z)))
+# define G(x, y, z) (y ^ (z & (y ^ x)))
+# define H(x, y, z) (x ^ y ^ z)
+# define I(x, y, z) (y ^ (x | (~z)))
-#ifndef PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE
+# ifndef PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE
-#define FF(a,b,c,d,M,s,t) \
- a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b;
+# define FF(a, b, c, d, M, s, t) \
+ a = (a + F(b, c, d) + M + t); a = ROL(a, s) + b;
-#define GG(a,b,c,d,M,s,t) \
- a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b;
+# define GG(a, b, c, d, M, s, t) \
+ a = (a + G(b, c, d) + M + t); a = ROL(a, s) + b;
-#define HH(a,b,c,d,M,s,t) \
- a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b;
+# define HH(a, b, c, d, M, s, t) \
+ a = (a + H(b, c, d) + M + t); a = ROL(a, s) + b;
-#define II(a,b,c,d,M,s,t) \
- a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b;
+# define II(a, b, c, d, M, s, t) \
+ a = (a + I(b, c, d) + M + t); a = ROL(a, s) + b;
static const unsigned char Worder[64] = {
- 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
- 1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
- 5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
- 0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12,
+ 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,
+ 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9
};
static const unsigned char Rorder[64] = {
- 7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
- 5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
- 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
- 6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
+ 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
+ 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
+ 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
+ 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
};
static const uint32 Korder[] = {
- 0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL,
- 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
- 0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL,
- 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
- 0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL,
- 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
- 0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL,
- 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
- 0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL,
- 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
- 0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL,
- 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
- 0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL,
- 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
- 0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL,
- 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL,
- 0xe1f27f3aUL, 0xf5710fb0UL, 0xada0e5c4UL, 0x98e4c919UL
- };
-#else /* PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE */
+ 0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL,
+ 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
+ 0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL,
+ 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
+ 0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL,
+ 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
+ 0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL,
+ 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
+ 0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL,
+ 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
+ 0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL,
+ 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
+ 0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL,
+ 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
+ 0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL,
+ 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL,
+ 0xe1f27f3aUL, 0xf5710fb0UL, 0xada0e5c4UL, 0x98e4c919UL
+};
+# else /* PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE */
-#define FF(a,b,c,d,M,s,t) \
- a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b;
+# define FF(a, b, c, d, M, s, t) \
+ a = (a + F(b, c, d) + M + t); a = ROL(a, s) + b;
-#define GG(a,b,c,d,M,s,t) \
- a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b;
+# define GG(a, b, c, d, M, s, t) \
+ a = (a + G(b, c, d) + M + t); a = ROL(a, s) + b;
-#define HH(a,b,c,d,M,s,t) \
- a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b;
+# define HH(a, b, c, d, M, s, t) \
+ a = (a + H(b, c, d) + M + t); a = ROL(a, s) + b;
-#define II(a,b,c,d,M,s,t) \
- a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b;
+# define II(a, b, c, d, M, s, t) \
+ a = (a + I(b, c, d) + M + t); a = ROL(a, s) + b;
-#endif /* PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE */
+# endif /* PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE */
-#ifdef USE_BURN_STACK
+# ifdef USE_BURN_STACK
static void _md5_compress(psMd5_t *md5)
-#else
+# else
static void md5_compress(psMd5_t *md5)
-#endif /* USE_BURN_STACK */
+# endif /* USE_BURN_STACK */
{
- uint32 i, W[16], a, b, c, d;
-#ifndef PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE
- uint32 t;
-#endif
-#ifdef CRYPTO_ASSERT
- psAssert(md5 != NULL);
-#endif
+ uint32 i, W[16], a, b, c, d;
- /* copy the state into 512-bits into W[0..15] */
- for (i = 0; i < 16; i++) {
- LOAD32L(W[i], md5->buf + (4*i));
- }
+# ifndef PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE
+ uint32 t;
+# endif
+# ifdef CRYPTO_ASSERT
+ psAssert(md5 != NULL);
+# endif
- /* copy state */
- a = md5->state[0];
- b = md5->state[1];
- c = md5->state[2];
- d = md5->state[3];
+ /* copy the state into 512-bits into W[0..15] */
+ for (i = 0; i < 16; i++)
+ {
+ LOAD32L(W[i], md5->buf + (4 * i));
+ }
-#ifndef PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE
- for (i = 0; i < 16; ++i) {
- FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
- t = d; d = c; c = b; b = a; a = t;
- }
+ /* copy state */
+ a = md5->state[0];
+ b = md5->state[1];
+ c = md5->state[2];
+ d = md5->state[3];
- for (; i < 32; ++i) {
- GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
- t = d; d = c; c = b; b = a; a = t;
- }
+# ifndef PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE
+ for (i = 0; i < 16; ++i)
+ {
+ FF(a, b, c, d, W[Worder[i]], Rorder[i], Korder[i]);
+ t = d; d = c; c = b; b = a; a = t;
+ }
- for (; i < 48; ++i) {
- HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
- t = d; d = c; c = b; b = a; a = t;
- }
+ for (; i < 32; ++i)
+ {
+ GG(a, b, c, d, W[Worder[i]], Rorder[i], Korder[i]);
+ t = d; d = c; c = b; b = a; a = t;
+ }
- for (; i < 64; ++i) {
- II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
- t = d; d = c; c = b; b = a; a = t;
- }
+ for (; i < 48; ++i)
+ {
+ HH(a, b, c, d, W[Worder[i]], Rorder[i], Korder[i]);
+ t = d; d = c; c = b; b = a; a = t;
+ }
-#else /* PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE */
+ for (; i < 64; ++i)
+ {
+ II(a, b, c, d, W[Worder[i]], Rorder[i], Korder[i]);
+ t = d; d = c; c = b; b = a; a = t;
+ }
- FF(a,b,c,d,W[0],7,0xd76aa478UL)
- FF(d,a,b,c,W[1],12,0xe8c7b756UL)
- FF(c,d,a,b,W[2],17,0x242070dbUL)
- FF(b,c,d,a,W[3],22,0xc1bdceeeUL)
- FF(a,b,c,d,W[4],7,0xf57c0fafUL)
- FF(d,a,b,c,W[5],12,0x4787c62aUL)
- FF(c,d,a,b,W[6],17,0xa8304613UL)
- FF(b,c,d,a,W[7],22,0xfd469501UL)
- FF(a,b,c,d,W[8],7,0x698098d8UL)
- FF(d,a,b,c,W[9],12,0x8b44f7afUL)
- FF(c,d,a,b,W[10],17,0xffff5bb1UL)
- FF(b,c,d,a,W[11],22,0x895cd7beUL)
- FF(a,b,c,d,W[12],7,0x6b901122UL)
- FF(d,a,b,c,W[13],12,0xfd987193UL)
- FF(c,d,a,b,W[14],17,0xa679438eUL)
- FF(b,c,d,a,W[15],22,0x49b40821UL)
- GG(a,b,c,d,W[1],5,0xf61e2562UL)
- GG(d,a,b,c,W[6],9,0xc040b340UL)
- GG(c,d,a,b,W[11],14,0x265e5a51UL)
- GG(b,c,d,a,W[0],20,0xe9b6c7aaUL)
- GG(a,b,c,d,W[5],5,0xd62f105dUL)
- GG(d,a,b,c,W[10],9,0x02441453UL)
- GG(c,d,a,b,W[15],14,0xd8a1e681UL)
- GG(b,c,d,a,W[4],20,0xe7d3fbc8UL)
- GG(a,b,c,d,W[9],5,0x21e1cde6UL)
- GG(d,a,b,c,W[14],9,0xc33707d6UL)
- GG(c,d,a,b,W[3],14,0xf4d50d87UL)
- GG(b,c,d,a,W[8],20,0x455a14edUL)
- GG(a,b,c,d,W[13],5,0xa9e3e905UL)
- GG(d,a,b,c,W[2],9,0xfcefa3f8UL)
- GG(c,d,a,b,W[7],14,0x676f02d9UL)
- GG(b,c,d,a,W[12],20,0x8d2a4c8aUL)
- HH(a,b,c,d,W[5],4,0xfffa3942UL)
- HH(d,a,b,c,W[8],11,0x8771f681UL)
- HH(c,d,a,b,W[11],16,0x6d9d6122UL)
- HH(b,c,d,a,W[14],23,0xfde5380cUL)
- HH(a,b,c,d,W[1],4,0xa4beea44UL)
- HH(d,a,b,c,W[4],11,0x4bdecfa9UL)
- HH(c,d,a,b,W[7],16,0xf6bb4b60UL)
- HH(b,c,d,a,W[10],23,0xbebfbc70UL)
- HH(a,b,c,d,W[13],4,0x289b7ec6UL)
- HH(d,a,b,c,W[0],11,0xeaa127faUL)
- HH(c,d,a,b,W[3],16,0xd4ef3085UL)
- HH(b,c,d,a,W[6],23,0x04881d05UL)
- HH(a,b,c,d,W[9],4,0xd9d4d039UL)
- HH(d,a,b,c,W[12],11,0xe6db99e5UL)
- HH(c,d,a,b,W[15],16,0x1fa27cf8UL)
- HH(b,c,d,a,W[2],23,0xc4ac5665UL)
- II(a,b,c,d,W[0],6,0xf4292244UL)
- II(d,a,b,c,W[7],10,0x432aff97UL)
- II(c,d,a,b,W[14],15,0xab9423a7UL)
- II(b,c,d,a,W[5],21,0xfc93a039UL)
- II(a,b,c,d,W[12],6,0x655b59c3UL)
- II(d,a,b,c,W[3],10,0x8f0ccc92UL)
- II(c,d,a,b,W[10],15,0xffeff47dUL)
- II(b,c,d,a,W[1],21,0x85845dd1UL)
- II(a,b,c,d,W[8],6,0x6fa87e4fUL)
- II(d,a,b,c,W[15],10,0xfe2ce6e0UL)
- II(c,d,a,b,W[6],15,0xa3014314UL)
- II(b,c,d,a,W[13],21,0x4e0811a1UL)
- II(a,b,c,d,W[4],6,0xf7537e82UL)
- II(d,a,b,c,W[11],10,0xbd3af235UL)
- II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
- II(b,c,d,a,W[9],21,0xeb86d391UL)
-#endif /* PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE */
+# else /* PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE */
- md5->state[0] = md5->state[0] + a;
- md5->state[1] = md5->state[1] + b;
- md5->state[2] = md5->state[2] + c;
- md5->state[3] = md5->state[3] + d;
+ FF(a, b, c, d, W[0], 7, 0xd76aa478UL)
+ FF(d, a, b, c, W[1], 12, 0xe8c7b756UL)
+ FF(c, d, a, b, W[2], 17, 0x242070dbUL)
+ FF(b, c, d, a, W[3], 22, 0xc1bdceeeUL)
+ FF(a, b, c, d, W[4], 7, 0xf57c0fafUL)
+ FF(d, a, b, c, W[5], 12, 0x4787c62aUL)
+ FF(c, d, a, b, W[6], 17, 0xa8304613UL)
+ FF(b, c, d, a, W[7], 22, 0xfd469501UL)
+ FF(a, b, c, d, W[8], 7, 0x698098d8UL)
+ FF(d, a, b, c, W[9], 12, 0x8b44f7afUL)
+ FF(c, d, a, b, W[10], 17, 0xffff5bb1UL)
+ FF(b, c, d, a, W[11], 22, 0x895cd7beUL)
+ FF(a, b, c, d, W[12], 7, 0x6b901122UL)
+ FF(d, a, b, c, W[13], 12, 0xfd987193UL)
+ FF(c, d, a, b, W[14], 17, 0xa679438eUL)
+ FF(b, c, d, a, W[15], 22, 0x49b40821UL)
+ GG(a, b, c, d, W[1], 5, 0xf61e2562UL)
+ GG(d, a, b, c, W[6], 9, 0xc040b340UL)
+ GG(c, d, a, b, W[11], 14, 0x265e5a51UL)
+ GG(b, c, d, a, W[0], 20, 0xe9b6c7aaUL)
+ GG(a, b, c, d, W[5], 5, 0xd62f105dUL)
+ GG(d, a, b, c, W[10], 9, 0x02441453UL)
+ GG(c, d, a, b, W[15], 14, 0xd8a1e681UL)
+ GG(b, c, d, a, W[4], 20, 0xe7d3fbc8UL)
+ GG(a, b, c, d, W[9], 5, 0x21e1cde6UL)
+ GG(d, a, b, c, W[14], 9, 0xc33707d6UL)
+ GG(c, d, a, b, W[3], 14, 0xf4d50d87UL)
+ GG(b, c, d, a, W[8], 20, 0x455a14edUL)
+ GG(a, b, c, d, W[13], 5, 0xa9e3e905UL)
+ GG(d, a, b, c, W[2], 9, 0xfcefa3f8UL)
+ GG(c, d, a, b, W[7], 14, 0x676f02d9UL)
+ GG(b, c, d, a, W[12], 20, 0x8d2a4c8aUL)
+ HH(a, b, c, d, W[5], 4, 0xfffa3942UL)
+ HH(d, a, b, c, W[8], 11, 0x8771f681UL)
+ HH(c, d, a, b, W[11], 16, 0x6d9d6122UL)
+ HH(b, c, d, a, W[14], 23, 0xfde5380cUL)
+ HH(a, b, c, d, W[1], 4, 0xa4beea44UL)
+ HH(d, a, b, c, W[4], 11, 0x4bdecfa9UL)
+ HH(c, d, a, b, W[7], 16, 0xf6bb4b60UL)
+ HH(b, c, d, a, W[10], 23, 0xbebfbc70UL)
+ HH(a, b, c, d, W[13], 4, 0x289b7ec6UL)
+ HH(d, a, b, c, W[0], 11, 0xeaa127faUL)
+ HH(c, d, a, b, W[3], 16, 0xd4ef3085UL)
+ HH(b, c, d, a, W[6], 23, 0x04881d05UL)
+ HH(a, b, c, d, W[9], 4, 0xd9d4d039UL)
+ HH(d, a, b, c, W[12], 11, 0xe6db99e5UL)
+ HH(c, d, a, b, W[15], 16, 0x1fa27cf8UL)
+ HH(b, c, d, a, W[2], 23, 0xc4ac5665UL)
+ II(a, b, c, d, W[0], 6, 0xf4292244UL)
+ II(d, a, b, c, W[7], 10, 0x432aff97UL)
+ II(c, d, a, b, W[14], 15, 0xab9423a7UL)
+ II(b, c, d, a, W[5], 21, 0xfc93a039UL)
+ II(a, b, c, d, W[12], 6, 0x655b59c3UL)
+ II(d, a, b, c, W[3], 10, 0x8f0ccc92UL)
+ II(c, d, a, b, W[10], 15, 0xffeff47dUL)
+ II(b, c, d, a, W[1], 21, 0x85845dd1UL)
+ II(a, b, c, d, W[8], 6, 0x6fa87e4fUL)
+ II(d, a, b, c, W[15], 10, 0xfe2ce6e0UL)
+ II(c, d, a, b, W[6], 15, 0xa3014314UL)
+ II(b, c, d, a, W[13], 21, 0x4e0811a1UL)
+ II(a, b, c, d, W[4], 6, 0xf7537e82UL)
+ II(d, a, b, c, W[11], 10, 0xbd3af235UL)
+ II(c, d, a, b, W[2], 15, 0x2ad7d2bbUL)
+ II(b, c, d, a, W[9], 21, 0xeb86d391UL)
+# endif /* PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE */
+
+ md5->state[0] = md5->state[0] + a;
+ md5->state[1] = md5->state[1] + b;
+ md5->state[2] = md5->state[2] + c;
+ md5->state[3] = md5->state[3] + d;
}
-#ifdef USE_BURN_STACK
+# ifdef USE_BURN_STACK
static void md5_compress(psMd5_t *md5)
{
- _md5_compress(md5);
- psBurnStack(sizeof(uint32) * 21);
+ _md5_compress(md5);
+ psBurnStack(sizeof(uint32) * 21);
}
-#endif /* USE_BURN_STACK */
+# endif /* USE_BURN_STACK */
-#endif /* USE_MATRIX_MD5 */
+#endif /* USE_MATRIX_MD5 */
/******************************************************************************/
diff --git a/crypto/digest/md5sha1.c b/crypto/digest/md5sha1.c
index bb7c53a..4f7b7e7 100644
--- a/crypto/digest/md5sha1.c
+++ b/crypto/digest/md5sha1.c
@@ -1,93 +1,96 @@
/**
- * @file md5sha1.c
- * @version $Format:%h%d$
+ * @file md5sha1.c
+ * @version $Format:%h%d$
*
- * Combined MD5+SHA1 hash for SSL 3.0 and TLS 1.0/1.1 handshake hash.
+ * Combined MD5+SHA1 hash for SSL 3.0 and TLS 1.0/1.1 handshake hash.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
#ifdef USE_MATRIX_MD5SHA1
-#if !defined(USE_MD5) || !defined(USE_SHA1)
-#error USE_MD5 and USE_SHA1 required
-#endif
+# if !defined(USE_MD5) || !defined(USE_SHA1)
+# error USE_MD5 and USE_SHA1 required
+# endif
/******************************************************************************/
/**
- Maintain MD5 and SHA1 hashes of the same data.
- @note This could be done more optimally, give the use of this in TLS.
- Some state is shared between the two contexts, and some paralellism
- could be used in calculation.
-*/
+ Maintain MD5 and SHA1 hashes of the same data.
+ @note This could be done more optimally, give the use of this in TLS.
+ Some state is shared between the two contexts, and some paralellism
+ could be used in calculation.
+ */
int32_t psMd5Sha1Init(psMd5Sha1_t *md)
{
- int32_t rc;
-#ifdef CRYPTO_ASSERT
- psAssert(md);
-#endif
- if ((rc = psMd5Init(&md->md5)) < 0) {
- return rc;
- }
- if ((rc = psSha1Init(&md->sha1)) < 0) {
- /* We call Final to clear the state, ignoring the output */
- psMd5Final(&md->md5, NULL);
- return rc;
- }
- return PS_SUCCESS;
+ int32_t rc;
+
+# ifdef CRYPTO_ASSERT
+ psAssert(md);
+# endif
+ if ((rc = psMd5Init(&md->md5)) < 0)
+ {
+ return rc;
+ }
+ if ((rc = psSha1Init(&md->sha1)) < 0)
+ {
+ /* We call Final to clear the state, ignoring the output */
+ psMd5Final(&md->md5, NULL);
+ return rc;
+ }
+ return PS_SUCCESS;
}
/**
- Update MD5 and SHA1 hashes of the same data.
-*/
+ Update MD5 and SHA1 hashes of the same data.
+ */
void psMd5Sha1Update(psMd5Sha1_t *md, const unsigned char *buf,
- uint32_t len)
+ uint32_t len)
{
-#ifdef CRYPTO_ASSERT
- psAssert(md && buf);
-#endif
- psMd5Update(&md->md5, buf, len);
- psSha1Update(&md->sha1, buf, len);
+# ifdef CRYPTO_ASSERT
+ psAssert(md && buf);
+# endif
+ psMd5Update(&md->md5, buf, len);
+ psSha1Update(&md->sha1, buf, len);
}
/**
- Finalize output of the combined MD5-SHA1
- The output is 36 bytes, first the 16 bytes MD5 then the 20 bytes SHA1
-*/
+ Finalize output of the combined MD5-SHA1
+ The output is 36 bytes, first the 16 bytes MD5 then the 20 bytes SHA1
+ */
void psMd5Sha1Final(psMd5Sha1_t *md, unsigned char hash[MD5SHA1_HASHLEN])
{
-#ifdef CRYPTO_ASSERT
- psAssert(md && hash);
-#endif
- psMd5Final(&md->md5, hash);
- psSha1Final(&md->sha1, hash + MD5_HASHLEN);
+# ifdef CRYPTO_ASSERT
+ psAssert(md && hash);
+# endif
+ psMd5Final(&md->md5, hash);
+ psSha1Final(&md->sha1, hash + MD5_HASHLEN);
}
#endif /* USE_MATRIX_MD5SHA1 */
diff --git a/crypto/digest/sha1.c b/crypto/digest/sha1.c
index 78c2832..056dfd7 100644
--- a/crypto/digest/sha1.c
+++ b/crypto/digest/sha1.c
@@ -1,269 +1,290 @@
/**
- * @file sha1.c
- * @version $Format:%h%d$
+ * @file sha1.c
+ * @version $Format:%h%d$
*
- * SHA1 hash implementation.
+ * SHA1 hash implementation.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
#ifdef USE_MATRIX_SHA1
/******************************************************************************/
-#define F0(x,y,z) (z ^ (x & (y ^ z)))
-#define F1(x,y,z) (x ^ y ^ z)
-#define F2(x,y,z) ((x & y) | (z & (x | y)))
-#define F3(x,y,z) (x ^ y ^ z)
+# define F0(x, y, z) (z ^ (x & (y ^ z)))
+# define F1(x, y, z) (x ^ y ^ z)
+# define F2(x, y, z) ((x & y) | (z & (x | y)))
+# define F3(x, y, z) (x ^ y ^ z)
-#ifdef USE_BURN_STACK
+# ifdef USE_BURN_STACK
static void _sha1_compress(psSha1_t *sha1)
-#else
+# else
static void sha1_compress(psSha1_t *sha1)
-#endif /* USE_BURN_STACK */
+# endif /* USE_BURN_STACK */
{
- uint32 a,b,c,d,e,W[80],i;
-#ifndef PS_SHA1_IMPROVE_PERF_INCREASE_CODESIZE
- uint32 t;
-#endif
+ uint32 a, b, c, d, e, W[80], i;
- /* copy the state into 512-bits into W[0..15] */
- for (i = 0; i < 16; i++) {
- LOAD32H(W[i], sha1->buf + (4*i));
- }
+# ifndef PS_SHA1_IMPROVE_PERF_INCREASE_CODESIZE
+ uint32 t;
+# endif
- /* copy state */
- a = sha1->state[0];
- b = sha1->state[1];
- c = sha1->state[2];
- d = sha1->state[3];
- e = sha1->state[4];
+ /* copy the state into 512-bits into W[0..15] */
+ for (i = 0; i < 16; i++)
+ {
+ LOAD32H(W[i], sha1->buf + (4 * i));
+ }
- /* expand it */
- for (i = 16; i < 80; i++) {
- W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
- }
+ /* copy state */
+ a = sha1->state[0];
+ b = sha1->state[1];
+ c = sha1->state[2];
+ d = sha1->state[3];
+ e = sha1->state[4];
- /* compress round one */
- #define FF0(a,b,c,d,e,i) e = (ROL(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROL(b, 30);
- #define FF1(a,b,c,d,e,i) e = (ROL(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROL(b, 30);
- #define FF2(a,b,c,d,e,i) e = (ROL(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROL(b, 30);
- #define FF3(a,b,c,d,e,i) e = (ROL(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROL(b, 30);
+ /* expand it */
+ for (i = 16; i < 80; i++)
+ {
+ W[i] = ROL(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
+ }
-#ifndef PS_SHA1_IMPROVE_PERF_INCREASE_CODESIZE
- for (i = 0; i < 20; ) {
- FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
- }
+ /* compress round one */
+# define FF0(a, b, c, d, e, i) e = (ROL(a, 5) + F0(b, c, d) + e + W[i] + 0x5a827999UL); b = ROL(b, 30);
+# define FF1(a, b, c, d, e, i) e = (ROL(a, 5) + F1(b, c, d) + e + W[i] + 0x6ed9eba1UL); b = ROL(b, 30);
+# define FF2(a, b, c, d, e, i) e = (ROL(a, 5) + F2(b, c, d) + e + W[i] + 0x8f1bbcdcUL); b = ROL(b, 30);
+# define FF3(a, b, c, d, e, i) e = (ROL(a, 5) + F3(b, c, d) + e + W[i] + 0xca62c1d6UL); b = ROL(b, 30);
- for (; i < 40; ) {
- FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
- }
+# ifndef PS_SHA1_IMPROVE_PERF_INCREASE_CODESIZE
+ for (i = 0; i < 20; )
+ {
+ FF0(a, b, c, d, e, i++); t = e; e = d; d = c; c = b; b = a; a = t;
+ }
- for (; i < 60; ) {
- FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
- }
+ for (; i < 40; )
+ {
+ FF1(a, b, c, d, e, i++); t = e; e = d; d = c; c = b; b = a; a = t;
+ }
- for (; i < 80; ) {
- FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
- }
-#else /* PS_SHA1_IMPROVE_PERF_INCREASE_CODESIZE */
- for (i = 0; i < 20; ) {
- FF0(a,b,c,d,e,i++);
- FF0(e,a,b,c,d,i++);
- FF0(d,e,a,b,c,i++);
- FF0(c,d,e,a,b,i++);
- FF0(b,c,d,e,a,i++);
- }
+ for (; i < 60; )
+ {
+ FF2(a, b, c, d, e, i++); t = e; e = d; d = c; c = b; b = a; a = t;
+ }
- /* round two */
- for (; i < 40; ) {
- FF1(a,b,c,d,e,i++);
- FF1(e,a,b,c,d,i++);
- FF1(d,e,a,b,c,i++);
- FF1(c,d,e,a,b,i++);
- FF1(b,c,d,e,a,i++);
- }
+ for (; i < 80; )
+ {
+ FF3(a, b, c, d, e, i++); t = e; e = d; d = c; c = b; b = a; a = t;
+ }
+# else /* PS_SHA1_IMPROVE_PERF_INCREASE_CODESIZE */
+ for (i = 0; i < 20; )
+ {
+ FF0(a, b, c, d, e, i++);
+ FF0(e, a, b, c, d, i++);
+ FF0(d, e, a, b, c, i++);
+ FF0(c, d, e, a, b, i++);
+ FF0(b, c, d, e, a, i++);
+ }
- /* round three */
- for (; i < 60; ) {
- FF2(a,b,c,d,e,i++);
- FF2(e,a,b,c,d,i++);
- FF2(d,e,a,b,c,i++);
- FF2(c,d,e,a,b,i++);
- FF2(b,c,d,e,a,i++);
- }
+ /* round two */
+ for (; i < 40; )
+ {
+ FF1(a, b, c, d, e, i++);
+ FF1(e, a, b, c, d, i++);
+ FF1(d, e, a, b, c, i++);
+ FF1(c, d, e, a, b, i++);
+ FF1(b, c, d, e, a, i++);
+ }
- /* round four */
- for (; i < 80; ) {
- FF3(a,b,c,d,e,i++);
- FF3(e,a,b,c,d,i++);
- FF3(d,e,a,b,c,i++);
- FF3(c,d,e,a,b,i++);
- FF3(b,c,d,e,a,i++);
- }
-#endif /* PS_SHA1_IMPROVE_PERF_INCREASE_CODESIZE */
+ /* round three */
+ for (; i < 60; )
+ {
+ FF2(a, b, c, d, e, i++);
+ FF2(e, a, b, c, d, i++);
+ FF2(d, e, a, b, c, i++);
+ FF2(c, d, e, a, b, i++);
+ FF2(b, c, d, e, a, i++);
+ }
- #undef FF0
- #undef FF1
- #undef FF2
- #undef FF3
+ /* round four */
+ for (; i < 80; )
+ {
+ FF3(a, b, c, d, e, i++);
+ FF3(e, a, b, c, d, i++);
+ FF3(d, e, a, b, c, i++);
+ FF3(c, d, e, a, b, i++);
+ FF3(b, c, d, e, a, i++);
+ }
+# endif /* PS_SHA1_IMPROVE_PERF_INCREASE_CODESIZE */
- /* store */
- sha1->state[0] = sha1->state[0] + a;
- sha1->state[1] = sha1->state[1] + b;
- sha1->state[2] = sha1->state[2] + c;
- sha1->state[3] = sha1->state[3] + d;
- sha1->state[4] = sha1->state[4] + e;
+# undef FF0
+# undef FF1
+# undef FF2
+# undef FF3
+
+ /* store */
+ sha1->state[0] = sha1->state[0] + a;
+ sha1->state[1] = sha1->state[1] + b;
+ sha1->state[2] = sha1->state[2] + c;
+ sha1->state[3] = sha1->state[3] + d;
+ sha1->state[4] = sha1->state[4] + e;
}
-#ifdef USE_BURN_STACK
+# ifdef USE_BURN_STACK
static void sha1_compress(psSha1_t *sha1)
{
- _sha1_compress(sha1);
- psBurnStack(sizeof(uint32) * 87);
+ _sha1_compress(sha1);
+ psBurnStack(sizeof(uint32) * 87);
}
-#endif /* USE_BURN_STACK */
+# endif /* USE_BURN_STACK */
/******************************************************************************/
int32_t psSha1Init(psSha1_t *sha1)
{
-#ifdef CRYPTO_ASSERT
- psAssert(sha1 != NULL);
-#endif
- sha1->state[0] = 0x67452301UL;
- sha1->state[1] = 0xefcdab89UL;
- sha1->state[2] = 0x98badcfeUL;
- sha1->state[3] = 0x10325476UL;
- sha1->state[4] = 0xc3d2e1f0UL;
- sha1->curlen = 0;
-#ifdef HAVE_NATIVE_INT64
- sha1->length = 0;
-#else
- sha1->lengthHi = 0;
- sha1->lengthLo = 0;
-#endif /* HAVE_NATIVE_INT64 */
- return PS_SUCCESS;
+# ifdef CRYPTO_ASSERT
+ psAssert(sha1 != NULL);
+# endif
+ sha1->state[0] = 0x67452301UL;
+ sha1->state[1] = 0xefcdab89UL;
+ sha1->state[2] = 0x98badcfeUL;
+ sha1->state[3] = 0x10325476UL;
+ sha1->state[4] = 0xc3d2e1f0UL;
+ sha1->curlen = 0;
+# ifdef HAVE_NATIVE_INT64
+ sha1->length = 0;
+# else
+ sha1->lengthHi = 0;
+ sha1->lengthLo = 0;
+# endif /* HAVE_NATIVE_INT64 */
+ return PS_SUCCESS;
}
void psSha1Update(psSha1_t *sha1, const unsigned char *buf, uint32_t len)
{
- uint32_t n;
+ uint32_t n;
-#ifdef CRYPTO_ASSERT
- psAssert(sha1 != NULL);
- psAssert(buf != NULL);
-#endif
- while (len > 0) {
- n = min(len, (64 - sha1->curlen));
- memcpy(sha1->buf + sha1->curlen, buf, (size_t)n);
- sha1->curlen += n;
- buf += n;
- len -= n;
+# ifdef CRYPTO_ASSERT
+ psAssert(sha1 != NULL);
+ psAssert(buf != NULL);
+# endif
+ while (len > 0)
+ {
+ n = min(len, (64 - sha1->curlen));
+ memcpy(sha1->buf + sha1->curlen, buf, (size_t) n);
+ sha1->curlen += n;
+ buf += n;
+ len -= n;
- /* is 64 bytes full? */
- if (sha1->curlen == 64) {
- sha1_compress(sha1);
-#ifdef HAVE_NATIVE_INT64
- sha1->length += 512;
-#else
- n = (sha1->lengthLo + 512) & 0xFFFFFFFFL;
- if (n < sha1->lengthLo) {
- sha1->lengthHi++;
- }
- sha1->lengthLo = n;
-#endif /* HAVE_NATIVE_INT64 */
- sha1->curlen = 0;
- }
- }
+ /* is 64 bytes full? */
+ if (sha1->curlen == 64)
+ {
+ sha1_compress(sha1);
+# ifdef HAVE_NATIVE_INT64
+ sha1->length += 512;
+# else
+ n = (sha1->lengthLo + 512) & 0xFFFFFFFFL;
+ if (n < sha1->lengthLo)
+ {
+ sha1->lengthHi++;
+ }
+ sha1->lengthLo = n;
+# endif /* HAVE_NATIVE_INT64 */
+ sha1->curlen = 0;
+ }
+ }
}
/******************************************************************************/
void psSha1Final(psSha1_t *sha1, unsigned char hash[SHA1_HASHLEN])
{
- int32 i;
-#ifndef HAVE_NATIVE_INT64
- uint32 n;
-#endif
-#ifdef CRYPTO_ASSERT
- psAssert(sha1 != NULL);
- if (sha1->curlen >= sizeof(sha1->buf) || hash == NULL) {
- psTraceCrypto("psSha1Final error\n");
- return;
- }
-#endif
- /* increase the length of the message */
-#ifdef HAVE_NATIVE_INT64
- sha1->length += sha1->curlen << 3;
-#else
- n = (sha1->lengthLo + (sha1->curlen << 3)) & 0xFFFFFFFFL;
- if (n < sha1->lengthLo) {
- sha1->lengthHi++;
- }
- sha1->lengthHi += (sha1->curlen >> 29);
- sha1->lengthLo = n;
-#endif /* HAVE_NATIVE_INT64 */
+ int32 i;
- /* append the '1' bit */
- sha1->buf[sha1->curlen++] = (unsigned char)0x80;
+# ifndef HAVE_NATIVE_INT64
+ uint32 n;
+# endif
+# ifdef CRYPTO_ASSERT
+ psAssert(sha1 != NULL);
+ if (sha1->curlen >= sizeof(sha1->buf) || hash == NULL)
+ {
+ psTraceCrypto("psSha1Final error\n");
+ return;
+ }
+# endif
+ /* increase the length of the message */
+# ifdef HAVE_NATIVE_INT64
+ sha1->length += sha1->curlen << 3;
+# else
+ n = (sha1->lengthLo + (sha1->curlen << 3)) & 0xFFFFFFFFL;
+ if (n < sha1->lengthLo)
+ {
+ sha1->lengthHi++;
+ }
+ sha1->lengthHi += (sha1->curlen >> 29);
+ sha1->lengthLo = n;
+# endif /* HAVE_NATIVE_INT64 */
- /*
- if the length is currently above 56 bytes we append zeros then compress.
- Then we can fall back to padding zeros and length encoding like normal.
- */
- if (sha1->curlen > 56) {
- while (sha1->curlen < 64) {
- sha1->buf[sha1->curlen++] = (unsigned char)0;
- }
- sha1_compress(sha1);
- sha1->curlen = 0;
- }
- /* pad upto 56 bytes of zeroes */
- while (sha1->curlen < 56) {
- sha1->buf[sha1->curlen++] = (unsigned char)0;
- }
- /* store length */
-#ifdef HAVE_NATIVE_INT64
- STORE64H(sha1->length, sha1->buf+56);
-#else
- STORE32H(sha1->lengthHi, sha1->buf+56);
- STORE32H(sha1->lengthLo, sha1->buf+60);
-#endif /* HAVE_NATIVE_INT64 */
- sha1_compress(sha1);
+ /* append the '1' bit */
+ sha1->buf[sha1->curlen++] = (unsigned char) 0x80;
- /* copy output */
- for (i = 0; i < 5; i++) {
- STORE32H(sha1->state[i], hash+(4*i));
- }
- memset(sha1, 0x0, sizeof(psSha1_t));
+ /*
+ if the length is currently above 56 bytes we append zeros then compress.
+ Then we can fall back to padding zeros and length encoding like normal.
+ */
+ if (sha1->curlen > 56)
+ {
+ while (sha1->curlen < 64)
+ {
+ sha1->buf[sha1->curlen++] = (unsigned char) 0;
+ }
+ sha1_compress(sha1);
+ sha1->curlen = 0;
+ }
+ /* pad upto 56 bytes of zeroes */
+ while (sha1->curlen < 56)
+ {
+ sha1->buf[sha1->curlen++] = (unsigned char) 0;
+ }
+ /* store length */
+# ifdef HAVE_NATIVE_INT64
+ STORE64H(sha1->length, sha1->buf + 56);
+# else
+ STORE32H(sha1->lengthHi, sha1->buf + 56);
+ STORE32H(sha1->lengthLo, sha1->buf + 60);
+# endif /* HAVE_NATIVE_INT64 */
+ sha1_compress(sha1);
+
+ /* copy output */
+ for (i = 0; i < 5; i++)
+ {
+ STORE32H(sha1->state[i], hash + (4 * i));
+ }
+ memset(sha1, 0x0, sizeof(psSha1_t));
}
#endif /* USE_MATRIX_SHA1 */
diff --git a/crypto/digest/sha256.c b/crypto/digest/sha256.c
index 7a0387d..5bda707 100644
--- a/crypto/digest/sha256.c
+++ b/crypto/digest/sha256.c
@@ -1,400 +1,419 @@
/**
- * @file sha256.c
- * @version $Format:%h%d$
+ * @file sha256.c
+ * @version $Format:%h%d$
*
- * SHA256 hash implementation.
+ * SHA256 hash implementation.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
#ifdef USE_MATRIX_SHA256
/******************************************************************************/
-#ifndef PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE
+# ifndef PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE
/* The K array */
static const uint32_t K[64] = {
- 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
- 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
- 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
- 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
- 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
- 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
- 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
- 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
- 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
- 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
- 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
- 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
- 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
+ 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
+ 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
+ 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
+ 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
+ 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
+ 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
+ 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
+ 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
+ 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
+ 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
+ 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
+ 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
+ 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
};
-#endif /* PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE */
+# endif /* PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE */
/* Various logical functions */
-#define Ch(x,y,z) (z ^ (x & (y ^ z)))
-#define Maj(x,y,z) (((x | y) & z) | (x & y))
-#define S(x, n) ROR((x),(n))
-#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
-#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
-#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
-#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
-#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
+# define Ch(x, y, z) (z ^ (x & (y ^ z)))
+# define Maj(x, y, z) (((x | y) & z) | (x & y))
+# define S(x, n) ROR((x), (n))
+# define R(x, n) (((x) & 0xFFFFFFFFUL) >> (n))
+# define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
+# define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
+# define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
+# define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
/*
- compress 512-bits
+ compress 512-bits
*/
-#ifdef USE_BURN_STACK
+# ifdef USE_BURN_STACK
static void _sha256_compress(psSha256_t *sha256, const unsigned char *buf)
-#else
+# else
static void sha256_compress(psSha256_t *sha256, const unsigned char *buf)
-#endif /* CLEAN_STACK */
+# endif /* CLEAN_STACK */
{
- uint32 S[8], W[64], t0, t1;
-#ifndef PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE
- uint32 t;
-#endif /* PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE */
- int32 i;
+ uint32 S[8], W[64], t0, t1;
+# ifndef PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE
+ uint32 t;
+# endif /* PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE */
+ int32 i;
- /* copy state into S */
- for (i = 0; i < 8; i++) {
- S[i] = sha256->state[i];
- }
+ /* copy state into S */
+ for (i = 0; i < 8; i++)
+ {
+ S[i] = sha256->state[i];
+ }
- /* copy the state into 512-bits into W[0..15] */
- for (i = 0; i < 16; i++) {
- LOAD32H(W[i], buf + (4*i));
- }
+ /* copy the state into 512-bits into W[0..15] */
+ for (i = 0; i < 16; i++)
+ {
+ LOAD32H(W[i], buf + (4 * i));
+ }
- /* fill W[16..63] */
- for (i = 16; i < 64; i++) {
- W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
- }
+ /* fill W[16..63] */
+ for (i = 16; i < 64; i++)
+ {
+ W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
+ }
- /* Compress */
-#ifndef PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE
-#define RND(a,b,c,d,e,f,g,h,i) \
- t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
- t1 = Sigma0(a) + Maj(a, b, c); \
- d += t0; \
- h = t0 + t1;
+ /* Compress */
+# ifndef PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE
+# define RND(a, b, c, d, e, f, g, h, i) \
+ t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
+ t1 = Sigma0(a) + Maj(a, b, c); \
+ d += t0; \
+ h = t0 + t1;
- for (i = 0; i < 64; ++i) {
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
- t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
- S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
- }
-#else /* PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE */
-#define RND(a,b,c,d,e,f,g,h,i,ki) \
- t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
- t1 = Sigma0(a) + Maj(a, b, c); \
- d += t0; \
- h = t0 + t1;
+ for (i = 0; i < 64; ++i)
+ {
+ RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i);
+ t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
+ S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
+ }
+# else /* PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE */
+# define RND(a, b, c, d, e, f, g, h, i, ki) \
+ t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
+ t1 = Sigma0(a) + Maj(a, b, c); \
+ d += t0; \
+ h = t0 + t1;
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
+ RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 0, 0x428a2f98);
+ RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 1, 0x71374491);
+ RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 2, 0xb5c0fbcf);
+ RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 3, 0xe9b5dba5);
+ RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 4, 0x3956c25b);
+ RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 5, 0x59f111f1);
+ RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 6, 0x923f82a4);
+ RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 7, 0xab1c5ed5);
+ RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 8, 0xd807aa98);
+ RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 9, 0x12835b01);
+ RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 10, 0x243185be);
+ RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 11, 0x550c7dc3);
+ RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 12, 0x72be5d74);
+ RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 13, 0x80deb1fe);
+ RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 14, 0x9bdc06a7);
+ RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 15, 0xc19bf174);
+ RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 16, 0xe49b69c1);
+ RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 17, 0xefbe4786);
+ RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 18, 0x0fc19dc6);
+ RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 19, 0x240ca1cc);
+ RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 20, 0x2de92c6f);
+ RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 21, 0x4a7484aa);
+ RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 22, 0x5cb0a9dc);
+ RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 23, 0x76f988da);
+ RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 24, 0x983e5152);
+ RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 25, 0xa831c66d);
+ RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 26, 0xb00327c8);
+ RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 27, 0xbf597fc7);
+ RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 28, 0xc6e00bf3);
+ RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 29, 0xd5a79147);
+ RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 30, 0x06ca6351);
+ RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 31, 0x14292967);
+ RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 32, 0x27b70a85);
+ RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 33, 0x2e1b2138);
+ RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 34, 0x4d2c6dfc);
+ RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 35, 0x53380d13);
+ RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 36, 0x650a7354);
+ RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 37, 0x766a0abb);
+ RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 38, 0x81c2c92e);
+ RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 39, 0x92722c85);
+ RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 40, 0xa2bfe8a1);
+ RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 41, 0xa81a664b);
+ RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 42, 0xc24b8b70);
+ RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 43, 0xc76c51a3);
+ RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 44, 0xd192e819);
+ RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 45, 0xd6990624);
+ RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 46, 0xf40e3585);
+ RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 47, 0x106aa070);
+ RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 48, 0x19a4c116);
+ RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 49, 0x1e376c08);
+ RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 50, 0x2748774c);
+ RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 51, 0x34b0bcb5);
+ RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 52, 0x391c0cb3);
+ RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 53, 0x4ed8aa4a);
+ RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 54, 0x5b9cca4f);
+ RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 55, 0x682e6ff3);
+ RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], 56, 0x748f82ee);
+ RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], 57, 0x78a5636f);
+ RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], 58, 0x84c87814);
+ RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], 59, 0x8cc70208);
+ RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], 60, 0x90befffa);
+ RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], 61, 0xa4506ceb);
+ RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], 62, 0xbef9a3f7);
+ RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], 63, 0xc67178f2);
-#undef RND
+# undef RND
-#endif /* PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE */
+# endif /* PS_SHA256_IMPROVE_PERF_INCREASE_CODESIZE */
- /* feedback */
- for (i = 0; i < 8; i++) {
- sha256->state[i] = sha256->state[i] + S[i];
- }
+ /* feedback */
+ for (i = 0; i < 8; i++)
+ {
+ sha256->state[i] = sha256->state[i] + S[i];
+ }
}
-#ifdef USE_BURN_STACK
+# ifdef USE_BURN_STACK
static void sha256_compress(psSha256_t *sha256, const unsigned char *buf)
{
- _sha256_compress(sha256, buf);
- psBurnStack(sizeof(uint32) * 74);
+ _sha256_compress(sha256, buf);
+ psBurnStack(sizeof(uint32) * 74);
}
-#endif /* USE_BURN_STACK */
+# endif /* USE_BURN_STACK */
/******************************************************************************/
int32_t psSha256Init(psSha256_t *sha256)
{
-#ifdef CRYPTO_ASSERT
- psAssert(sha256 != NULL);
-#endif
- sha256->curlen = 0;
- sha256->state[0] = 0x6A09E667UL;
- sha256->state[1] = 0xBB67AE85UL;
- sha256->state[2] = 0x3C6EF372UL;
- sha256->state[3] = 0xA54FF53AUL;
- sha256->state[4] = 0x510E527FUL;
- sha256->state[5] = 0x9B05688CUL;
- sha256->state[6] = 0x1F83D9ABUL;
- sha256->state[7] = 0x5BE0CD19UL;
-#ifdef HAVE_NATIVE_INT64
- sha256->length = 0;
-#else
- sha256->lengthHi = 0;
- sha256->lengthLo = 0;
-#endif /* HAVE_NATIVE_INT64 */
- return PS_SUCCESS;
+# ifdef CRYPTO_ASSERT
+ psAssert(sha256 != NULL);
+# endif
+ sha256->curlen = 0;
+ sha256->state[0] = 0x6A09E667UL;
+ sha256->state[1] = 0xBB67AE85UL;
+ sha256->state[2] = 0x3C6EF372UL;
+ sha256->state[3] = 0xA54FF53AUL;
+ sha256->state[4] = 0x510E527FUL;
+ sha256->state[5] = 0x9B05688CUL;
+ sha256->state[6] = 0x1F83D9ABUL;
+ sha256->state[7] = 0x5BE0CD19UL;
+# ifdef HAVE_NATIVE_INT64
+ sha256->length = 0;
+# else
+ sha256->lengthHi = 0;
+ sha256->lengthLo = 0;
+# endif /* HAVE_NATIVE_INT64 */
+ return PS_SUCCESS;
}
/******************************************************************************/
void psSha256Update(psSha256_t *sha256, const unsigned char *buf, uint32_t len)
{
- uint32 n;
+ uint32 n;
-#ifdef CRYPTO_ASSERT
- psAssert(sha256 != NULL);
- psAssert(buf != NULL);
-#endif
+# ifdef CRYPTO_ASSERT
+ psAssert(sha256 != NULL);
+ psAssert(buf != NULL);
+# endif
- while (len > 0) {
- if (sha256->curlen == 0 && len >= 64) {
- sha256_compress(sha256, (unsigned char *)buf);
-#ifdef HAVE_NATIVE_INT64
- sha256->length += 512;
-#else
- n = (sha256->lengthLo + 512) & 0xFFFFFFFFL;
- if (n < sha256->lengthLo) {
- sha256->lengthHi++;
- }
- sha256->lengthLo = n;
-#endif /* HAVE_NATIVE_INT64 */
- buf += 64;
- len -= 64;
- } else {
- n = min(len, (64 - sha256->curlen));
- memcpy(sha256->buf + sha256->curlen, buf, (size_t)n);
- sha256->curlen += n;
- buf += n;
- len -= n;
+ while (len > 0)
+ {
+ if (sha256->curlen == 0 && len >= 64)
+ {
+ sha256_compress(sha256, (unsigned char *) buf);
+# ifdef HAVE_NATIVE_INT64
+ sha256->length += 512;
+# else
+ n = (sha256->lengthLo + 512) & 0xFFFFFFFFL;
+ if (n < sha256->lengthLo)
+ {
+ sha256->lengthHi++;
+ }
+ sha256->lengthLo = n;
+# endif /* HAVE_NATIVE_INT64 */
+ buf += 64;
+ len -= 64;
+ }
+ else
+ {
+ n = min(len, (64 - sha256->curlen));
+ memcpy(sha256->buf + sha256->curlen, buf, (size_t) n);
+ sha256->curlen += n;
+ buf += n;
+ len -= n;
- if (sha256->curlen == 64) {
- sha256_compress (sha256, sha256->buf);
-#ifdef HAVE_NATIVE_INT64
- sha256->length += 512;
-#else
- n = (sha256->lengthLo + 512) & 0xFFFFFFFFL;
- if (n < sha256->lengthLo) {
- sha256->lengthHi++;
- }
- sha256->lengthLo = n;
-#endif /* HAVE_NATIVE_INT64 */
- sha256->curlen = 0;
- }
- }
- }
- return;
+ if (sha256->curlen == 64)
+ {
+ sha256_compress(sha256, sha256->buf);
+# ifdef HAVE_NATIVE_INT64
+ sha256->length += 512;
+# else
+ n = (sha256->lengthLo + 512) & 0xFFFFFFFFL;
+ if (n < sha256->lengthLo)
+ {
+ sha256->lengthHi++;
+ }
+ sha256->lengthLo = n;
+# endif /* HAVE_NATIVE_INT64 */
+ sha256->curlen = 0;
+ }
+ }
+ }
+ return;
}
/******************************************************************************/
void psSha256Final(psSha256_t *sha256, unsigned char hash[SHA256_HASHLEN])
{
- int32 i;
-#ifndef HAVE_NATIVE_INT64
- uint32 n;
-#endif
+ int32 i;
-#ifdef CRYPTO_ASSERT
- psAssert(sha256 != NULL);
- psAssert(hash != NULL);
- if (sha256->curlen >= sizeof(sha256->buf)) {
- psTraceCrypto("psSha256Final error\n");
- return;
- }
-#endif
+# ifndef HAVE_NATIVE_INT64
+ uint32 n;
+# endif
- /* increase the length of the message */
-#ifdef HAVE_NATIVE_INT64
- sha256->length += sha256->curlen << 3;
-#else
- n = (sha256->lengthLo + (sha256->curlen << 3)) & 0xFFFFFFFFL;
- if (n < sha256->lengthLo) {
- sha256->lengthHi++;
- }
- sha256->lengthHi += (sha256->curlen >> 29);
- sha256->lengthLo = n;
-#endif /* HAVE_NATIVE_INT64 */
+# ifdef CRYPTO_ASSERT
+ psAssert(sha256 != NULL);
+ psAssert(hash != NULL);
+ if (sha256->curlen >= sizeof(sha256->buf))
+ {
+ psTraceCrypto("psSha256Final error\n");
+ return;
+ }
+# endif
- /* append the '1' bit */
- sha256->buf[sha256->curlen++] = (unsigned char)0x80;
+ /* increase the length of the message */
+# ifdef HAVE_NATIVE_INT64
+ sha256->length += sha256->curlen << 3;
+# else
+ n = (sha256->lengthLo + (sha256->curlen << 3)) & 0xFFFFFFFFL;
+ if (n < sha256->lengthLo)
+ {
+ sha256->lengthHi++;
+ }
+ sha256->lengthHi += (sha256->curlen >> 29);
+ sha256->lengthLo = n;
+# endif /* HAVE_NATIVE_INT64 */
+
+ /* append the '1' bit */
+ sha256->buf[sha256->curlen++] = (unsigned char) 0x80;
/*
- if the length is currently above 56 bytes we append zeros then compress.
- Then we can fall back to padding zeros and length encoding like normal.
-*/
- if (sha256->curlen > 56) {
- while (sha256->curlen < 64) {
- sha256->buf[sha256->curlen++] = (unsigned char)0;
- }
- sha256_compress(sha256, sha256->buf);
- sha256->curlen = 0;
- }
- /* pad upto 56 bytes of zeroes */
- while (sha256->curlen < 56) {
- sha256->buf[sha256->curlen++] = (unsigned char)0;
- }
+ if the length is currently above 56 bytes we append zeros then compress.
+ Then we can fall back to padding zeros and length encoding like normal.
+ */
+ if (sha256->curlen > 56)
+ {
+ while (sha256->curlen < 64)
+ {
+ sha256->buf[sha256->curlen++] = (unsigned char) 0;
+ }
+ sha256_compress(sha256, sha256->buf);
+ sha256->curlen = 0;
+ }
+ /* pad upto 56 bytes of zeroes */
+ while (sha256->curlen < 56)
+ {
+ sha256->buf[sha256->curlen++] = (unsigned char) 0;
+ }
- /* store length */
-#ifdef HAVE_NATIVE_INT64
- STORE64H(sha256->length, sha256->buf+56);
-#else
- STORE32H(sha256->lengthHi, sha256->buf+56);
- STORE32H(sha256->lengthLo, sha256->buf+60);
-#endif /* HAVE_NATIVE_INT64 */
- sha256_compress(sha256, sha256->buf);
+ /* store length */
+# ifdef HAVE_NATIVE_INT64
+ STORE64H(sha256->length, sha256->buf + 56);
+# else
+ STORE32H(sha256->lengthHi, sha256->buf + 56);
+ STORE32H(sha256->lengthLo, sha256->buf + 60);
+# endif /* HAVE_NATIVE_INT64 */
+ sha256_compress(sha256, sha256->buf);
- /* copy output */
- for (i = 0; i < 8; i++) {
- STORE32H(sha256->state[i], hash+(4*i));
- }
- memset(sha256, 0x0, sizeof(psSha256_t));
+ /* copy output */
+ for (i = 0; i < 8; i++)
+ {
+ STORE32H(sha256->state[i], hash + (4 * i));
+ }
+ memset(sha256, 0x0, sizeof(psSha256_t));
}
-#ifdef USE_SHA224
+# ifdef USE_SHA224
/******************************************************************************/
void psSha224Init(psSha256_t *sha256)
{
-#ifdef CRYPTO_ASSERT
- psAssert(sha256 != NULL);
-#endif
+# ifdef CRYPTO_ASSERT
+ psAssert(sha256 != NULL);
+# endif
- sha256->curlen = 0;
-#ifdef HAVE_NATIVE_INT64
- sha256->length = 0;
-#else
- sha256->lengthHi = 0;
- sha256->lengthLo = 0;
-#endif /* HAVE_NATIVE_INT64 */
- sha256->state[0] = 0xc1059ed8UL;
- sha256->state[1] = 0x367cd507UL;
- sha256->state[2] = 0x3070dd17UL;
- sha256->state[3] = 0xf70e5939UL;
- sha256->state[4] = 0xffc00b31UL;
- sha256->state[5] = 0x68581511UL;
- sha256->state[6] = 0x64f98fa7UL;
- sha256->state[7] = 0xbefa4fa4UL;
+ sha256->curlen = 0;
+# ifdef HAVE_NATIVE_INT64
+ sha256->length = 0;
+# else
+ sha256->lengthHi = 0;
+ sha256->lengthLo = 0;
+# endif /* HAVE_NATIVE_INT64 */
+ sha256->state[0] = 0xc1059ed8UL;
+ sha256->state[1] = 0x367cd507UL;
+ sha256->state[2] = 0x3070dd17UL;
+ sha256->state[3] = 0xf70e5939UL;
+ sha256->state[4] = 0xffc00b31UL;
+ sha256->state[5] = 0x68581511UL;
+ sha256->state[6] = 0x64f98fa7UL;
+ sha256->state[7] = 0xbefa4fa4UL;
}
/******************************************************************************/
void psSha224Update(psSha256_t *sha256, const unsigned char *buf, uint32 len)
{
- psSha256Update(sha256, buf, len);
+ psSha256Update(sha256, buf, len);
}
/******************************************************************************/
void psSha224Final(psSha256_t *sha256, unsigned char out[SHA224_HASHLEN])
{
- unsigned char buf[SHA224_HASHLEN];
+ unsigned char buf[SHA224_HASHLEN];
-#ifdef CRYPTO_ASSERT
- psAssert(sha256 != NULL);
- psAssert(out != NULL);
-#endif
- psSha256Final(sha256, buf);
- memcpy(out, buf, SHA224_HASH_SIZE);
-#ifdef USE_BURN_STACK
- psBurnStack(sizeof(buf));
-#endif
+# ifdef CRYPTO_ASSERT
+ psAssert(sha256 != NULL);
+ psAssert(out != NULL);
+# endif
+ psSha256Final(sha256, buf);
+ memcpy(out, buf, SHA224_HASH_SIZE);
+# ifdef USE_BURN_STACK
+ psBurnStack(sizeof(buf));
+# endif
}
-#endif /* USE_SHA224 */
+# endif /* USE_SHA224 */
-#endif /* USE_MATRIX_SHA256 */
+#endif /* USE_MATRIX_SHA256 */
/******************************************************************************/
diff --git a/crypto/digest/sha512.c b/crypto/digest/sha512.c
index f4a51d3..995192d 100644
--- a/crypto/digest/sha512.c
+++ b/crypto/digest/sha512.c
@@ -1,336 +1,354 @@
/**
- * @file sha512.c
- * @version $Format:%h%d$
+ * @file sha512.c
+ * @version $Format:%h%d$
*
- * SHA256 hash implementation.
+ * SHA256 hash implementation.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
#if defined(USE_MATRIX_SHA384) || defined(USE_MATRIX_SHA512)
-#ifndef HAVE_NATIVE_INT64
-#error Must have NATIVE_INT64 support
-#endif
+# ifndef HAVE_NATIVE_INT64
+# error Must have NATIVE_INT64 support
+# endif
/******************************************************************************/
/* the K array */
static const uint64_t K[80] = {
-CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd),
-CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
-CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019),
-CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
-CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe),
-CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
-CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1),
-CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
-CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3),
-CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
-CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483),
-CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
-CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210),
-CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
-CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725),
-CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
-CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926),
-CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
-CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8),
-CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
-CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
-CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
-CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910),
-CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
-CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53),
-CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
-CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb),
-CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
-CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60),
-CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
-CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9),
-CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
-CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207),
-CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
-CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6),
-CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
-CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493),
-CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
-CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a),
-CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
+ CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd),
+ CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
+ CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019),
+ CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
+ CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe),
+ CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
+ CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1),
+ CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
+ CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3),
+ CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
+ CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483),
+ CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
+ CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210),
+ CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
+ CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725),
+ CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
+ CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926),
+ CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
+ CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8),
+ CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
+ CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
+ CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
+ CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910),
+ CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
+ CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53),
+ CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
+ CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb),
+ CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
+ CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60),
+ CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
+ CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9),
+ CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
+ CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207),
+ CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
+ CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6),
+ CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
+ CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493),
+ CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
+ CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a),
+ CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
};
/* Various logical functions */
-#define Ch(x,y,z) (z ^ (x & (y ^ z)))
-#define Maj(x,y,z) (((x | y) & z) | (x & y))
-#define S(x, n) ROR64c(x, n)
-#define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((uint64)n))
-#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
-#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
-#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
-#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
+# define Ch(x, y, z) (z ^ (x & (y ^ z)))
+# define Maj(x, y, z) (((x | y) & z) | (x & y))
+# define S(x, n) ROR64c(x, n)
+# define R(x, n) (((x) & CONST64(0xFFFFFFFFFFFFFFFF)) >> ((uint64) n))
+# define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
+# define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
+# define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
+# define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
/* compress 1024-bits */
-#ifdef USE_BURN_STACK
+# ifdef USE_BURN_STACK
static void _sha512_compress(psSha512_t *sha512, const unsigned char *buf)
-#else
+# else
static void sha512_compress(psSha512_t *sha512, const unsigned char *buf)
-#endif
+# endif
{
- uint64 S[8], W[80], t0, t1;
- int i;
+ uint64 S[8], W[80], t0, t1;
+ int i;
- /* copy state into S */
- for (i = 0; i < 8; i++) {
- S[i] = sha512->state[i];
- }
+ /* copy state into S */
+ for (i = 0; i < 8; i++)
+ {
+ S[i] = sha512->state[i];
+ }
- /* copy the state into 1024-bits into W[0..15] */
- for (i = 0; i < 16; i++) {
- LOAD64H(W[i], buf + (8*i));
- }
+ /* copy the state into 1024-bits into W[0..15] */
+ for (i = 0; i < 16; i++)
+ {
+ LOAD64H(W[i], buf + (8 * i));
+ }
- /* fill W[16..79] */
- for (i = 16; i < 80; i++) {
- W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
- }
+ /* fill W[16..79] */
+ for (i = 16; i < 80; i++)
+ {
+ W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
+ }
- /* Compress */
-#ifndef PS_SHA512_IMPROVE_PERF_INCREASE_CODESIZE
- for (i = 0; i < 80; i++) {
- t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
- t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
- S[7] = S[6];
- S[6] = S[5];
- S[5] = S[4];
- S[4] = S[3] + t0;
- S[3] = S[2];
- S[2] = S[1];
- S[1] = S[0];
- S[0] = t0 + t1;
- }
-#else
-#define RND(a,b,c,d,e,f,g,h,i) \
- t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
- t1 = Sigma0(a) + Maj(a, b, c); \
- d += t0; \
- h = t0 + t1;
+ /* Compress */
+# ifndef PS_SHA512_IMPROVE_PERF_INCREASE_CODESIZE
+ for (i = 0; i < 80; i++)
+ {
+ t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
+ t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
+ S[7] = S[6];
+ S[6] = S[5];
+ S[5] = S[4];
+ S[4] = S[3] + t0;
+ S[3] = S[2];
+ S[2] = S[1];
+ S[1] = S[0];
+ S[0] = t0 + t1;
+ }
+# else
+# define RND(a, b, c, d, e, f, g, h, i) \
+ t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
+ t1 = Sigma0(a) + Maj(a, b, c); \
+ d += t0; \
+ h = t0 + t1;
- for (i = 0; i < 80; i += 8) {
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
- }
-#endif /* PS_SHA512_IMPROVE_PERF_INCREASE_CODESIZE */
+ for (i = 0; i < 80; i += 8)
+ {
+ RND(S[0], S[1], S[2], S[3], S[4], S[5], S[6], S[7], i + 0);
+ RND(S[7], S[0], S[1], S[2], S[3], S[4], S[5], S[6], i + 1);
+ RND(S[6], S[7], S[0], S[1], S[2], S[3], S[4], S[5], i + 2);
+ RND(S[5], S[6], S[7], S[0], S[1], S[2], S[3], S[4], i + 3);
+ RND(S[4], S[5], S[6], S[7], S[0], S[1], S[2], S[3], i + 4);
+ RND(S[3], S[4], S[5], S[6], S[7], S[0], S[1], S[2], i + 5);
+ RND(S[2], S[3], S[4], S[5], S[6], S[7], S[0], S[1], i + 6);
+ RND(S[1], S[2], S[3], S[4], S[5], S[6], S[7], S[0], i + 7);
+ }
+# endif /* PS_SHA512_IMPROVE_PERF_INCREASE_CODESIZE */
- /* feedback */
- for (i = 0; i < 8; i++) {
- sha512->state[i] = sha512->state[i] + S[i];
- }
+ /* feedback */
+ for (i = 0; i < 8; i++)
+ {
+ sha512->state[i] = sha512->state[i] + S[i];
+ }
}
/* compress 1024-bits */
-#ifdef USE_BURN_STACK
+# ifdef USE_BURN_STACK
static void sha512_compress(psSha512_t *sha512, const unsigned char *buf)
{
- _sha512_compress(sha512, buf);
- psBurnStack(sizeof(uint64) * 90 + sizeof(int));
+ _sha512_compress(sha512, buf);
+ psBurnStack(sizeof(uint64) * 90 + sizeof(int));
}
-#endif
+# endif
/******************************************************************************/
-#ifdef USE_MATRIX_SHA512
+# ifdef USE_MATRIX_SHA512
/* Other 512 functions are used by 384 */
int32_t psSha512Init(psSha512_t *sha512)
{
-#ifdef CRYPTO_ASSERT
- psAssert(sha512 != NULL);
-#endif
- sha512->curlen = 0;
- sha512->length = 0;
- sha512->state[0] = CONST64(0x6a09e667f3bcc908);
- sha512->state[1] = CONST64(0xbb67ae8584caa73b);
- sha512->state[2] = CONST64(0x3c6ef372fe94f82b);
- sha512->state[3] = CONST64(0xa54ff53a5f1d36f1);
- sha512->state[4] = CONST64(0x510e527fade682d1);
- sha512->state[5] = CONST64(0x9b05688c2b3e6c1f);
- sha512->state[6] = CONST64(0x1f83d9abfb41bd6b);
- sha512->state[7] = CONST64(0x5be0cd19137e2179);
- return PS_SUCCESS;
+# ifdef CRYPTO_ASSERT
+ psAssert(sha512 != NULL);
+# endif
+ sha512->curlen = 0;
+ sha512->length = 0;
+ sha512->state[0] = CONST64(0x6a09e667f3bcc908);
+ sha512->state[1] = CONST64(0xbb67ae8584caa73b);
+ sha512->state[2] = CONST64(0x3c6ef372fe94f82b);
+ sha512->state[3] = CONST64(0xa54ff53a5f1d36f1);
+ sha512->state[4] = CONST64(0x510e527fade682d1);
+ sha512->state[5] = CONST64(0x9b05688c2b3e6c1f);
+ sha512->state[6] = CONST64(0x1f83d9abfb41bd6b);
+ sha512->state[7] = CONST64(0x5be0cd19137e2179);
+ return PS_SUCCESS;
}
-#endif
+# endif
/******************************************************************************/
-#ifdef USE_MATRIX_SHA512
+# ifdef USE_MATRIX_SHA512
void psSha512Update(psSha512_t *sha512, const unsigned char *buf, uint32_t len)
-#else
+# else
static void psSha512Update(psSha512_t *sha512, const unsigned char *buf, uint32_t len)
-#endif
+# endif
{
- uint32_t n;
+ uint32_t n;
- psAssert(sha512 != NULL);
- psAssert(buf != NULL);
+ psAssert(sha512 != NULL);
+ psAssert(buf != NULL);
- while (len > 0) {
- if (sha512->curlen == 0 && len >= 128) {
- sha512_compress(sha512, (unsigned char *)buf);
- sha512->length += 1024;
- buf += 128;
- len -= 128;
- } else {
- n = min(len, (128 - sha512->curlen));
- memcpy(sha512->buf + sha512->curlen, buf, (size_t)n);
- sha512->curlen += n;
- buf += n;
- len -= n;
+ while (len > 0)
+ {
+ if (sha512->curlen == 0 && len >= 128)
+ {
+ sha512_compress(sha512, (unsigned char *) buf);
+ sha512->length += 1024;
+ buf += 128;
+ len -= 128;
+ }
+ else
+ {
+ n = min(len, (128 - sha512->curlen));
+ memcpy(sha512->buf + sha512->curlen, buf, (size_t) n);
+ sha512->curlen += n;
+ buf += n;
+ len -= n;
- if (sha512->curlen == 128) {
- sha512_compress (sha512, sha512->buf);
- sha512->length += 1024;
- sha512->curlen = 0;
- }
- }
- }
+ if (sha512->curlen == 128)
+ {
+ sha512_compress(sha512, sha512->buf);
+ sha512->length += 1024;
+ sha512->curlen = 0;
+ }
+ }
+ }
}
/******************************************************************************/
-#ifdef USE_MATRIX_SHA512
+# ifdef USE_MATRIX_SHA512
void psSha512Final(psSha512_t *sha512, unsigned char out[SHA512_HASHLEN])
-#else
+# else
static void psSha512Final(psSha512_t *sha512, unsigned char out[SHA512_HASHLEN])
-#endif
+# endif
{
- int i;
-#ifdef CRYPTO_ASSERT
- psAssert(sha512 != NULL);
- psAssert(out != NULL);
- if (sha512->curlen >= sizeof(sha512->buf)) {
- return;
- }
-#endif
- /* increase the length of the message */
- sha512->length += sha512->curlen * CONST64(8);
+ int i;
- /* append the '1' bit */
- sha512->buf[sha512->curlen++] = (unsigned char)0x80;
+# ifdef CRYPTO_ASSERT
+ psAssert(sha512 != NULL);
+ psAssert(out != NULL);
+ if (sha512->curlen >= sizeof(sha512->buf))
+ {
+ return;
+ }
+# endif
+ /* increase the length of the message */
+ sha512->length += sha512->curlen * CONST64(8);
- /* if the length is currently above 112 bytes we append zeros
- * then compress. Then we can fall back to padding zeros and length
- * encoding like normal.
- */
- if (sha512->curlen > 112) {
- while (sha512->curlen < 128) {
- sha512->buf[sha512->curlen++] = (unsigned char)0;
- }
- sha512_compress(sha512, sha512->buf);
- sha512->curlen = 0;
- }
+ /* append the '1' bit */
+ sha512->buf[sha512->curlen++] = (unsigned char) 0x80;
- /* pad upto 120 bytes of zeroes
- @note from 112 to 120 is the 64 MSB of the length.
- We assume that you won't hash > 2^64 bits of data... :-)
- */
- while (sha512->curlen < 120) {
- sha512->buf[sha512->curlen++] = (unsigned char)0;
- }
+ /* if the length is currently above 112 bytes we append zeros
+ * then compress. Then we can fall back to padding zeros and length
+ * encoding like normal.
+ */
+ if (sha512->curlen > 112)
+ {
+ while (sha512->curlen < 128)
+ {
+ sha512->buf[sha512->curlen++] = (unsigned char) 0;
+ }
+ sha512_compress(sha512, sha512->buf);
+ sha512->curlen = 0;
+ }
- /* store length */
- STORE64H(sha512->length, sha512->buf+120);
- sha512_compress(sha512, sha512->buf);
+ /* pad upto 120 bytes of zeroes
+ @note from 112 to 120 is the 64 MSB of the length.
+ We assume that you won't hash > 2^64 bits of data... :-)
+ */
+ while (sha512->curlen < 120)
+ {
+ sha512->buf[sha512->curlen++] = (unsigned char) 0;
+ }
- /* copy output */
- for (i = 0; i < 8; i++) {
- STORE64H(sha512->state[i], out+(8*i));
- }
-#ifdef USE_BURN_STACK
- psBurnStack(sizeof(psSha512_t));
-#endif
+ /* store length */
+ STORE64H(sha512->length, sha512->buf + 120);
+ sha512_compress(sha512, sha512->buf);
+
+ /* copy output */
+ for (i = 0; i < 8; i++)
+ {
+ STORE64H(sha512->state[i], out + (8 * i));
+ }
+# ifdef USE_BURN_STACK
+ psBurnStack(sizeof(psSha512_t));
+# endif
}
-#ifdef USE_MATRIX_SHA384
+# ifdef USE_MATRIX_SHA384
/******************************************************************************/
int32_t psSha384Init(psSha384_t *sha384)
{
-#ifdef CRYPTO_ASSERT
- psAssert(sha384 != NULL);
-#endif
- sha384->curlen = 0;
- sha384->length = 0;
- sha384->state[0] = CONST64(0xcbbb9d5dc1059ed8);
- sha384->state[1] = CONST64(0x629a292a367cd507);
- sha384->state[2] = CONST64(0x9159015a3070dd17);
- sha384->state[3] = CONST64(0x152fecd8f70e5939);
- sha384->state[4] = CONST64(0x67332667ffc00b31);
- sha384->state[5] = CONST64(0x8eb44a8768581511);
- sha384->state[6] = CONST64(0xdb0c2e0d64f98fa7);
- sha384->state[7] = CONST64(0x47b5481dbefa4fa4);
- return PS_SUCCESS;
+# ifdef CRYPTO_ASSERT
+ psAssert(sha384 != NULL);
+# endif
+ sha384->curlen = 0;
+ sha384->length = 0;
+ sha384->state[0] = CONST64(0xcbbb9d5dc1059ed8);
+ sha384->state[1] = CONST64(0x629a292a367cd507);
+ sha384->state[2] = CONST64(0x9159015a3070dd17);
+ sha384->state[3] = CONST64(0x152fecd8f70e5939);
+ sha384->state[4] = CONST64(0x67332667ffc00b31);
+ sha384->state[5] = CONST64(0x8eb44a8768581511);
+ sha384->state[6] = CONST64(0xdb0c2e0d64f98fa7);
+ sha384->state[7] = CONST64(0x47b5481dbefa4fa4);
+ return PS_SUCCESS;
}
/******************************************************************************/
void psSha384Update(psSha384_t *sha384, const unsigned char *buf, uint32_t len)
{
- psSha512Update(sha384, buf, len);
+ psSha512Update(sha384, buf, len);
}
/******************************************************************************/
void psSha384Final(psSha384_t *sha384, unsigned char out[SHA384_HASHLEN])
{
- unsigned char buf[SHA512_HASHLEN];
+ unsigned char buf[SHA512_HASHLEN];
-#ifdef CRYPTO_ASSERT
- psAssert(sha384 != NULL);
- psAssert(out != NULL);
- if (sha384->curlen >= sizeof(sha384->buf)) {
- return;
- }
-#endif
- psSha512Final(sha384, buf);
- memcpy(out, buf, SHA384_HASHLEN);
-#ifdef USE_BURN_STACK
- psBurnStack(sizeof(buf));
-#endif
+# ifdef CRYPTO_ASSERT
+ psAssert(sha384 != NULL);
+ psAssert(out != NULL);
+ if (sha384->curlen >= sizeof(sha384->buf))
+ {
+ return;
+ }
+# endif
+ psSha512Final(sha384, buf);
+ memcpy(out, buf, SHA384_HASHLEN);
+# ifdef USE_BURN_STACK
+ psBurnStack(sizeof(buf));
+# endif
}
-#endif /* USE_MATRIX_SHA384 */
+# endif /* USE_MATRIX_SHA384 */
-#endif /* USE_MATRIX_SHA384 || USE_MATRIX_SHA512 */
+#endif /* USE_MATRIX_SHA384 || USE_MATRIX_SHA512 */
/******************************************************************************/
diff --git a/crypto/keyformat/asn1.c b/crypto/keyformat/asn1.c
index 069a0a8..af54118 100644
--- a/crypto/keyformat/asn1.c
+++ b/crypto/keyformat/asn1.c
@@ -1,511 +1,629 @@
/**
- * @file asn1.c
- * @version $Format:%h%d$
+ * @file asn1.c
+ * @version $Format:%h%d$
*
- * DER/BER coding.
+ * DER/BER coding.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
/******************************************************************************/
/*
- On success, p will be updated to point to first character of value and
- len will contain number of bytes in value.
+ On success, p will be updated to point to first character of value and
+ len will contain number of bytes in value.
- Indefinite length formats return ASN_UNKNOWN_LEN and *len will simply
- be updated with the overall remaining length
-*/
-int32_t getAsnLength(const unsigned char **pp, uint16_t size, uint16_t *len)
+ Indefinite length formats return ASN_UNKNOWN_LEN and *len will simply
+ be updated with the overall remaining length
+ */
+int32_t getAsnLength(const unsigned char **pp, psSize_t size, psSize_t *len)
{
- uint32_t len32 = 0;
- int32_t rc;
+ uint32_t len32 = 0;
+ int32_t rc;
- if ((rc = getAsnLength32(pp, size, &len32, 0)) < 0) {
- return rc;
- }
- *len = (uint16_t)(len32 & 0xFFFF);
- return PS_SUCCESS;
+ if ((rc = getAsnLength32(pp, size, &len32, 0)) < 0)
+ {
+ return rc;
+ }
+ *len = (uint16_t) (len32 & 0xFFFF);
+ return PS_SUCCESS;
}
int32_t getAsnLength32(const unsigned char **pp, uint32_t size, uint32_t *len,
- uint32_t indefinite)
+ uint32_t indefinite)
{
- const unsigned char *c, *end;
- uint32_t l;
+ const unsigned char *c, *end;
+ uint32_t l;
- c = *pp;
- end = c + size;
- *len = 0;
- if (end - c < 1) {
- psTraceCrypto("getAsnLength called on empty buffer\n");
- return PS_LIMIT_FAIL;
- }
+ c = *pp;
+ end = c + size;
+ *len = 0;
+ if (end - c < 1)
+ {
+ psTraceCrypto("getAsnLength called on empty buffer\n");
+ return PS_LIMIT_FAIL;
+ }
/*
- If the high bit is set, the lower 7 bits represent the number of
- bytes that follow defining length
- If the high bit is not set, the lower 7 represent the actual length
-*/
- l = *c & 0x7F;
- if (*c & 0x80) {
- /* Point c at first length byte */
- c++;
- /* Ensure we have that many bytes left in the buffer. */
- if (end - c < l) {
- psTraceCrypto("Malformed stream in getAsnLength\n");
- return PS_LIMIT_FAIL;
- }
+ If the high bit is set, the lower 7 bits represent the number of
+ bytes that follow defining length
+ If the high bit is not set, the lower 7 represent the actual length
+ */
+ l = *c & 0x7F;
+ if (*c & 0x80)
+ {
+ /* Point c at first length byte */
+ c++;
+ /* Ensure we have that many bytes left in the buffer. */
+ if (end - c < l)
+ {
+ psTraceCrypto("Malformed stream in getAsnLength\n");
+ return PS_LIMIT_FAIL;
+ }
- switch (l) {
- case 4:
- l = *c << 24; c++;
- l |= *c << 16; c++;
- l |= *c << 8; c++;
- l |= *c; c++;
- break;
- case 3:
- l = *c << 16; c++;
- l |= *c << 8; c++;
- l |= *c; c++;
- break;
- case 2:
- l = *c << 8; c++;
- l |= *c; c++;
- break;
- case 1:
- l = *c; c++;
- break;
+ switch (l)
+ {
+ case 4:
+ l = *c << 24; c++;
+ l |= *c << 16; c++;
+ l |= *c << 8; c++;
+ l |= *c; c++;
+ break;
+ case 3:
+ l = *c << 16; c++;
+ l |= *c << 8; c++;
+ l |= *c; c++;
+ break;
+ case 2:
+ l = *c << 8; c++;
+ l |= *c; c++;
+ break;
+ case 1:
+ l = *c; c++;
+ break;
/*
- If the length byte has high bit only set, it's an indefinite
- length. If allowed, return the number of bytes remaining in buffer.
-*/
- case 0:
- if (indefinite) {
- *pp = c;
- *len = size - 1;
- return ASN_UNKNOWN_LEN;
- }
- return PS_LIMIT_FAIL;
+ If the length byte has high bit only set, it's an indefinite
+ length. If allowed, return the number of bytes remaining in buffer.
+ */
+ case 0:
+ if (indefinite)
+ {
+ *pp = c;
+ *len = size - 1;
+ return ASN_UNKNOWN_LEN;
+ }
+ return PS_LIMIT_FAIL;
- /* Make sure there aren't more than 4 bytes of length specifier. */
- default:
- psTraceCrypto("Malformed stream in getAsnLength\n");
- return PS_LIMIT_FAIL;
- }
- } else {
- c++;
- }
+ /* Make sure there aren't more than 4 bytes of length specifier. */
+ default:
+ psTraceCrypto("Malformed stream in getAsnLength\n");
+ return PS_LIMIT_FAIL;
+ }
+ }
+ else
+ {
+ c++;
+ }
- /* Stream parsers will not require the entire data to be present */
- if (!indefinite && (end - c < l)) {
- psTraceCrypto("getAsnLength longer than remaining buffer.\n");
- return PS_LIMIT_FAIL;
- }
+ /* Stream parsers will not require the entire data to be present */
+ if (!indefinite && (end - c < l))
+ {
+ psTraceCrypto("getAsnLength longer than remaining buffer.\n");
+ return PS_LIMIT_FAIL;
+ }
- *pp = c;
- *len = l;
- return PS_SUCCESS;
+ *pp = c;
+ *len = l;
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- Callback to extract a sequence length from the DER stream
- Verifies that 'len' bytes are >= 'seqlen'
- Move pp to the first character in the sequence
-*/
+ Callback to extract a sequence length from the DER stream
+ Verifies that 'len' bytes are >= 'seqlen'
+ Move pp to the first character in the sequence
+ */
/* #define DISABLE_STRICT_ASN_LENGTH_CHECK */
int32_t getAsnSequence32(const unsigned char **pp, uint32_t size,
- uint32_t *len, uint32_t indefinite)
+ uint32_t *len, uint32_t indefinite)
{
- const unsigned char *p = *pp;
- int32_t rc;
+ const unsigned char *p = *pp;
+ int32_t rc;
- rc = PS_PARSE_FAIL;
- if (size < 1 || *(p++) != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
- ((rc = getAsnLength32(&p, size - 1, len, indefinite)) < 0)) {
- psTraceCrypto("ASN getSequence failed\n");
- return rc;
- }
+ rc = PS_PARSE_FAIL;
+ if (size < 1 || *(p++) != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
+ ((rc = getAsnLength32(&p, size - 1, len, indefinite)) < 0))
+ {
+ psTraceCrypto("ASN getSequence failed\n");
+ return rc;
+ }
#ifndef DISABLE_STRICT_ASN_LENGTH_CHECK
- /* The (p - *pp) is taking the length encoding bytes into account */
- if (!indefinite && (size - ((uint32_t)(p - *pp))) < *len) {
- /* It isn't cool but some encodings have an outer length layer that
- is smaller than the inner. Normally you'll want this check but if
- you're hitting this case, you could try skipping it to see if there
- is an error in the encoding */
- psTraceCrypto("ASN_SEQUENCE parse found length greater than total\n");
- psTraceCrypto("Could try enabling DISABLE_STRICT_ASN_LENGTH_CHECK\n");
- return PS_LIMIT_FAIL;
- }
+ /* The (p - *pp) is taking the length encoding bytes into account */
+ if (!indefinite && (size - ((uint32_t) (p - *pp))) < *len)
+ {
+ /* It isn't cool but some encodings have an outer length layer that
+ is smaller than the inner. Normally you'll want this check but if
+ you're hitting this case, you could try skipping it to see if there
+ is an error in the encoding */
+ psTraceCrypto("ASN_SEQUENCE parse found length greater than total\n");
+ psTraceCrypto("Could try enabling DISABLE_STRICT_ASN_LENGTH_CHECK\n");
+ return PS_LIMIT_FAIL;
+ }
#endif
- *pp = p;
- return rc;
+ *pp = p;
+ return rc;
}
-int32_t getAsnSequence(const unsigned char **pp, uint16_t size, uint16_t *len)
+int32_t getAsnSequence(const unsigned char **pp, psSize_t size, psSize_t *len)
{
- uint32_t len32 = 0;
- int32_t rc;
+ uint32_t len32 = 0;
+ int32_t rc;
- if ((rc = getAsnSequence32(pp, size, &len32, 0)) < 0) {
- return rc;
- }
- *len = (uint16_t)(len32 & 0xFFFF);
- return PS_SUCCESS;
+ if ((rc = getAsnSequence32(pp, size, &len32, 0)) < 0)
+ {
+ return rc;
+ }
+ *len = (uint16_t) (len32 & 0xFFFF);
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- Extract a set length from the DER stream. Will also test that there
- is enough data available to hold it all. Returns LIMIT_FAIL if not.
-*/
+ Extract a set length from the DER stream. Will also test that there
+ is enough data available to hold it all. Returns LIMIT_FAIL if not.
+ */
int32_t getAsnSet32(const unsigned char **pp, uint32_t size, uint32_t *len,
- uint32_t indefinite)
+ uint32_t indefinite)
{
- const unsigned char *p = *pp;
- int32_t rc;
+ const unsigned char *p = *pp;
+ int32_t rc;
- rc = PS_PARSE_FAIL;
- if (size < 1 || *(p++) != (ASN_SET | ASN_CONSTRUCTED) ||
- ((rc = getAsnLength32(&p, size - 1, len, indefinite)) < 0)) {
- psTraceCrypto("ASN getSet failed\n");
- return rc;
- }
- /* Account for overhead needed to get the length */
- if (size < ((uint32_t)(p - *pp) + *len)) {
- return PS_LIMIT_FAIL;
- }
- *pp = p;
- return rc;
+ rc = PS_PARSE_FAIL;
+ if (size < 1 || *(p++) != (ASN_SET | ASN_CONSTRUCTED) ||
+ ((rc = getAsnLength32(&p, size - 1, len, indefinite)) < 0))
+ {
+ psTraceCrypto("ASN getSet failed\n");
+ return rc;
+ }
+ /* Account for overhead needed to get the length */
+ if (size < ((uint32_t) (p - *pp) + *len))
+ {
+ return PS_LIMIT_FAIL;
+ }
+ *pp = p;
+ return rc;
}
-int32_t getAsnSet(const unsigned char **pp, uint16_t size, uint16_t *len)
+int32_t getAsnSet(const unsigned char **pp, psSize_t size, psSize_t *len)
{
- uint32_t len32 = 0;
- int32_t rc;
+ uint32_t len32 = 0;
+ int32_t rc;
- if ((rc = getAsnSet32(pp, size, &len32, 0)) < 0) {
- return rc;
- }
- *len = (uint16_t)(len32 & 0xFFFF);
- return PS_SUCCESS;
+ if ((rc = getAsnSet32(pp, size, &len32, 0)) < 0)
+ {
+ return rc;
+ }
+ *len = (uint16_t) (len32 & 0xFFFF);
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- Get an enumerated value
-*/
+ Get an enumerated value
+ */
int32_t getAsnEnumerated(const unsigned char **pp, uint32_t len, int32_t *val)
{
- const unsigned char *p = *pp, *end;
- uint32_t ui, slen;
- int32_t rc;
- uint32_t vlen;
+ const unsigned char *p = *pp, *end;
+ uint32_t ui, slen;
+ int32_t rc;
+ uint32_t vlen;
- rc = PS_PARSE_FAIL;
- end = p + len;
- if (len < 1 || *(p++) != ASN_ENUMERATED ||
- ((rc = getAsnLength32(&p, len - 1, &vlen, 0)) < 0)) {
- psTraceCrypto("ASN getInteger failed from the start\n");
- return rc;
- }
+ rc = PS_PARSE_FAIL;
+ end = p + len;
+ if (len < 1 || *(p++) != ASN_ENUMERATED ||
+ ((rc = getAsnLength32(&p, len - 1, &vlen, 0)) < 0))
+ {
+ psTraceCrypto("ASN getInteger failed from the start\n");
+ return rc;
+ }
/*
- This check prevents us from having a big positive integer where the
- high bit is set because it will be encoded as 5 bytes (with leading
- blank byte). If that is required, a getUnsigned routine should be used
-*/
- if (vlen > sizeof(int32_t) || (uint32_t)(end - p) < vlen) {
- psTraceCrypto("ASN getInteger had limit failure\n");
- return PS_LIMIT_FAIL;
- }
- ui = 0;
+ This check prevents us from having a big positive integer where the
+ high bit is set because it will be encoded as 5 bytes (with leading
+ blank byte). If that is required, a getUnsigned routine should be used
+ */
+ if (vlen > sizeof(int32_t) || (uint32_t) (end - p) < vlen)
+ {
+ psTraceCrypto("ASN getInteger had limit failure\n");
+ return PS_LIMIT_FAIL;
+ }
+ ui = 0;
/*
- If high bit is set, it's a negative integer, so perform the two's compliment
- Otherwise do a standard big endian read (most likely case for RSA)
-*/
- if (*p & 0x80) {
- while (vlen > 0) {
- ui = (ui << 8) | (*p ^ 0xFF);
- p++;
- vlen--;
- }
- slen = ui;
- slen++;
- slen = -slen;
- *val = slen;
- } else {
- while (vlen > 0) {
- ui = (ui << 8) | *p;
- p++;
- vlen--;
- }
- *val = ui;
- }
- *pp = p;
- return PS_SUCCESS;
+ If high bit is set, it's a negative integer, so perform the two's compliment
+ Otherwise do a standard big endian read (most likely case for RSA)
+ */
+ if (*p & 0x80)
+ {
+ while (vlen > 0)
+ {
+ ui = (ui << 8) | (*p ^ 0xFF);
+ p++;
+ vlen--;
+ }
+ slen = ui;
+ slen++;
+ slen = -slen;
+ *val = slen;
+ }
+ else
+ {
+ while (vlen > 0)
+ {
+ ui = (ui << 8) | *p;
+ p++;
+ vlen--;
+ }
+ *val = ui;
+ }
+ *pp = p;
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- Get an integer
-*/
+ Get an integer
+ */
int32_t getAsnInteger(const unsigned char **pp, uint32_t len, int32_t *val)
{
- const unsigned char *p = *pp, *end;
- uint32_t ui, slen;
- int32_t rc;
- uint32_t vlen;
+ const unsigned char *p = *pp, *end;
+ uint32_t ui, slen;
+ int32_t rc;
+ uint32_t vlen;
- rc = PS_PARSE_FAIL;
- end = p + len;
- if (len < 1 || *(p++) != ASN_INTEGER ||
- ((rc = getAsnLength32(&p, len - 1, &vlen, 0)) < 0)) {
- psTraceCrypto("ASN getInteger failed from the start\n");
- return rc;
- }
+ rc = PS_PARSE_FAIL;
+ end = p + len;
+ if (len < 1 || *(p++) != ASN_INTEGER ||
+ ((rc = getAsnLength32(&p, len - 1, &vlen, 0)) < 0))
+ {
+ psTraceCrypto("ASN getInteger failed from the start\n");
+ return rc;
+ }
/*
- This check prevents us from having a big positive integer where the
- high bit is set because it will be encoded as 5 bytes (with leading
- blank byte). If that is required, a getUnsigned routine should be used
-*/
- if (vlen > sizeof(int32_t) || (uint32_t)(end - p) < vlen) {
- psTraceCrypto("ASN getInteger had limit failure\n");
- return PS_LIMIT_FAIL;
- }
- ui = 0;
+ This check prevents us from having a big positive integer where the
+ high bit is set because it will be encoded as 5 bytes (with leading
+ blank byte). If that is required, a getUnsigned routine should be used
+ */
+ if (vlen > sizeof(int32_t) || (uint32_t) (end - p) < vlen)
+ {
+ psTraceCrypto("ASN getInteger had limit failure\n");
+ return PS_LIMIT_FAIL;
+ }
+ ui = 0;
/*
- If high bit is set, it's a negative integer, so perform the two's compliment
- Otherwise do a standard big endian read (most likely case for RSA)
-*/
- if (*p & 0x80) {
- while (vlen > 0) {
- ui = (ui << 8) | (*p ^ 0xFF);
- p++;
- vlen--;
- }
- slen = ui;
- slen++;
- slen = -slen;
- *val = slen;
- } else {
- while (vlen > 0) {
- ui = (ui << 8) | *p;
- p++;
- vlen--;
- }
- *val = ui;
- }
- *pp = p;
- return PS_SUCCESS;
+ If high bit is set, it's a negative integer, so perform the two's compliment
+ Otherwise do a standard big endian read (most likely case for RSA)
+ */
+ if (*p & 0x80)
+ {
+ while (vlen > 0)
+ {
+ ui = (ui << 8) | (*p ^ 0xFF);
+ p++;
+ vlen--;
+ }
+ slen = ui;
+ slen++;
+ slen = -slen;
+ *val = slen;
+ }
+ else
+ {
+ while (vlen > 0)
+ {
+ ui = (ui << 8) | *p;
+ p++;
+ vlen--;
+ }
+ *val = ui;
+ }
+ *pp = p;
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- Implementation specific OID parser
-*/
+ Implementation specific OID parser
+ */
int32_t getAsnAlgorithmIdentifier(const unsigned char **pp, uint32_t len,
- int32_t *oi, uint16_t *paramLen)
+ int32_t *oi, psSize_t *paramLen)
{
- const unsigned char *p = *pp, *end;
- int32_t rc;
- uint32_t llen;
+ const unsigned char *p = *pp, *end;
+ int32_t rc;
+ uint32_t llen;
- rc = PS_PARSE_FAIL;
- end = p + len;
- if (len < 1 || (rc = getAsnSequence32(&p, len, &llen, 0)) < 0) {
- psTraceCrypto("getAsnAlgorithmIdentifier failed on inital parse\n");
- return rc;
- }
- /* Always checks for parameter length */
- if (end - p < 1) {
- return PS_LIMIT_FAIL;
- }
- rc = getAsnOID(&p, llen, oi, 1, paramLen);
- *pp = p;
- return rc;
+ rc = PS_PARSE_FAIL;
+ end = p + len;
+ if (len < 1 || (rc = getAsnSequence32(&p, len, &llen, 0)) < 0)
+ {
+ psTraceCrypto("getAsnAlgorithmIdentifier failed on inital parse\n");
+ return rc;
+ }
+ /* Always checks for parameter length */
+ if (end - p < 1)
+ {
+ return PS_LIMIT_FAIL;
+ }
+ rc = getAsnOID(&p, llen, oi, 1, paramLen);
+ *pp = p;
+ return rc;
+}
+
+/******************************************************************************/
+/**
+ Parse ASN.1 DER encoded OBJECT bytes into an OID array.
+ @param[in] der Pointer to start of OBJECT encoding.
+ @param[in] derlen Number of bytes pointed to by 'der'.
+ @param[out] oid Caller allocated array to receive OID, of
+ at least MAX_OID_LEN elements.
+ @return Number of OID elements written to 'oid', 0 on error.
+ */
+uint8_t asnParseOid(const unsigned char *der, psSize_t derlen,
+ uint32_t oid[MAX_OID_LEN])
+{
+ const unsigned char *end;
+ uint8_t n, sanity;
+
+ if (derlen < 1)
+ {
+ return 0;
+ }
+ end = der + derlen;
+ /* First two OID elements are single octet, base 40 for some reason */
+ oid[0] = *der / 40;
+ oid[1] = *der % 40;
+ der++;
+ /* Zero the remainder of OID and leave n == 2 */
+ for (n = MAX_OID_LEN - 1; n > 2; n--)
+ {
+ oid[n] = 0;
+ }
+ while (der < end && n < MAX_OID_LEN)
+ {
+ /* If the high bit is 0, it's short form variable length quantity */
+ if (!(*der & 0x80))
+ {
+ oid[n++] = *der++;
+ }
+ else
+ {
+ sanity = 0;
+ /* Long form. High bit means another (lower) 7 bits following */
+ do
+ {
+ oid[n] |= (*der & 0x7F);
+ /* A clear high bit ends the byte sequence */
+ if (!(*der & 0x80))
+ {
+ break;
+ }
+ /* Allow a maximum of 4 x 7 bit shifts (28 bits) */
+ if (++sanity > 4)
+ {
+ return 0;
+ }
+ /* Make room for the next 7 bits */
+ oid[n] <<= 7;
+ der++;
+ }
+ while (der < end);
+ der++;
+ n++;
+ }
+ }
+ if (n < MAX_OID_LEN)
+ {
+ return n;
+ }
+ return 0;
}
#ifndef MATRIXSSL_NO_OID_DATABASE
+
/* This function uses computed OID sums as base and adds suitable number of
multiples of OID_COLLISION in case the first known oid with the number
did not match. If function fails the value will be >= 32768. */
static void checkAsnOidDatabase(int32_t *oi,
- const unsigned char *oidStart,
- uint32_t oidLen)
+ const unsigned char *oidStart,
+ uint32_t oidLen)
{
- /* The values are represented as C strings, although they contain
- binary data. Therefore the type needs to be const char *. */
- const char *oid_hex;
- /* Loop until match is found, adding multiples of OID_COLLISION in case of
- mismatch. */
- while(1) {
- switch(*oi) {
- case OID_SHA1_ALG: oid_hex = OID_SHA1_ALG_HEX; break;
- case OID_SHA256_ALG: oid_hex = OID_SHA256_ALG_HEX; break;
- case OID_SHA384_ALG: oid_hex = OID_SHA384_ALG_HEX; break;
- case OID_SHA512_ALG: oid_hex = OID_SHA512_ALG_HEX; break;
- case OID_MD2_ALG: oid_hex = OID_MD2_ALG_HEX; break;
- case OID_MD5_ALG: oid_hex = OID_MD5_ALG_HEX; break;
- case OID_MD2_RSA_SIG: oid_hex = OID_MD2_RSA_SIG_HEX; break;
- case OID_MD5_RSA_SIG: oid_hex = OID_MD5_RSA_SIG_HEX; break;
- case OID_SHA1_RSA_SIG: oid_hex = OID_SHA1_RSA_SIG_HEX; break;
- case OID_ID_MGF1: oid_hex = OID_ID_MGF1_HEX; break;
- case OID_RSASSA_PSS: oid_hex = OID_RSASSA_PSS_HEX; break;
- case OID_SHA256_RSA_SIG: oid_hex = OID_SHA256_RSA_SIG_HEX; break;
- case OID_SHA384_RSA_SIG: oid_hex = OID_SHA384_RSA_SIG_HEX; break;
- case OID_SHA512_RSA_SIG: oid_hex = OID_SHA512_RSA_SIG_HEX; break;
- case OID_SHA1_DSA_SIG: oid_hex = OID_SHA1_DSA_SIG_HEX; break;
- case OID_SHA1_ECDSA_SIG: oid_hex = OID_SHA1_ECDSA_SIG_HEX; break;
- case OID_SHA224_ECDSA_SIG: oid_hex = OID_SHA224_ECDSA_SIG_HEX; break;
- case OID_SHA256_ECDSA_SIG: oid_hex = OID_SHA256_ECDSA_SIG_HEX; break;
- case OID_SHA384_ECDSA_SIG: oid_hex = OID_SHA384_ECDSA_SIG_HEX; break;
- case OID_SHA512_ECDSA_SIG: oid_hex = OID_SHA512_ECDSA_SIG_HEX; break;
- case OID_RSA_KEY_ALG: oid_hex = OID_RSA_KEY_ALG_HEX; break;
- case OID_DSA_KEY_ALG: oid_hex = OID_DSA_KEY_ALG_HEX; break;
- case OID_ECDSA_KEY_ALG: oid_hex = OID_ECDSA_KEY_ALG_HEX; break;
- case OID_DES_EDE3_CBC: oid_hex = OID_DES_EDE3_CBC_HEX; break;
- case OID_AES_128_CBC: oid_hex = OID_AES_128_CBC_HEX; break;
- case OID_AES_128_WRAP: oid_hex = OID_AES_128_WRAP_HEX; break;
- case OID_AES_128_GCM: oid_hex = OID_AES_128_GCM_HEX; break;
- case OID_AES_192_CBC: oid_hex = OID_AES_192_CBC_HEX; break;
- case OID_AES_192_WRAP: oid_hex = OID_AES_192_WRAP_HEX; break;
- case OID_AES_192_GCM: oid_hex = OID_AES_192_GCM_HEX; break;
- case OID_AES_256_CBC: oid_hex = OID_AES_256_CBC_HEX; break;
- case OID_AES_256_WRAP: oid_hex = OID_AES_256_WRAP_HEX; break;
- case OID_AES_256_GCM: oid_hex = OID_AES_256_GCM_HEX; break;
- case OID_AES_CMAC: oid_hex = OID_AES_CMAC_HEX; break;
- case OID_AES_CBC_CMAC_128: oid_hex = OID_AES_CBC_CMAC_128_HEX; break;
- case OID_AES_CBC_CMAC_192: oid_hex = OID_AES_CBC_CMAC_192_HEX; break;
- case OID_AES_CBC_CMAC_256: oid_hex = OID_AES_CBC_CMAC_256_HEX; break;
- case OID_AUTH_ENC_256_SUM: oid_hex = OID_AUTH_ENC_256_SUM_HEX; break;
- case OID_PKCS_PBKDF2: oid_hex = OID_PKCS_PBKDF2_HEX; break;
- case OID_PKCS_PBES2: oid_hex = OID_PKCS_PBES2_HEX; break;
- case OID_PKCS_PBESHA128RC4: oid_hex = OID_PKCS_PBESHA128RC4_HEX; break;
- case OID_PKCS_PBESHA40RC4: oid_hex = OID_PKCS_PBESHA40RC4_HEX; break;
- case OID_PKCS_PBESHA3DES3: oid_hex = OID_PKCS_PBESHA3DES3_HEX; break;
- case OID_PKCS_PBESHA2DES3: oid_hex = OID_PKCS_PBESHA2DES3_HEX; break;
- case OID_PKCS_PBESHA128RC2: oid_hex = OID_PKCS_PBESHA128RC2_HEX; break;
- case OID_PKCS_PBESHA40RC2: oid_hex = OID_PKCS_PBESHA40RC2_HEX; break;
- case OID_PKCS12_BAG_TYPE_KEY: oid_hex = OID_PKCS12_BAG_TYPE_KEY_HEX; break;
- case OID_PKCS12_BAG_TYPE_SHROUD: oid_hex = OID_PKCS12_BAG_TYPE_SHROUD_HEX; break;
- case OID_PKCS12_BAG_TYPE_CERT: oid_hex = OID_PKCS12_BAG_TYPE_CERT_HEX; break;
- case OID_PKCS12_BAG_TYPE_CRL: oid_hex = OID_PKCS12_BAG_TYPE_CRL_HEX; break;
- case OID_PKCS12_BAG_TYPE_SECRET: oid_hex = OID_PKCS12_BAG_TYPE_SECRET_HEX; break;
- case OID_PKCS12_BAG_TYPE_SAFE: oid_hex = OID_PKCS12_BAG_TYPE_SAFE_HEX; break;
- case OID_PKCS9_CERT_TYPE_X509: oid_hex = OID_PKCS9_CERT_TYPE_X509_HEX; break;
- case OID_PKCS9_CERT_TYPE_SDSI: oid_hex = OID_PKCS9_CERT_TYPE_SDSI_HEX; break;
- case OID_PKCS7_DATA: oid_hex = OID_PKCS7_DATA_HEX; break;
- case OID_PKCS7_SIGNED_DATA: oid_hex = OID_PKCS7_SIGNED_DATA_HEX; break;
- case OID_PKCS7_ENVELOPED_DATA: oid_hex = OID_PKCS7_ENVELOPED_DATA_HEX; break;
- case OID_PKCS7_SIGNED_ENVELOPED_DATA: oid_hex = OID_PKCS7_SIGNED_ENVELOPED_DATA_HEX; break;
- case OID_PKCS7_DIGESTED_DATA: oid_hex = OID_PKCS7_DIGESTED_DATA_HEX; break;
- case OID_PKCS7_ENCRYPTED_DATA: oid_hex = OID_PKCS7_ENCRYPTED_DATA_HEX; break;
- case OID_OCSP: oid_hex = OID_OCSP_HEX; break;
- case OID_BASIC_OCSP_RESPONSE: oid_hex = OID_BASIC_OCSP_RESPONSE_HEX; break;
- default:
- /* No possible matches: bitwise-add not found constant to OID. */
- *oi |= OID_NOT_FOUND;
- return;
- }
- /* Ignore tag, but use length byte and data from binary oid. */
- if (oidLen == oid_hex[1] && !memcmp(oidStart, &oid_hex[2], oidLen))
- return;
- *oi += OID_COLLISION;
- }
+ /* The values are represented as C strings, although they contain
+ binary data. Therefore the type needs to be const char *. */
+ const char *oid_hex;
+
+ /* Loop until match is found, adding multiples of OID_COLLISION in case of
+ mismatch. */
+ while (1)
+ {
+ switch (*oi)
+ {
+ case OID_SHA1_ALG: oid_hex = OID_SHA1_ALG_HEX; break;
+ case OID_SHA256_ALG: oid_hex = OID_SHA256_ALG_HEX; break;
+ case OID_SHA384_ALG: oid_hex = OID_SHA384_ALG_HEX; break;
+ case OID_SHA512_ALG: oid_hex = OID_SHA512_ALG_HEX; break;
+ case OID_MD2_ALG: oid_hex = OID_MD2_ALG_HEX; break;
+ case OID_MD5_ALG: oid_hex = OID_MD5_ALG_HEX; break;
+ case OID_MD2_RSA_SIG: oid_hex = OID_MD2_RSA_SIG_HEX; break;
+ case OID_MD5_RSA_SIG: oid_hex = OID_MD5_RSA_SIG_HEX; break;
+ case OID_SHA1_RSA_SIG: oid_hex = OID_SHA1_RSA_SIG_HEX; break;
+ case OID_SHA1_RSA_SIG2: oid_hex = OID_SHA1_RSA_SIG2_HEX; break;
+ case OID_ID_MGF1: oid_hex = OID_ID_MGF1_HEX; break;
+ case OID_RSASSA_PSS: oid_hex = OID_RSASSA_PSS_HEX; break;
+ case OID_SHA256_RSA_SIG: oid_hex = OID_SHA256_RSA_SIG_HEX; break;
+ case OID_SHA384_RSA_SIG: oid_hex = OID_SHA384_RSA_SIG_HEX; break;
+ case OID_SHA512_RSA_SIG: oid_hex = OID_SHA512_RSA_SIG_HEX; break;
+ case OID_SHA1_DSA_SIG: oid_hex = OID_SHA1_DSA_SIG_HEX; break;
+ case OID_SHA1_ECDSA_SIG: oid_hex = OID_SHA1_ECDSA_SIG_HEX; break;
+ case OID_SHA224_ECDSA_SIG: oid_hex = OID_SHA224_ECDSA_SIG_HEX; break;
+ case OID_SHA256_ECDSA_SIG: oid_hex = OID_SHA256_ECDSA_SIG_HEX; break;
+ case OID_SHA384_ECDSA_SIG: oid_hex = OID_SHA384_ECDSA_SIG_HEX; break;
+ case OID_SHA512_ECDSA_SIG: oid_hex = OID_SHA512_ECDSA_SIG_HEX; break;
+ case OID_RSA_KEY_ALG: oid_hex = OID_RSA_KEY_ALG_HEX; break;
+ case OID_DSA_KEY_ALG: oid_hex = OID_DSA_KEY_ALG_HEX; break;
+ case OID_ECDSA_KEY_ALG: oid_hex = OID_ECDSA_KEY_ALG_HEX; break;
+ case OID_DES_EDE3_CBC: oid_hex = OID_DES_EDE3_CBC_HEX; break;
+ case OID_AES_128_CBC: oid_hex = OID_AES_128_CBC_HEX; break;
+ case OID_AES_128_WRAP: oid_hex = OID_AES_128_WRAP_HEX; break;
+ case OID_AES_128_GCM: oid_hex = OID_AES_128_GCM_HEX; break;
+ case OID_AES_192_CBC: oid_hex = OID_AES_192_CBC_HEX; break;
+ case OID_AES_192_WRAP: oid_hex = OID_AES_192_WRAP_HEX; break;
+ case OID_AES_192_GCM: oid_hex = OID_AES_192_GCM_HEX; break;
+ case OID_AES_256_CBC: oid_hex = OID_AES_256_CBC_HEX; break;
+ case OID_AES_256_WRAP: oid_hex = OID_AES_256_WRAP_HEX; break;
+ case OID_AES_256_GCM: oid_hex = OID_AES_256_GCM_HEX; break;
+ case OID_AES_CMAC: oid_hex = OID_AES_CMAC_HEX; break;
+ case OID_AES_CBC_CMAC_128: oid_hex = OID_AES_CBC_CMAC_128_HEX; break;
+ case OID_AES_CBC_CMAC_192: oid_hex = OID_AES_CBC_CMAC_192_HEX; break;
+ case OID_AES_CBC_CMAC_256: oid_hex = OID_AES_CBC_CMAC_256_HEX; break;
+ case OID_AUTH_ENC_256_SUM: oid_hex = OID_AUTH_ENC_256_SUM_HEX; break;
+ case OID_PKCS_PBKDF2: oid_hex = OID_PKCS_PBKDF2_HEX; break;
+ case OID_PKCS_PBES2: oid_hex = OID_PKCS_PBES2_HEX; break;
+ case OID_PKCS_PBESHA128RC4: oid_hex = OID_PKCS_PBESHA128RC4_HEX; break;
+ case OID_PKCS_PBESHA40RC4: oid_hex = OID_PKCS_PBESHA40RC4_HEX; break;
+ case OID_PKCS_PBESHA3DES3: oid_hex = OID_PKCS_PBESHA3DES3_HEX; break;
+ case OID_PKCS_PBESHA2DES3: oid_hex = OID_PKCS_PBESHA2DES3_HEX; break;
+ case OID_PKCS_PBESHA128RC2: oid_hex = OID_PKCS_PBESHA128RC2_HEX; break;
+ case OID_PKCS_PBESHA40RC2: oid_hex = OID_PKCS_PBESHA40RC2_HEX; break;
+ case OID_PKCS12_BAG_TYPE_KEY: oid_hex = OID_PKCS12_BAG_TYPE_KEY_HEX; break;
+ case OID_PKCS12_BAG_TYPE_SHROUD: oid_hex = OID_PKCS12_BAG_TYPE_SHROUD_HEX; break;
+ case OID_PKCS12_BAG_TYPE_CERT: oid_hex = OID_PKCS12_BAG_TYPE_CERT_HEX; break;
+ case OID_PKCS12_BAG_TYPE_CRL: oid_hex = OID_PKCS12_BAG_TYPE_CRL_HEX; break;
+ case OID_PKCS12_BAG_TYPE_SECRET: oid_hex = OID_PKCS12_BAG_TYPE_SECRET_HEX; break;
+ case OID_PKCS12_BAG_TYPE_SAFE: oid_hex = OID_PKCS12_BAG_TYPE_SAFE_HEX; break;
+ case OID_PKCS9_CERT_TYPE_X509: oid_hex = OID_PKCS9_CERT_TYPE_X509_HEX; break;
+ case OID_PKCS9_CERT_TYPE_SDSI: oid_hex = OID_PKCS9_CERT_TYPE_SDSI_HEX; break;
+ case OID_PKCS7_DATA: oid_hex = OID_PKCS7_DATA_HEX; break;
+ case OID_PKCS7_SIGNED_DATA: oid_hex = OID_PKCS7_SIGNED_DATA_HEX; break;
+ case OID_PKCS7_ENVELOPED_DATA: oid_hex = OID_PKCS7_ENVELOPED_DATA_HEX; break;
+ case OID_PKCS7_SIGNED_ENVELOPED_DATA: oid_hex = OID_PKCS7_SIGNED_ENVELOPED_DATA_HEX; break;
+ case OID_PKCS7_DIGESTED_DATA: oid_hex = OID_PKCS7_DIGESTED_DATA_HEX; break;
+ case OID_PKCS7_ENCRYPTED_DATA: oid_hex = OID_PKCS7_ENCRYPTED_DATA_HEX; break;
+ case OID_OCSP: oid_hex = OID_OCSP_HEX; break;
+ case OID_BASIC_OCSP_RESPONSE: oid_hex = OID_BASIC_OCSP_RESPONSE_HEX; break;
+ default:
+ /* No possible matches: bitwise-add not found constant to OID. */
+ *oi |= OID_NOT_FOUND;
+ return;
+ }
+ /* Ignore tag, but use length byte and data from binary oid. */
+ if (oidLen == oid_hex[1] && !memcmp(oidStart, &oid_hex[2], oidLen))
+ {
+ return; /* Success */
+ }
+ *oi += OID_COLLISION;
+ }
}
#endif /* MATRIXSSL_NO_OID_DATABASE */
/******************************************************************************/
int32_t getAsnOID(const unsigned char **pp, uint32_t len, int32_t *oi,
- uint8_t checkForParams, uint16_t *paramLen)
+ uint8_t checkForParams, psSize_t *paramLen)
{
- const unsigned char *p = *pp, *end;
- int32_t plen, rc;
- uint32_t arcLen;
- const unsigned char *oidStart;
- uint32_t oidLen;
+ const unsigned char *p = *pp, *end;
+ int32_t plen, rc;
+ uint32_t arcLen;
+ const unsigned char *oidStart;
+ uint32_t oidLen;
- rc = PS_PARSE_FAIL;
- end = p + len;
- plen = end - p;
- if (*(p++) != ASN_OID || (rc = getAsnLength32(&p, (uint32_t)(end - p), &arcLen, 0))
- < 0) {
- psTraceCrypto("Malformed algorithmId 2\n");
- return rc;
- }
- if (end - p < arcLen) {
- return PS_LIMIT_FAIL;
- }
- if (end - p < 2) {
- psTraceCrypto("Malformed algorithmId 3\n");
- return PS_LIMIT_FAIL;
- }
- *oi = 0;
- oidStart = p;
- oidLen = arcLen;
- while (arcLen > 0) {
- *oi += *p;
- p++;
- arcLen--;
- }
+ rc = PS_PARSE_FAIL;
+ end = p + len;
+ plen = end - p;
+ if (*(p++) != ASN_OID || (rc = getAsnLength32(&p, (uint32_t) (end - p), &arcLen, 0))
+ < 0)
+ {
+ psTraceCrypto("Malformed algorithmId 2\n");
+ return rc;
+ }
+ if (end - p < arcLen)
+ {
+ return PS_LIMIT_FAIL;
+ }
+ if (end - p < 2)
+ {
+ psTraceCrypto("Malformed algorithmId 3\n");
+ return PS_LIMIT_FAIL;
+ }
+ *oi = 0;
+ oidStart = p;
+ oidLen = arcLen;
+ while (arcLen > 0)
+ {
+ *oi += *p;
+ p++;
+ arcLen--;
+ }
#ifndef MATRIXSSL_NO_OID_DATABASE
- checkAsnOidDatabase(oi, oidStart, oidLen);
+ checkAsnOidDatabase(oi, oidStart, oidLen);
#endif /* MATRIXSSL_NO_OID_DATABASE */
- if (checkForParams) {
- plen -= (end - p);
- *paramLen = len - plen;
- if (*p != ASN_NULL) {
- *pp = p;
- /* paramLen tells whether params exist or completely missing (0) */
- if (*paramLen > 0) {
- //psTraceIntCrypto("OID %d has parameters to process\n", *oi);
- }
- return PS_SUCCESS;
- }
- /* NULL parameter case. Somewhat common. Skip it for the caller */
- if (end - p < 2) {
- psTraceCrypto("Malformed algorithmId 4\n");
- return PS_LIMIT_FAIL;
- }
- if (*paramLen < 2) {
- psTraceCrypto("Malformed algorithmId 5\n");
- return PS_LIMIT_FAIL;
- }
- *paramLen -= 2; /* 1 for the OID tag and 1 for the NULL */
- *pp = p + 2;
- } else {
- *paramLen = 0;
- *pp = p;
- }
- return PS_SUCCESS;
+ if (checkForParams)
+ {
+ plen -= (end - p);
+ *paramLen = len - plen;
+ if (*p != ASN_NULL)
+ {
+ *pp = p;
+ /* paramLen tells whether params exist or completely missing (0) */
+ if (*paramLen > 0)
+ {
+ /* psTraceIntCrypto("OID %d has parameters to process\n", *oi); */
+ }
+ return PS_SUCCESS;
+ }
+ /* NULL parameter case. Somewhat common. Skip it for the caller */
+ if (end - p < 2)
+ {
+ psTraceCrypto("Malformed algorithmId 4\n");
+ return PS_LIMIT_FAIL;
+ }
+ if (*paramLen < 2)
+ {
+ psTraceCrypto("Malformed algorithmId 5\n");
+ return PS_LIMIT_FAIL;
+ }
+ *paramLen -= 2; /* 1 for the OID tag and 1 for the NULL */
+ *pp = p + 2;
+ }
+ else
+ {
+ *paramLen = 0;
+ *pp = p;
+ }
+ return PS_SUCCESS;
}
/******************************************************************************/
diff --git a/crypto/keyformat/asn1.h b/crypto/keyformat/asn1.h
index 19ece9c..f9c8b13 100644
--- a/crypto/keyformat/asn1.h
+++ b/crypto/keyformat/asn1.h
@@ -1,109 +1,120 @@
/**
- * @file asn1.h
- * @version $Format:%h%d$
+ * @file asn1.h
+ * @version $Format:%h%d$
*
- * ASN.1 header.
+ * ASN.1 header.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
/* Allow inclusion of asn1.h as standalone. */
#ifndef _h_PS_CRYPTOAPI
-#include "../cryptoApi.h"
+# include "../cryptoApi.h"
#endif /* _h_PS_CRYPTOAPI */
#ifndef _h_PS_ASN1
-#define _h_PS_ASN1
+# define _h_PS_ASN1
/******************************************************************************/
/*
- 8 bit bit masks for ASN.1 tag field
-*/
-#define ASN_PRIMITIVE 0x0
-#define ASN_CONSTRUCTED 0x20
+ 8 bit bit masks for ASN.1 tag field
+ */
+# define ASN_PRIMITIVE 0x0
+# define ASN_CONSTRUCTED 0x20
-#define ASN_UNIVERSAL 0x0
-#define ASN_APPLICATION 0x40
-#define ASN_CONTEXT_SPECIFIC 0x80
-#define ASN_PRIVATE 0xC0
+# define ASN_UNIVERSAL 0x0
+# define ASN_APPLICATION 0x40
+# define ASN_CONTEXT_SPECIFIC 0x80
+# define ASN_PRIVATE 0xC0
/*
- ASN.1 primitive data types
-*/
-enum {
- ASN_BOOLEAN = 1,
- ASN_INTEGER,
- ASN_BIT_STRING,
- ASN_OCTET_STRING,
- ASN_NULL,
- ASN_OID,
- ASN_ENUMERATED = 10,
- ASN_UTF8STRING = 12,
- ASN_SEQUENCE = 16,
- ASN_SET,
- ASN_PRINTABLESTRING = 19,
- ASN_T61STRING,
- ASN_IA5STRING = 22,
- ASN_UTCTIME,
- ASN_GENERALIZEDTIME,
- ASN_VISIBLE_STRING = 26,
- ASN_GENERAL_STRING,
- ASN_BMPSTRING = 30
+ ASN.1 primitive data types
+ */
+enum
+{
+ ASN_BOOLEAN = 1,
+ ASN_INTEGER,
+ ASN_BIT_STRING,
+ ASN_OCTET_STRING,
+ ASN_NULL,
+ ASN_OID,
+ ASN_ENUMERATED = 10,
+ ASN_UTF8STRING = 12,
+ ASN_SEQUENCE = 16,
+ ASN_SET,
+ ASN_PRINTABLESTRING = 19,
+ ASN_T61STRING,
+ ASN_IA5STRING = 22,
+ ASN_UTCTIME,
+ ASN_GENERALIZEDTIME,
+ ASN_VISIBLE_STRING = 26,
+ ASN_GENERAL_STRING,
+ ASN_BMPSTRING = 30
};
-#define ASN_UNKNOWN_LEN 65533
+# define ASN_UNKNOWN_LEN 65533
-extern int32_t getAsnLength(const unsigned char **p, uint16_t size,
- uint16_t *valLen);
+extern int32_t getAsnLength(const unsigned char **p, psSize_t size,
+ psSize_t *valLen);
extern int32_t getAsnLength32(const unsigned char **p, uint32_t size,
- uint32_t *valLen, uint32_t indefinite);
-extern int32_t getAsnSequence(const unsigned char **pp, uint16_t len,
- uint16_t *seqlen);
+ uint32_t *valLen, uint32_t indefinite);
+extern int32_t getAsnSequence(const unsigned char **pp, psSize_t len,
+ psSize_t *seqlen);
extern int32_t getAsnSequence32(const unsigned char **pp, uint32_t size,
- uint32_t *len, uint32_t indefinite);
-extern int32_t getAsnSet(const unsigned char **pp, uint16_t len,
- uint16_t *setlen);
+ uint32_t *len, uint32_t indefinite);
+extern int32_t getAsnSet(const unsigned char **pp, psSize_t len,
+ psSize_t *setlen);
extern int32_t getAsnSet32(const unsigned char **pp, uint32_t size,
- uint32_t *len, uint32_t indefinite);
+ uint32_t *len, uint32_t indefinite);
extern int32_t getAsnEnumerated(const unsigned char **pp, uint32_t len,
- int32_t *val);
+ int32_t *val);
extern int32_t getAsnInteger(const unsigned char **pp, uint32_t len,
- int32_t *val);
+ int32_t *val);
extern int32_t getAsnAlgorithmIdentifier(const unsigned char **pp, uint32_t len,
- int32_t *oi, uint16_t *paramLen);
+ int32_t *oi, psSize_t *paramLen);
extern int32_t getAsnOID(const unsigned char **pp, uint32_t len, int32_t *oi,
- uint8_t checkForParams, uint16_t *paramLen);
+ uint8_t checkForParams, psSize_t *paramLen);
+
+# define MAX_OID_LEN 16 /**< Maximum number of segments in OID */
+
+extern uint8_t asnParseOid(const unsigned char *der, psSize_t derlen,
+ uint32_t oid[MAX_OID_LEN]);
+
+
+/* Format OID tag as string for printing. */
+extern char *asnFormatOid(psPool_t *pool,
+ const unsigned char *oid, size_t oidlen);
/******************************************************************************/
-#endif /* _h_PS_ASN1 */
+#endif /* _h_PS_ASN1 */
/******************************************************************************/
diff --git a/crypto/keyformat/asn1fmt.c b/crypto/keyformat/asn1fmt.c
new file mode 100644
index 0000000..b1b10b6
--- /dev/null
+++ b/crypto/keyformat/asn1fmt.c
@@ -0,0 +1,340 @@
+/**
+ * @file x509dbg.c
+ * @version $Format:%h%d$
+ *
+ * ASN.1 Parsing: convenience functions for formatting ASN.1.
+ */
+/*
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#if !defined USE_X509 && !defined USE_OCSP
+# include "../cryptoImpl.h" /* MatrixSSL API interface and configuration. */
+#endif
+
+#if (defined USE_X509 && defined USE_FULL_CERT_PARSE) || defined USE_OCSP
+
+# include /* for snprintf() */
+# include /* for strlen() */
+
+/* Constants used in OID formatting code. */
+# define OID_STR_BUF_LEN (129 * 4) /* Temporary string length. */
+# define OID_STR_MAX_SEQ_LEN 64 /* Maximum octets in sequence. */
+
+/* Access bitarray containing 7 bits of data per octet. */
+static unsigned char oid_get_bit7(const unsigned char *bitarray,
+ size_t n, int i)
+{
+ unsigned char byte;
+ size_t a = (size_t) (i / 7);
+ int bitidx = i % 7;
+
+ if (n <= a)
+ {
+ return 0;
+ }
+
+ byte = bitarray[n - a - 1];
+ byte >>= bitidx;
+ return byte & 1;
+}
+
+/* Perform conversion between OID encoded data (i.e. BER compressed
+ integer like perl pack("w"), and a long sequence of octets. */
+static
+unsigned int oid_double_dabble_workhorse(const unsigned char *b,
+ size_t n,
+ unsigned char t[],
+ int v_bits, size_t t_bytes)
+{
+ int i;
+ size_t j;
+ unsigned int x;
+ unsigned int overflow = 0;
+ size_t t_bcdbytes = (t_bytes + 1) / 2;
+
+ for (j = t_bcdbytes; j-- > 0; )
+ {
+ t[j] = 0;
+ }
+
+ /* Compute BCD corresponding with Buc_p.
+ (double-dabble algorithm). */
+ for (i = v_bits; i-- > 0; )
+ {
+ unsigned char c = oid_get_bit7(b, n, i);
+ x = c;
+ for (j = t_bcdbytes; j-- > 0; )
+ {
+ x += (2 * (unsigned int) t[j]);
+ t[j] = x & 255;
+ x >>= 8;
+ }
+ overflow |= x;
+ if (i == 0)
+ {
+ break;
+ }
+ for (j = t_bcdbytes; j-- > 0; )
+ {
+ unsigned char a, add51, m;
+ a = t[j];
+ add51 = a + 51;
+ m = add51 & 0x88;
+ m |= m >> 2;
+ m |= m >> 1;
+ t[j] = (a & ~m) | (add51 & m);
+ }
+ }
+
+ /* Convert BCD to decimal. */
+ if ((t_bytes & 1) == 1)
+ {
+ /* The result is shifted 4 bits; fix it. */
+ overflow |= t[0] >> 4;
+ for (j = t_bytes; j-- > 0; )
+ {
+ if (j & 1)
+ {
+ t[j] = '0' + (t[j / 2 + 1] >> 4);
+ }
+ else
+ {
+ t[j] = '0' + (t[j / 2] & 15);
+ }
+ }
+ }
+ else
+ {
+ for (j = t_bytes; j-- > 0; )
+ {
+ if (j & 1)
+ {
+ t[j] = '0' + (t[j / 2] & 15);
+ }
+ else
+ {
+ t[j] = '0' + (t[j / 2] >> 4);
+ }
+ }
+ }
+
+ return overflow;
+}
+
+/* Append to string s (assumed sufficiently long) a contiguous segment of
+ BER compressed integer like perl pack("w") unpacked. This function
+ processes at most 64 bytes at once (i.e. up-to 72683872429560689054932380
+ 7888004534353641360687318060281490199180639288113397923326191050713763565
+ 560762521606266177933534601628614655).
+ This range is sufficient for typical OIDs as well as UUID-based OIDs.
+ */
+static size_t oid_part_append(char *s, const unsigned char *oid, size_t oidlen)
+{
+ size_t pos;
+ unsigned long long ll;
+ const unsigned char *oid_orig = oid;
+
+ /* The most common case: single byte oid segment. */
+ if (*oid < 128)
+ {
+ sprintf(s, ".%d", *oid);
+ return 1;
+ }
+ else if (*oid == 128)
+ {
+ /* Illegal: One of the highest bits shall be set. */
+ return 0;
+ }
+
+ /* Handle oid parts smaller than 2**64-1. */
+ ll = *oid & 127;
+ pos = 1;
+ while (pos < oidlen)
+ {
+ oid++;
+ ll *= 128;
+ ll += *oid & 127;
+ if (*oid < 128)
+ {
+ if (pos < 8)
+ {
+ sprintf(s, ".%llu", ll);
+ return pos + 1;
+ }
+ else if (pos < OID_STR_MAX_SEQ_LEN)
+ {
+ size_t plen;
+ size_t ilen;
+ /* Precision may exceed capacity of unsigned long long.
+ Use variant of double-dabble that can do arbitrary
+ precision. */
+ pos += 1;
+ *s = '.';
+ memset(s + 1, 0, pos * 3 + 1);
+ oid_double_dabble_workhorse(oid_orig, pos,
+ (unsigned char *) (s + 1),
+ pos * 8, pos * 3);
+
+ /* The string formatting generates extra zeroes. Remove them. */
+ s += 1; /* Skip '.' */
+ ilen = strlen(s);
+ plen = 0;
+ while (plen < ilen && plen < ilen - 1 && s[plen] == '0')
+ {
+ plen++;
+ }
+ /* Remove initial zeroes. */
+ memmove(s, s + plen, ilen + 1 - plen);
+ return pos;
+ }
+ else
+ {
+ /* Single OID component exceeds sizes required for any
+ known uses. These are not handled. */
+ return 0;
+ }
+ }
+ pos++;
+ }
+
+ return 0; /* Unable to process. */
+}
+
+/* Decrement 1 from number expressed in ascii. */
+static void oid_asciidec(char *s, size_t l)
+{
+ size_t i;
+ int dec = 1;
+
+ for (i = l; i-- > 0; )
+ {
+ s[i] -= dec;
+ if (s[i] < '0')
+ {
+ s[i] = '9';
+ }
+ else
+ {
+ dec = 0;
+ }
+ }
+}
+
+/* Format OID to string buffer. Returns position within the buffer
+ on successful execution or NULL on failure. */
+static char *oid_to_string(const unsigned char *oid, size_t oidlen,
+ char str[OID_STR_BUF_LEN])
+{
+ char *s = str;
+ int prefix = 0; /* Ignored bytes in beginning. */
+
+ str[0] = 0;
+ /* Only process OID identifiers, and up-to 129 bytes long, with
+ correct length identifier. */
+ if (oidlen < 3 || oidlen > 129 || oid[0] != 0x06 || oid[1] != oidlen - 2)
+ {
+ return NULL;
+ }
+ if (oid[2] < 120)
+ {
+ /* Simple case, [012].x where x < 40. */
+ sprintf(s, "%d.%d", oid[2] / 40, oid[2] % 40);
+ s += strlen(s);
+ oid += 3;
+ oidlen -= 3;
+ }
+ else
+ {
+ /* Process 2.xxx, where xxx is arbitrary length number >= 40. */
+ size_t bytes = oid_part_append(s + 1, oid + 2, oidlen - 2);
+ int i;
+
+ if (bytes < 2)
+ {
+ return NULL;
+ }
+
+ /* Decrement tens eight time. */
+ for (i = 0; i < 8; i++)
+ {
+ oid_asciidec(s + 2, strlen(s + 2) - 1);
+ }
+
+ /* Check if there were extra zeroes in s[2]. */
+ while (strlen(s + 2) && s[2] == '0')
+ {
+ s++;
+ prefix++;
+ }
+
+ s[0] = '2';
+ s[1] = '.';
+ s += strlen(s);
+ oid += 2 + bytes;
+ oidlen -= 2 + bytes;
+ }
+ while (oidlen > 0)
+ {
+ size_t bytes = oid_part_append(s, oid, oidlen);
+ if (bytes == 0)
+ {
+ return NULL;
+ }
+ oidlen -= bytes;
+ oid += bytes;
+ s += strlen(s);
+ }
+ return str + prefix;
+}
+
+# ifndef NO_ASN_FORMAT_OID
+char *asnFormatOid(psPool_t *pool,
+ const unsigned char *oid, size_t oidlen)
+{
+ /* Perform formatting for oid. */
+ char *out;
+ char str_tmp[OID_STR_BUF_LEN];
+ char *str = oid_to_string(oid, oidlen, str_tmp);
+
+ if (str == NULL)
+ {
+ return NULL;
+ }
+
+ /* Allocate dynamically new memory for the result. */
+ out = psMalloc(pool, strlen(str) + 1);
+ if (out)
+ {
+ memcpy(out, str, strlen(str) + 1);
+ }
+ return out;
+}
+# endif /* NO_ASN_FORMAT_OID */
+
+#endif /* compilation selector: full X.509 or OCSP enabled */
+
diff --git a/crypto/keyformat/base64.c b/crypto/keyformat/base64.c
index 202b819..b60efce 100644
--- a/crypto/keyformat/base64.c
+++ b/crypto/keyformat/base64.c
@@ -1,127 +1,140 @@
/**
- * @file base64.c
- * @version $Format:%h%d$
+ * @file base64.c
+ * @version $Format:%h%d$
*
- * Base64 operations.
+ * Base64 operations.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
#ifdef USE_BASE64_DECODE
static const unsigned char map[] = {
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
-255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
-255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
- 49, 50, 51
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
+ 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
+ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51
/* , 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
-255, 255, 255, 255
-*/
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255
+ */
};
-int32_t psBase64decode(const unsigned char *in, uint16_t len,
- unsigned char *out, uint16_t *outlen)
+int32_t psBase64decode(const unsigned char *in, psSize_t len,
+ unsigned char *out, psSize_t *outlen)
{
- unsigned int t;
- unsigned char c;
- uint16_t x, y, z;
- int16_t g;
+ unsigned int t;
+ unsigned char c;
+ uint16_t x, y, z;
+ int16_t g;
- if (in == NULL || out == NULL || outlen == NULL) {
- psTraceCrypto("Arg failure to psBase64decode\n");
- return PS_ARG_FAIL;
- }
- g = 3;
- for (x = y = z = t = 0; x < len; x++) {
- /* Save a little space by skipping values that would be 255 in the full map */
- if (in[x] > 122) {
- continue;
- }
- c = map[in[x]];
- if (c == 255) {
- continue;
- }
- /* the final '=' symbols are read and used to trim the remaining bytes */
- if (c == 254) {
- c = 0;
- /* prevent g < 0 which would potentially allow an overflow later */
- if (--g < 0) {
- psTraceCrypto("Negative g failure in psBase64decode\n");
- return PS_LIMIT_FAIL;
- }
- } else if (g != 3) {
- /* we only allow = to be at the end */
- psTraceCrypto("g failure in psBase64decode\n");
- return PS_PARSE_FAIL;
- }
-
- t = (t << 6) | c;
+ if (in == NULL || out == NULL || outlen == NULL)
+ {
+ psTraceCrypto("Arg failure to psBase64decode\n");
+ return PS_ARG_FAIL;
+ }
+ g = 3;
+ for (x = y = z = t = 0; x < len; x++)
+ {
+ /* Save a little space by skipping values that would be 255 in the full map */
+ if (in[x] > 122)
+ {
+ continue;
+ }
+ c = map[in[x]];
+ if (c == 255)
+ {
+ continue;
+ }
+ /* the final '=' symbols are read and used to trim the remaining bytes */
+ if (c == 254)
+ {
+ c = 0;
+ /* prevent g < 0 which would potentially allow an overflow later */
+ if (--g < 0)
+ {
+ psTraceCrypto("Negative g failure in psBase64decode\n");
+ return PS_LIMIT_FAIL;
+ }
+ }
+ else if (g != 3)
+ {
+ /* we only allow = to be at the end */
+ psTraceCrypto("g failure in psBase64decode\n");
+ return PS_PARSE_FAIL;
+ }
- if (++y == 4) {
- if (z + g > *outlen) {
- psTraceCrypto("outlen too small for psBase64decode\n");
- return PS_LIMIT_FAIL;
- }
- out[z++] = (unsigned char)((t>>16) & 0xFF);
- if (g > 1) {
- out[z++] = (unsigned char)((t>>8) & 0xFF);
- }
- if (g > 2) {
- out[z++] = (unsigned char)(t & 0xFF);
- }
- y = t = 0;
- }
- }
- if (y != 0) {
- psTraceCrypto("y failure in psBase64decode\n");
- return PS_PARSE_FAIL;
- }
- *outlen = z;
- return PS_SUCCESS;
+ t = (t << 6) | c;
+
+ if (++y == 4)
+ {
+ if (z + g > *outlen)
+ {
+ psTraceCrypto("outlen too small for psBase64decode\n");
+ return PS_LIMIT_FAIL;
+ }
+ out[z++] = (unsigned char) ((t >> 16) & 0xFF);
+ if (g > 1)
+ {
+ out[z++] = (unsigned char) ((t >> 8) & 0xFF);
+ }
+ if (g > 2)
+ {
+ out[z++] = (unsigned char) (t & 0xFF);
+ }
+ y = t = 0;
+ }
+ }
+ if (y != 0)
+ {
+ psTraceCrypto("y failure in psBase64decode\n");
+ return PS_PARSE_FAIL;
+ }
+ *outlen = z;
+ return PS_SUCCESS;
}
#endif /* USE_BASE64_DECODE */
diff --git a/crypto/keyformat/crl.c b/crypto/keyformat/crl.c
index 3bc533f..e607d24 100644
--- a/crypto/keyformat/crl.c
+++ b/crypto/keyformat/crl.c
@@ -1,555 +1,641 @@
/**
- * @file crl.c
- * @version $Format:%h%d$
+ * @file crl.c
+ * @version $Format:%h%d$
*
- * Certificate Revocation List tools
+ * Certificate Revocation List tools
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
#ifdef USE_CRL
-#ifdef USE_CERT_PARSE
+# ifdef USE_CERT_PARSE
-#ifdef USE_MULTITHREADING
-static psMutex_t g_crlTableLock;
-#endif
+# ifdef USE_MULTITHREADING
+static psMutex_t g_crlTableLock;
+# endif
/* Seems like many CRLs are not adhering to the specification that this
- extension be present. That just leaves us with the DN to match against
- if we disable this define. Not a big concern to disable it because the
- authentication is either going to pass or fail based on sig validation */
-//#define ENFORCE_CRL_AUTH_KEY_ID_EXT
+ extension be present. That just leaves us with the DN to match against
+ if we disable this define. Not a big concern to disable it because the
+ authentication is either going to pass or fail based on sig validation */
+/* #define ENFORCE_CRL_AUTH_KEY_ID_EXT */
static void internalFreeCRL(psX509Crl_t *crl);
/* The global CRL cache is a linked list of psX509Crl_t structures. A
- psX509Crl_t structure represents a single CRL file */
-static psX509Crl_t *g_CRL = NULL;
+ psX509Crl_t structure represents a single CRL file */
+static psX509Crl_t *g_CRL = NULL;
/* Invoked from psCryptoOpen */
int32_t psCrlOpen()
{
-#ifdef USE_MULTITHREADING
- psCreateMutex(&g_crlTableLock, 0);
-#endif
- return PS_SUCCESS;
+# ifdef USE_MULTITHREADING
+ psCreateMutex(&g_crlTableLock, 0);
+# endif
+ return PS_SUCCESS;
}
/* Invoked from psCryptoClose */
void psCrlClose()
{
- psCRL_DeleteAll();
-#ifdef USE_MULTITHREADING
- psDestroyMutex(&g_crlTableLock);
-#endif
+ psCRL_DeleteAll();
+# ifdef USE_MULTITHREADING
+ psDestroyMutex(&g_crlTableLock);
+# endif
}
/* Helper for CRL insert */
static int internalCRLInsert(psX509Crl_t *crl)
{
- psX509Crl_t *next;
-
- if (crl == NULL) {
- return 0;
- }
+ psX509Crl_t *next;
- if (g_CRL == NULL) {
- /* first one */
- g_CRL = crl;
- return 1;
- }
- /* append */
- next = g_CRL;
- if (g_CRL == crl) {
- return 0; /* no pointer dups */
- }
- while (next->next) {
- next = next->next;
- if (next == crl) { /* no pointer dups */
- return 0;
- }
- }
- next->next = crl;
- return 1;
+ if (crl == NULL)
+ {
+ return 0;
+ }
+
+ if (g_CRL == NULL)
+ {
+ /* first one */
+ g_CRL = crl;
+ return 1;
+ }
+ /* append */
+ next = g_CRL;
+ if (g_CRL == crl)
+ {
+ return 0; /* no pointer dups */
+ }
+ while (next->next)
+ {
+ next = next->next;
+ if (next == crl) /* no pointer dups */
+ {
+ return 0;
+ }
+ }
+ next->next = crl;
+ return 1;
}
-/* Blindly append a CRL to the g_CRL list. Consider psCRL_Update instead.
- 1 - Added, 0 - Didn't */
+/* Blindly append a CRL to the g_CRL list. Consider psCRL_Update instead.
+ 1 - Added, 0 - Didn't */
int psCRL_Insert(psX509Crl_t *crl)
{
- int rc;
-#ifdef USE_MULTITHREADING
- psLockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
-
- rc = internalCRLInsert(crl);
-
-#ifdef USE_MULTITHREADING
- psUnlockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
- return rc;
+ int rc;
+
+# ifdef USE_MULTITHREADING
+ psLockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
+
+ rc = internalCRLInsert(crl);
+
+# ifdef USE_MULTITHREADING
+ psUnlockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
+ return rc;
}
/* Helper for Remove and Delete to take a CRL out of g_CRL */
static int internalShrinkCRLtable(psX509Crl_t *crl, int delete)
{
- psX509Crl_t *prev, *curr, *next;
+ psX509Crl_t *prev, *curr, *next;
- /* Return whether or not it was found in the list to help with the
- standalone psX509FreeCRL call logic */
-
- if (g_CRL == NULL || crl == NULL) {
- return 0;
- }
- prev = NULL;
- curr = g_CRL;
- next = curr->next;
- while (curr) {
- if (curr == crl) {
- if (delete) {
- internalFreeCRL(crl);
- } else {
- curr->next = NULL;
- }
- if (prev == NULL && next == NULL) {
- /* Only one in list */
- g_CRL = NULL;
- } else if (prev == NULL && next != NULL) {
- /* Removed first one in list */
- g_CRL = next;
- } else if (prev != NULL) {
- /* Removed middle or end */
- prev->next = next;
- }
- return 1;
- }
- prev = curr;
- curr = curr->next;
- if (curr) {
- /* curr can be NULL if we never found crl */
- next = curr->next;
- }
- }
- return 0;
+ /* Return whether or not it was found in the list to help with the
+ standalone psX509FreeCRL call logic */
+
+ if (g_CRL == NULL || crl == NULL)
+ {
+ return 0;
+ }
+ prev = NULL;
+ curr = g_CRL;
+ next = curr->next;
+ while (curr)
+ {
+ if (curr == crl)
+ {
+ if (delete)
+ {
+ internalFreeCRL(crl);
+ }
+ else
+ {
+ curr->next = NULL;
+ }
+ if (prev == NULL && next == NULL)
+ {
+ /* Only one in list */
+ g_CRL = NULL;
+ }
+ else if (prev == NULL && next != NULL)
+ {
+ /* Removed first one in list */
+ g_CRL = next;
+ }
+ else if (prev != NULL)
+ {
+ /* Removed middle or end */
+ prev->next = next;
+ }
+ return 1;
+ }
+ prev = curr;
+ curr = curr->next;
+ if (curr)
+ {
+ /* curr can be NULL if we never found crl */
+ next = curr->next;
+ }
+ }
+ return 0;
}
/* Remove a CRL from g_CRL but don't free the associated CRL */
int psCRL_Remove(psX509Crl_t *crl)
{
- int rc;
+ int rc;
-#ifdef USE_MULTITHREADING
- psLockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
+# ifdef USE_MULTITHREADING
+ psLockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
- rc = internalShrinkCRLtable(crl, 0);
+ rc = internalShrinkCRLtable(crl, 0);
-#ifdef USE_MULTITHREADING
- psUnlockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
+# ifdef USE_MULTITHREADING
+ psUnlockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
- return rc;
+ return rc;
}
/* Remove a CRL from g_CRL and free the associated CRL */
int psCRL_Delete(psX509Crl_t *crl)
{
- int rc;
+ int rc;
-#ifdef USE_MULTITHREADING
- psLockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
+# ifdef USE_MULTITHREADING
+ psLockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
- rc = internalShrinkCRLtable(crl, 1);
+ rc = internalShrinkCRLtable(crl, 1);
-#ifdef USE_MULTITHREADING
- psUnlockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
- return rc;
+# ifdef USE_MULTITHREADING
+ psUnlockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
+ return rc;
}
/* Remove all CRLs from g_CRL but don't free the associated memory. Assumes
- the user will be using psX509FreeCRL later */
+ the user will be using psX509FreeCRL later */
void psCRL_RemoveAll()
{
- psX509Crl_t *curr, *next;
-
-#ifdef USE_MULTITHREADING
- psLockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
- curr = g_CRL;
- next = curr->next;
- while (next) {
- next = curr->next;
- curr->next = NULL;
- curr = next;
- }
- g_CRL = NULL;
-#ifdef USE_MULTITHREADING
- psUnlockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
+ psX509Crl_t *curr, *next;
+
+# ifdef USE_MULTITHREADING
+ psLockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
+ curr = g_CRL;
+ next = curr->next;
+ while (next)
+ {
+ next = curr->next;
+ curr->next = NULL;
+ curr = next;
+ }
+ g_CRL = NULL;
+# ifdef USE_MULTITHREADING
+ psUnlockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
}
/* Remove all CRLs from g_CRL and free the associated memory */
void psCRL_DeleteAll()
{
- psX509Crl_t *curr, *next;
+ psX509Crl_t *curr, *next;
-#ifdef USE_MULTITHREADING
- psLockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
-
- curr = g_CRL;
- while (curr) {
- next = curr->next;
- internalShrinkCRLtable(curr, 1);
- curr = next;
- }
- psAssert(g_CRL == NULL);
-#ifdef USE_MULTITHREADING
- psUnlockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
+# ifdef USE_MULTITHREADING
+ psLockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
+
+ curr = g_CRL;
+ while (curr)
+ {
+ next = curr->next;
+ internalShrinkCRLtable(curr, 1);
+ curr = next;
+ }
+ psAssert(g_CRL == NULL);
+# ifdef USE_MULTITHREADING
+ psUnlockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
}
/* Helpers to see if the two CRLs are from the same issuer */
int32 internalCRLmatch(psX509Crl_t *existing, psX509Crl_t *new)
{
- /* Same DN? */
- if (memcmpct(existing->issuer.hash, new->issuer.hash, SHA1_HASH_SIZE) != 0){
- return -1;
- }
-#ifdef ENFORCE_CRL_AUTH_KEY_ID_EXT
- /* Same AuthKeyId? */
- if (existing->extensions.ak.keyId == NULL ||
- new->extensions.ak.keyId == NULL) {
- /* Should never be possible */
- return PS_PARSE_FAIL;
- }
- if (existing->extensions.ak.keyLen != new->extensions.ak.keyLen) {
- return -1;
- }
- if (memcmpct(existing->extensions.ak.keyId, new->extensions.ak.keyId,
- new->extensions.ak.keyLen) != 0) {
- return -1;
- }
-#endif
- /* Looks like a match */
- return PS_TRUE;
+ /* Same DN? */
+ if (memcmpct(existing->issuer.hash, new->issuer.hash, SHA1_HASH_SIZE) != 0)
+ {
+ return -1;
+ }
+# ifdef ENFORCE_CRL_AUTH_KEY_ID_EXT
+ /* Same AuthKeyId? */
+ if (existing->extensions.ak.keyId == NULL ||
+ new->extensions.ak.keyId == NULL)
+ {
+ /* Should never be possible */
+ return PS_PARSE_FAIL;
+ }
+ if (existing->extensions.ak.keyLen != new->extensions.ak.keyLen)
+ {
+ return -1;
+ }
+ if (memcmpct(existing->extensions.ak.keyId, new->extensions.ak.keyId,
+ new->extensions.ak.keyLen) != 0)
+ {
+ return -1;
+ }
+# endif
+ /* Looks like a match */
+ return PS_TRUE;
}
/* Remove existing CRL if it exists. Append this one.
- FUTURE: Support Delta CRL */
+ FUTURE: Support Delta CRL */
int psCRL_Update(psX509Crl_t *crl, int deleteExisting)
{
- psX509Crl_t *curr, *next;
- int rc;
-
- if (crl == NULL) {
- return 0;
- }
-#ifdef USE_MULTITHREADING
- psLockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
- /* Currently no Delta CRL support so replace the CRL if we find the
- same issuer. Add otherwise. */
- curr = g_CRL;
- while (curr) {
- next = curr->next;
- if (internalCRLmatch(curr, crl) == PS_TRUE) {
- /* Just do a check to make sure the user isn't trying to update
- with the exact same CRL pointer */
- if (curr == crl) {
-#ifdef USE_MULTITHREADING
- psUnlockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
- return 0;
- }
- internalShrinkCRLtable(curr, deleteExisting);
- break;
- }
- curr = next;
- }
- rc = internalCRLInsert(crl);
-#ifdef USE_MULTITHREADING
- psUnlockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
- return rc;
+ psX509Crl_t *curr, *next;
+ int rc;
+
+ if (crl == NULL)
+ {
+ return 0;
+ }
+# ifdef USE_MULTITHREADING
+ psLockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
+ /* Currently no Delta CRL support so replace the CRL if we find the
+ same issuer. Add otherwise. */
+ curr = g_CRL;
+ while (curr)
+ {
+ next = curr->next;
+ if (internalCRLmatch(curr, crl) == PS_TRUE)
+ {
+ /* Just do a check to make sure the user isn't trying to update
+ with the exact same CRL pointer */
+ if (curr == crl)
+ {
+# ifdef USE_MULTITHREADING
+ psUnlockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
+ return 0;
+ }
+ internalShrinkCRLtable(curr, deleteExisting);
+ break;
+ }
+ curr = next;
+ }
+ rc = internalCRLInsert(crl);
+# ifdef USE_MULTITHREADING
+ psUnlockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
+ return rc;
}
/* Helper to see if we have a matching CRL for the given subject cert. So
- this means we are looking at the issuer/authority fields of the cert */
+ this means we are looking at the issuer/authority fields of the cert */
static int32 internalMatchSubject(psX509Cert_t *cert, psX509Crl_t *CRL)
{
- /* Same DN? */
- if (memcmpct(CRL->issuer.hash, cert->issuer.hash, SHA1_HASH_SIZE) != 0) {
- return PS_CERT_AUTH_FAIL_DN;
- }
-#ifdef ENFORCE_CRL_AUTH_KEY_ID_EXT
- /* Same AuthKeyId? */
- if (CRL->extensions.ak.keyId == NULL) {
- return PS_CERT_AUTH_FAIL_EXTENSION;
- }
- if (cert->extensions.ak.keyId == NULL) {
- return PS_CERT_AUTH_FAIL_EXTENSION;
- }
- if (CRL->extensions.ak.keyLen != cert->extensions.ak.keyLen) {
- return PS_CERT_AUTH_FAIL_EXTENSION;
- }
- if (memcmpct(CRL->extensions.ak.keyId, cert->extensions.ak.keyId,
- CRL->extensions.ak.keyLen) != 0) {
- return PS_CERT_AUTH_FAIL_EXTENSION;
- }
-#endif
- /* Looks good */
- return 1;
+ /* Same DN? */
+ if (memcmpct(CRL->issuer.hash, cert->issuer.hash, SHA1_HASH_SIZE) != 0)
+ {
+ return PS_CERT_AUTH_FAIL_DN;
+ }
+# ifdef ENFORCE_CRL_AUTH_KEY_ID_EXT
+ /* Same AuthKeyId? */
+ if (CRL->extensions.ak.keyId == NULL)
+ {
+ return PS_CERT_AUTH_FAIL_EXTENSION;
+ }
+ if (cert->extensions.ak.keyId == NULL)
+ {
+ return PS_CERT_AUTH_FAIL_EXTENSION;
+ }
+ if (CRL->extensions.ak.keyLen != cert->extensions.ak.keyLen)
+ {
+ return PS_CERT_AUTH_FAIL_EXTENSION;
+ }
+ if (memcmpct(CRL->extensions.ak.keyId, cert->extensions.ak.keyId,
+ CRL->extensions.ak.keyLen) != 0)
+ {
+ return PS_CERT_AUTH_FAIL_EXTENSION;
+ }
+# endif
+ /* Looks good */
+ return 1;
}
/* Check if nextUpdate time appears correct. Returns -1 when
timestamp was unparseable or the CRL was expired. 0 for success. */
static int32_t nextUpdateTest(const char *c, int32 timeType)
{
- int32 err;
- psBrokenDownTime_t timeNow;
- psBrokenDownTime_t nextTime;
- psBrokenDownTime_t nextTimeLinger;
+ int32 err;
+ psBrokenDownTime_t timeNow;
+ psBrokenDownTime_t nextTime;
+ psBrokenDownTime_t nextTimeLinger;
- err = psGetBrokenDownGMTime(&timeNow, 0);
- if (err != PS_SUCCESS)
- return -1;
+ err = psGetBrokenDownGMTime(&timeNow, 0);
+ if (err != PS_SUCCESS)
+ {
+ return -1;
+ }
- err = psBrokenDownTimeImport(
- &nextTime, c, strlen(c),
- timeType == ASN_UTCTIME ?
- PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0);
- if (err != PS_SUCCESS)
- return -1;
+ err = psBrokenDownTimeImport(
+ &nextTime, c, strlen(c),
+ timeType == ASN_UTCTIME ?
+ PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0);
+ if (err != PS_SUCCESS)
+ {
+ return -1;
+ }
- memcpy(&nextTimeLinger, &nextTime, sizeof nextTimeLinger);
- err = psBrokenDownTimeAdd(&nextTimeLinger, PS_CRL_TIME_LINGER);
- if (err != PS_SUCCESS)
- return -1;
+ memcpy(&nextTimeLinger, &nextTime, sizeof nextTimeLinger);
+ err = psBrokenDownTimeAdd(&nextTimeLinger, PS_CRL_TIME_LINGER);
+ if (err != PS_SUCCESS)
+ {
+ return -1;
+ }
- if (psBrokenDownTimeCmp(&timeNow, &nextTimeLinger) > 0) {
- /* nextTime is in past. */
- return -1;
- }
- return 0;
+ if (psBrokenDownTimeCmp(&timeNow, &nextTimeLinger) > 0)
+ {
+ /* nextTime is in past. */
+ return -1;
+ }
+ return 0;
}
-static psX509Crl_t* internalGetCrlForCert(psX509Cert_t *cert)
+static psX509Crl_t *internalGetCrlForCert(psX509Cert_t *cert)
{
- psX509Crl_t *curr;
+ psX509Crl_t *curr;
- if (cert == NULL) {
- return NULL;
- }
- curr = g_CRL;
- while (curr) {
- if (internalMatchSubject(cert, curr) == PS_TRUE) {
- /* This is the point where we want to make sure this CRL isn't
- expired. We do this by looking at the nextUpdate time and
- seeing if we are beyond that */
- if (nextUpdateTest(curr->nextUpdate, curr->nextUpdateType) < 0) {
- /* Got it, but it's expired */
- curr->expired = 1;
- }
- return curr;
- }
- curr = curr->next;
- }
- return NULL;
+ if (cert == NULL)
+ {
+ return NULL;
+ }
+ curr = g_CRL;
+ while (curr)
+ {
+ if (internalMatchSubject(cert, curr) == PS_TRUE)
+ {
+ /* This is the point where we want to make sure this CRL isn't
+ expired. We do this by looking at the nextUpdate time and
+ seeing if we are beyond that */
+ if (nextUpdateTest(curr->nextUpdate, curr->nextUpdateType) < 0)
+ {
+ /* Got it, but it's expired */
+ curr->expired = 1;
+ }
+ return curr;
+ }
+ curr = curr->next;
+ }
+ return NULL;
}
/* Given a cert, do we have a CRL match for the issuer?
- Return if so or NULL if not */
-psX509Crl_t* psCRL_GetCRLForCert(psX509Cert_t *cert)
+ Return if so or NULL if not */
+psX509Crl_t *psCRL_GetCRLForCert(psX509Cert_t *cert)
{
- psX509Crl_t *rc = NULL;
-#ifdef USE_MULTITHREADING
- psLockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
+ psX509Crl_t *rc = NULL;
- rc = internalGetCrlForCert(cert);
+# ifdef USE_MULTITHREADING
+ psLockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
-#ifdef USE_MULTITHREADING
- psUnlockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
- return rc;
+ rc = internalGetCrlForCert(cert);
+
+# ifdef USE_MULTITHREADING
+ psUnlockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
+ return rc;
}
-/*
- -1 no entry in the cache for this cert at all
- 0 entry is found and cert is NOT revoked
- 1 entry is found and cert IS revoked
-
- A CRL may be passed in if that specific one is being tested. Otherwise
- pass NULL to search the g_CRL
-*/
-int32_t internalCrlIsRevoked(psX509Cert_t *cert, psX509Crl_t *CRL)
+/*
+ -1 no entry in the cache for this cert at all
+ 0 entry is found and cert is NOT revoked
+ 1 entry is found and cert IS revoked
+
+ A CRL may be passed in if that specific one is being tested. Otherwise
+ pass NULL to search the g_CRL
+ */
+int32_t internalCrlIsRevoked(psX509Cert_t *cert, psX509Crl_t *CRL,
+ psBrokenDownTime_t *bdt)
{
- psX509Crl_t *crl;
- x509revoked_t *entry;
+ psX509Crl_t *crl;
+ x509revoked_t *entry;
- if (cert == NULL) {
- return -1;
- }
+ if (cert == NULL)
+ {
+ return -1;
+ }
- if (CRL) {
- crl = CRL;
- } else {
- if ((crl = internalGetCrlForCert(cert)) == NULL) {
- return -1;
- }
- }
- if (crl->revoked == NULL) {
- /* It is totally reasonable to have a CRL with no revoked certs */
- return 0;
- }
- for (entry = crl->revoked; entry != NULL; entry = entry->next) {
- if (cert->serialNumberLen == entry->serialLen) {
- if (memcmpct(cert->serialNumber, entry->serial, entry->serialLen)
- == 0) {
- return 1; /* REVOKED! */
- }
- }
- }
- return 0; /* never found it. good to go */
+ if (CRL)
+ {
+ crl = CRL;
+ }
+ else
+ {
+ if ((crl = internalGetCrlForCert(cert)) == NULL)
+ {
+ return -1;
+ }
+ }
+ if (crl->revoked == NULL)
+ {
+ /* It is totally reasonable to have a CRL with no revoked certs */
+ return 0;
+ }
+ for (entry = crl->revoked; entry != NULL; entry = entry->next)
+ {
+ if (cert->serialNumberLen == entry->serialLen)
+ {
+ if (memcmpct(cert->serialNumber, entry->serial, entry->serialLen)
+ == 0)
+ {
+ if (bdt)
+ {
+ memcpy(bdt, &entry->revocationDateBDT,
+ sizeof(psBrokenDownTime_t));
+ }
+ return 1; /* REVOKED! */
+ }
+ }
+ }
+ return 0; /* never found it. good to go */
}
-/*
- Not sure this needs to be public. The "determine" API is actually
- doing the full check
-
- -1 no entry in the cache for this cert at all
- 0 entry is found and cert is NOT revoked
- 1 entry is found and cert IS revoked
-
- A CRL may be passed in if that specific one is being tested. Otherwise
- pass NULL to search the g_CRL
-*/
+/*
+ Not sure this needs to be public. The "determine" API is actually
+ doing the full check
+
+ -1 no entry in the cache for this cert at all
+ 0 entry is found and cert is NOT revoked
+ 1 entry is found and cert IS revoked
+
+ A CRL may be passed in if that specific one is being tested. Otherwise
+ pass NULL to search the g_CRL
+ */
int32_t psCRL_isRevoked(psX509Cert_t *cert, psX509Crl_t *CRL)
{
- int32_t rc;
-#ifdef USE_MULTITHREADING
- psLockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
+ int32_t rc;
- rc = internalCrlIsRevoked(cert, CRL);
-
-#ifdef USE_MULTITHREADING
- psUnlockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
+# ifdef USE_MULTITHREADING
+ psLockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
- return rc;
+ rc = internalCrlIsRevoked(cert, CRL, NULL);
+
+# ifdef USE_MULTITHREADING
+ psUnlockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
+
+ return rc;
}
static int doesCertExpectCRL(psX509Cert_t *cert)
{
- if (cert->extensions.crlDist) {
- return PS_TRUE;
- }
- return PS_FALSE;
+ if (cert->extensions.crlDist)
+ {
+ return PS_TRUE;
+ }
+ return PS_FALSE;
+}
+
+/*
+ Uses the psCRL_ format to highlight the use of g_CRL cache
+
+ Updates the "revokedStatus" member of a psX509Cert_t based on information
+ from within the cert itself and on the revocation status if a g_CRL entry
+ is found.
+ */
+int32_t psCRL_determineRevokedStatusBDT(psX509Cert_t *cert,
+ psBrokenDownTime_t *bdt)
+{
+ psX509Crl_t *crl;
+ int expectCrl;
+ int32_t revoked;
+
+ if (cert == NULL)
+ {
+ return 0;
+ }
+# ifdef USE_MULTITHREADING
+ psLockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
+
+ crl = internalGetCrlForCert(cert);
+
+ if (crl)
+ {
+ /* Not going to move along if the CRL has expired */
+ if (crl->expired)
+ {
+ cert->revokedStatus = CRL_CHECK_CRL_EXPIRED;
+# ifdef USE_MULTITHREADING
+ psUnlockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
+ return cert->revokedStatus;
+ }
+
+ /* If we now have a CRL that is not authenticated yet, let's see if
+ if our subject happens to have a parent that we can try against.
+ This case happens if a CRL for an child certificate was
+ fetched out-of-handshake and now a reconnection attempt is being
+ made. We now have the parent for that child cert and can
+ attempt to authenticate */
+ if (crl->authenticated == 0 && cert->next)
+ {
+ psX509AuthenticateCRL(cert->next, crl, NULL);
+ }
+
+ /* test it and set the status */
+ revoked = internalCrlIsRevoked(cert, crl, bdt);
+ if (revoked == 0 && crl->authenticated == 1)
+ {
+ cert->revokedStatus = CRL_CHECK_PASSED_AND_AUTHENTICATED;
+
+ }
+ else if (revoked == 0 && crl->authenticated == 0)
+ {
+ cert->revokedStatus = CRL_CHECK_PASSED_BUT_NOT_AUTHENTICATED;
+
+ }
+ else if (revoked == 1 && crl->authenticated == 1)
+ {
+ cert->revokedStatus = CRL_CHECK_REVOKED_AND_AUTHENTICATED;
+
+ }
+ else if (revoked == 1 && crl->authenticated == 0)
+ {
+ cert->revokedStatus = CRL_CHECK_REVOKED_BUT_NOT_AUTHENTICATED;
+
+ }
+ else
+ {
+ psTraceCrypto("Unexpected revoked/authenticated combo\n");
+ }
+ }
+ else
+ {
+ expectCrl = doesCertExpectCRL(cert);
+ if (expectCrl)
+ {
+ cert->revokedStatus = CRL_CHECK_EXPECTED; /* but no entry */
+ }
+ else
+ {
+ cert->revokedStatus = CRL_CHECK_NOT_EXPECTED;
+ }
+ }
+# ifdef USE_MULTITHREADING
+ psUnlockMutex(&g_crlTableLock);
+# endif /* USE_MULTITHREADING */
+ return cert->revokedStatus;
}
-/*
- Uses the psCRL_ format to highlight the use of g_CRL cache
-
- Updates the "revokedStatus" member of a psX509Cert_t based on information
- from within the cert itself and on the revocation status if a g_CRL entry
- is found.
-*/
int32_t psCRL_determineRevokedStatus(psX509Cert_t *cert)
{
- psX509Crl_t *crl;
- int expectCrl;
- int32_t revoked;
-
- if (cert == NULL) {
- return 0;
- }
-#ifdef USE_MULTITHREADING
- psLockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
-
- crl = internalGetCrlForCert(cert);
-
- if (crl) {
- /* Not going to move along if the CRL has expired */
- if (crl->expired) {
- cert->revokedStatus = CRL_CHECK_CRL_EXPIRED;
-#ifdef USE_MULTITHREADING
- psUnlockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
- return cert->revokedStatus;
- }
-
- /* If we now have a CRL that is not authenticated yet, let's see if
- if our subject happens to have a parent that we can try against.
- This case happens if a CRL for an child certificate was
- fetched out-of-handshake and now a reconnection attempt is being
- made. We now have the parent for that child cert and can
- attempt to authenticate */
- if (crl->authenticated == 0 && cert->next) {
- psX509AuthenticateCRL(cert->next, crl, NULL);
- }
-
- /* test it and set the status */
- revoked = internalCrlIsRevoked(cert, crl);
- if (revoked == 0 && crl->authenticated == 1) {
- cert->revokedStatus = CRL_CHECK_PASSED_AND_AUTHENTICATED;
-
- } else if (revoked == 0 && crl->authenticated == 0) {
- cert->revokedStatus = CRL_CHECK_PASSED_BUT_NOT_AUTHENTICATED;
-
- } else if (revoked == 1 && crl->authenticated == 1) {
- cert->revokedStatus = CRL_CHECK_REVOKED_AND_AUTHENTICATED;
-
- } else if (revoked == 1 && crl->authenticated == 0) {
- cert->revokedStatus = CRL_CHECK_REVOKED_BUT_NOT_AUTHENTICATED;
-
- } else {
- psTraceCrypto("Unexpected revoked/authenticated combo\n");
- }
- } else {
- expectCrl = doesCertExpectCRL(cert);
- if (expectCrl) {
- cert->revokedStatus = CRL_CHECK_EXPECTED; /* but no entry */
- } else {
- cert->revokedStatus = CRL_CHECK_NOT_EXPECTED;
- }
- }
-#ifdef USE_MULTITHREADING
- psUnlockMutex(&g_crlTableLock);
-#endif /* USE_MULTITHREADING */
- return cert->revokedStatus;
+ return psCRL_determineRevokedStatusBDT(cert, NULL);
}
/********************* end of psCRL_ family of APIs ***************************/
@@ -558,567 +644,583 @@ int32_t psCRL_determineRevokedStatus(psX509Cert_t *cert)
/******************************************************************************/
static void x509FreeRevoked(x509revoked_t **revoked, psPool_t *pool)
{
- x509revoked_t *next, *curr = *revoked;
+ x509revoked_t *next, *curr = *revoked;
- while (curr) {
- next = curr->next;
- psFree(curr->serial, pool);
- psFree(curr, pool);
- curr = next;
- }
- *revoked = NULL;
+ while (curr)
+ {
+ next = curr->next;
+ psFree(curr->serial, pool);
+ psFree(curr, pool);
+ curr = next;
+ }
+ *revoked = NULL;
}
static void internalFreeCRL(psX509Crl_t *crl)
{
- psPool_t *pool;
-
- if (crl == NULL) {
- return;
- }
- /* test all components for NULL. This is used for freeing during
- parse so some might not be there at all */
- pool = crl->pool;
+ psPool_t *pool;
- psX509FreeDNStruct(&crl->issuer, pool);
- x509FreeExtensions(&crl->extensions);
- x509FreeRevoked(&crl->revoked, pool);
- psFree(crl->sig, pool);
- psFree(crl->nextUpdate, pool);
-
- memset(crl, 0, sizeof(psX509Crl_t));
- psFree(crl, pool);
+ if (crl == NULL)
+ {
+ return;
+ }
+ /* test all components for NULL. This is used for freeing during
+ parse so some might not be there at all */
+ pool = crl->pool;
+
+ psX509FreeDNStruct(&crl->issuer, pool);
+ x509FreeExtensions(&crl->extensions);
+ x509FreeRevoked(&crl->revoked, pool);
+ psFree(crl->sig, pool);
+ psFree(crl->nextUpdate, pool);
+
+ memset(crl, 0, sizeof(psX509Crl_t));
+ psFree(crl, pool);
}
void psX509FreeCRL(psX509Crl_t *crl)
{
- if (crl == NULL) {
- return;
- }
- /* Try to delete from g_CRL list first. Will lock table */
- if (psCRL_Delete(crl)) {
- return;
- }
- internalFreeCRL(crl);
+ if (crl == NULL)
+ {
+ return;
+ }
+ /* Try to delete from g_CRL list first. Will lock table */
+ if (psCRL_Delete(crl))
+ {
+ return;
+ }
+ internalFreeCRL(crl);
}
/* Helper for psX509AuthenticateCRL to see if we have a matching CRL for
- the given issuer cert */
+ the given issuer cert */
static int32 internalMatchIssuer(psX509Cert_t *CA, psX509Crl_t *CRL)
{
- /* Ensure crlSign flag of KeyUsage for the given CA. */
- if ( ! (CA->extensions.keyUsageFlags & KEY_USAGE_CRL_SIGN)) {
- return PS_CERT_AUTH_FAIL_EXTENSION;
- }
- /* Same DN? */
- if (memcmpct(CRL->issuer.hash, CA->subject.hash, SHA1_HASH_SIZE) != 0) {
- psTraceCrypto("CRL not issued by this CA\n");
- return PS_CERT_AUTH_FAIL_DN;
- }
-#ifdef ENFORCE_CRL_AUTH_KEY_ID_EXT
- /* Same AuthKeyId? */
- if (CRL->extensions.ak.keyId == NULL) {
- psTraceCrypto("CRL does not have a AuthKeyId extension\n");
- return PS_CERT_AUTH_FAIL_EXTENSION;
- }
- if (CA->extensions.sk.id == NULL) {
- psTraceCrypto("CA does not have a SubjectKeyId extension\n");
- return PS_CERT_AUTH_FAIL_EXTENSION;
- }
- if (CRL->extensions.ak.keyLen != CA->extensions.sk.len) {
- psTraceCrypto("CRL issuer does not have same AuthKeyId as CA\n");
- return PS_CERT_AUTH_FAIL_EXTENSION;
- }
- if (memcmpct(CRL->extensions.ak.keyId, CA->extensions.sk.id,
- CRL->extensions.ak.keyLen) != 0) {
- psTraceCrypto("CRL issuer does not have same AuthKeyId as CA\n");
- return PS_CERT_AUTH_FAIL_EXTENSION;
- }
-#endif
- /* Looks good */
- return 1;
+ /* Ensure crlSign flag of KeyUsage for the given CA. */
+ if ( !(CA->extensions.keyUsageFlags & KEY_USAGE_CRL_SIGN))
+ {
+# ifndef ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE
+ /*
+ Fail if there is no keyUsage extension or the cRLSign flag
+ is not set.
+ */
+ return PS_CERT_AUTH_FAIL_EXTENSION;
+# else
+ /*
+ Allow missing cRLSign flag when there is no keyUsage extension.
+ */
+ if (CA->extensions.keyUsageFlags != 0) /* RFC 5280: at least one bit
+ must be 1 when keyUsage
+ is present. */
+ {
+ return PS_CERT_AUTH_FAIL_EXTENSION;
+ }
+# endif /* !ALLOW_CRL_ISSUERS_WITHOUT_KEYUSAGE */
+ }
+
+ /* Same DN? */
+ if (memcmpct(CRL->issuer.hash, CA->subject.hash, SHA1_HASH_SIZE) != 0)
+ {
+ psTraceCrypto("CRL not issued by this CA\n");
+ return PS_CERT_AUTH_FAIL_DN;
+ }
+# ifdef ENFORCE_CRL_AUTH_KEY_ID_EXT
+ /* Same AuthKeyId? */
+ if (CRL->extensions.ak.keyId == NULL)
+ {
+ psTraceCrypto("CRL does not have a AuthKeyId extension\n");
+ return PS_CERT_AUTH_FAIL_EXTENSION;
+ }
+ if (CA->extensions.sk.id == NULL)
+ {
+ psTraceCrypto("CA does not have a SubjectKeyId extension\n");
+ return PS_CERT_AUTH_FAIL_EXTENSION;
+ }
+ if (CRL->extensions.ak.keyLen != CA->extensions.sk.len)
+ {
+ psTraceCrypto("CRL issuer does not have same AuthKeyId as CA\n");
+ return PS_CERT_AUTH_FAIL_EXTENSION;
+ }
+ if (memcmpct(CRL->extensions.ak.keyId, CA->extensions.sk.id,
+ CRL->extensions.ak.keyLen) != 0)
+ {
+ psTraceCrypto("CRL issuer does not have same AuthKeyId as CA\n");
+ return PS_CERT_AUTH_FAIL_EXTENSION;
+ }
+# endif
+ /* Looks good */
+ return 1;
}
-/*
- NO g_CRL used at all
-
- Worth noting that the authenticated state is reset each time this is
- called so it shouldn't be called blindly in a loop hoping the status
- will come out correctly.
-
- poolUserPtr is for the TMP_PKI pool
+/*
+ NO g_CRL used at all
+
+ Worth noting that the authenticated state is reset each time this is
+ called so it shouldn't be called blindly in a loop hoping the status
+ will come out correctly.
+
+ poolUserPtr is for the TMP_PKI pool
*/
-int32_t psX509AuthenticateCRL(psX509Cert_t *CA, psX509Crl_t *CRL,
- void *poolUserPtr)
+int32_t psX509AuthenticateCRL(psX509Cert_t *CA, psX509Crl_t *CRL,
+ void *poolUserPtr)
{
- int32 rc, sigType;
- unsigned char sigOut[SHA512_HASH_SIZE];
- psPool_t *pkiPool = MATRIX_NO_POOL;
-
- if (CA == NULL || CRL == NULL) {
- return PS_ARG_FAIL;
- }
- if (CRL->authenticated == 1) {
- /* Going to have to assume caller knows what they are doing */
- psTraceCrypto("WARNING: this CRL has already been authenticated\n");
- }
- CRL->authenticated = 0;
-
- /* A few tests to see if this CA is the true issuer of the CRL */
- if ((rc = internalMatchIssuer(CA, CRL)) < 0) {
- return rc;
- }
-
- /* Determine digest and signature algorithms. */
- switch (CRL->sigAlg) {
-#ifdef ENABLE_MD5_SIGNED_CERTS
- case OID_MD5_RSA_SIG:
- sigType = PS_RSA;
- break;
-#endif
-#ifdef ENABLE_SHA1_SIGNED_CERTS
- case OID_SHA1_RSA_SIG:
- sigType = PS_RSA;
- break;
-#ifdef USE_ECC
- case OID_SHA1_ECDSA_SIG:
- sigType = PS_ECC;
- break;
-#endif /* USE_ECC */
-#endif /* ENABLE_SHA1_SIGNED_CERTS */
-#ifdef USE_SHA256
- case OID_SHA256_RSA_SIG:
- sigType = PS_RSA;
- break;
-#ifdef USE_ECC
- case OID_SHA256_ECDSA_SIG:
- sigType = PS_ECC;
- break;
-#endif /* USE_ECC */
-#endif /* USE_SHA256 */
-#ifdef USE_SHA384
- case OID_SHA384_RSA_SIG:
- sigType = PS_RSA;
- break;
-#ifdef USE_ECC
- case OID_SHA384_ECDSA_SIG:
- sigType = PS_ECC;
- break;
-#endif /* USE_ECC */
-#endif /* USE_SHA384 */
-#ifdef USE_SHA512
- case OID_SHA512_RSA_SIG:
- sigType = PS_RSA;
- break;
-#ifdef USE_ECC
- case OID_SHA512_ECDSA_SIG:
- sigType = PS_ECC;
- break;
-#endif /* USE_ECC */
-#endif /* USE_SHA512 */
- default:
- psTraceCrypto("Need more signature alg support for CRL\n");
- return PS_UNSUPPORTED_FAIL;
- }
+ int32 rc;
- /* Perform the signature verification. */
+ psBool_t verifyResult = PS_FALSE;
+ psVerifySigOptions_t opts;
- if (sigType == PS_RSA) {
- rc = pubRsaDecryptSignedElement(pkiPool, &CA->publicKey.key.rsa,
- CRL->sig, CRL->sigLen, sigOut, CRL->sigHashLen, NULL);
- if (rc < 0) {
- psTraceCrypto("Unable to RSA decrypt CRL signature\n");
- return rc;
- }
- if (memcmpct(CRL->sigHash, sigOut, CRL->sigHashLen) != 0) {
- psTraceCrypto("Unable to verify CRL signature\n");
- return PS_CERT_AUTH_FAIL_SIG;
- }
- } else if (sigType == PS_ECC) {
- int32_t status;
-#ifdef USE_ECC
- rc = psEccDsaVerify(pkiPool, &CA->publicKey.key.ecc,
- CRL->sigHash, CRL->sigHashLen, CRL->sig, CRL->sigLen, &status,
- NULL);
-#else
- rc = PS_DISABLED_FEATURE_FAIL;
-#endif /* USE_ECC */
- if (status != 1) {
- psTraceCrypto("Unable to verify ECDSA CRL signature\n");
- return PS_CERT_AUTH_FAIL_SIG;
- }
- }
-
- CRL->authenticated = PS_TRUE;
-
- return PS_SUCCESS;
+ if (CA == NULL || CRL == NULL)
+ {
+ return PS_ARG_FAIL;
+ }
+ if (CRL->authenticated == 1)
+ {
+ /* Going to have to assume caller knows what they are doing */
+ psTraceCrypto("WARNING: this CRL has already been authenticated\n");
+ }
+ CRL->authenticated = PS_FALSE;
+
+ /* A few tests to see if this CA is the true issuer of the CRL */
+ if ((rc = internalMatchIssuer(CA, CRL)) < 0)
+ {
+ return rc;
+ }
+
+ /* Perform the signature verification. */
+ memset(&opts, 0, sizeof(psVerifySigOptions_t));
+ rc = psVerifySig(NULL,
+ CRL->sigHash, CRL->sigHashLen,
+ CRL->sig, CRL->sigLen,
+ &CA->publicKey,
+ CRL->sigAlg,
+ &verifyResult,
+ &opts);
+ if (rc != PS_SUCCESS)
+ {
+ if (verifyResult == PS_FALSE)
+ {
+ psTraceCrypto("Unable to verify CRL signature\n");
+ return PS_CERT_AUTH_FAIL_SIG;
+ }
+ else
+ {
+ psTraceIntCrypto("psVerifySig failed: %d\n", rc);
+ return rc;
+ }
+ }
+
+ if (verifyResult == PS_TRUE)
+ {
+ CRL->authenticated = PS_TRUE;
+ }
+
+ return PS_SUCCESS;
}
+int32 psX509GetCRLVersion(const unsigned char *crlBin, int32 crlBinLen)
+{
+ int version;
+ uint32_t glen, tbsCertLen;
+ const unsigned char *end, *p = crlBin;
+
+ if (crlBin == NULL || crlBinLen <= 0)
+ {
+ return PS_ARG_FAIL;
+ }
+ end = p + crlBinLen;
+ if (getAsnSequence32(&p, (uint32) (end - p), &glen, 0) < 0)
+ {
+ psTraceCrypto("Initial parse error in psX509GetCRLVersion\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnSequence32(&p, (uint32) (end - p), &tbsCertLen, 0) < 0)
+ {
+ psTraceCrypto("Initial parse error in psX509GetCRLVersion\n");
+ return PS_PARSE_FAIL;
+ }
+ if (end > p && *p == ASN_INTEGER)
+ {
+ version = 0;
+ if (getAsnInteger(&p, (uint32) (end - p), &version) < 0 || version < 0)
+ {
+ psTraceCrypto("Version parse error in psX509GetCRLVersion.\n");
+ return PS_PARSE_FAIL;
+ }
+ return (int32) version;
+ }
+ return 1; /* Default version (v2). */
+}
/*
- Parse a CRL.
-*/
+ Parse a CRL.
+ */
int32 psX509ParseCRL(psPool_t *pool, psX509Crl_t **crl, unsigned char *crlBin,
- int32 crlBinLen)
+ int32 crlBinLen)
{
- const unsigned char *end, *start, *sigStart, *sigEnd, *revStart, *p = crlBin;
- int32 oi, version, rc;
- x509revoked_t *curr, *next;
- psDigestContext_t hashCtx;
- psX509Crl_t *lcrl;
- uint32_t glen, ilen, tbsCertLen;
- uint16_t timelen, plen;
+ const unsigned char *end, *start, *sigStart, *sigEnd, *revStart, *p = crlBin;
+ int32 oi, version, rc;
+ x509revoked_t *curr, *next;
+ psX509Crl_t *lcrl;
+ uint32_t glen, ilen, tbsCertLen;
+ psSize_t timelen, plen;
+ unsigned char timetag;
- if (crlBin == NULL || crlBinLen <= 0) {
- return PS_ARG_FAIL;
- }
- end = p + crlBinLen;
- /*
- CertificateList ::= SEQUENCE {
- tbsCertList TBSCertList,
- signatureAlgorithm AlgorithmIdentifier,
- signatureValue BIT STRING }
+ if (crlBin == NULL || crlBinLen <= 0)
+ {
+ return PS_ARG_FAIL;
+ }
+ end = p + crlBinLen;
+ /*
+ CertificateList ::= SEQUENCE {
+ tbsCertList TBSCertList,
+ signatureAlgorithm AlgorithmIdentifier,
+ signatureValue BIT STRING }
- TBSCertList ::= SEQUENCE {
- version Version OPTIONAL,
- -- if present, shall be v2
- signature AlgorithmIdentifier,
- issuer Name,
- thisUpdate Time,
- nextUpdate Time OPTIONAL,
- revokedCertificates SEQUENCE OF SEQUENCE {
- userCertificate CertificateSerialNumber,
- revocationDate Time,
- crlEntryExtensions Extensions OPTIONAL
- -- if present, shall be v2
- } OPTIONAL,
- crlExtensions [0] EXPLICIT Extensions OPTIONAL
- -- if present, shall be v2
- }
- */
- if (getAsnSequence32(&p, (uint32)(end - p), &glen, 0) < 0) {
- psTraceCrypto("Initial parse error in psX509ParseCRL\n");
- return PS_PARSE_FAIL;
- }
+ TBSCertList ::= SEQUENCE {
+ version Version OPTIONAL,
+ -- if present, shall be v2
+ signature AlgorithmIdentifier,
+ issuer Name,
+ thisUpdate Time,
+ nextUpdate Time OPTIONAL,
+ revokedCertificates SEQUENCE OF SEQUENCE {
+ userCertificate CertificateSerialNumber,
+ revocationDate Time,
+ crlEntryExtensions Extensions OPTIONAL
+ -- if present, shall be v2
+ } OPTIONAL,
+ crlExtensions [0] EXPLICIT Extensions OPTIONAL
+ -- if present, shall be v2
+ }
+ */
+ if (getAsnSequence32(&p, (uint32) (end - p), &glen, 0) < 0)
+ {
+ psTraceCrypto("Initial parse error in psX509ParseCRL\n");
+ return PS_PARSE_FAIL;
+ }
- /* Track tbsCert for signature purposes and for encoding where there
- is no revokedCertificate entry */
- sigStart = p;
- if (getAsnSequence32(&p, (uint32)(end - p), &tbsCertLen, 0) < 0) {
- psTraceCrypto("Initial parse error in psX509ParseCRL\n");
- return PS_PARSE_FAIL;
- }
- start = p;
- if (*p == ASN_INTEGER) {
- version = 0;
- if (getAsnInteger(&p, (uint32)(end - p), &version) < 0 || version != 1){
- psTraceIntCrypto("Version parse error in psX509ParseCRL %d\n",
- version);
- return PS_PARSE_FAIL;
- }
- }
-
- /* looking correct. Allocate the psX509Crl_t */
- if ((lcrl = psMalloc(pool, sizeof(psX509Crl_t))) == NULL) {
- return PS_MEM_FAIL;
- }
- memset(lcrl, 0, sizeof(psX509Crl_t));
- lcrl->pool = pool;
-
- /* signature */
- if (getAsnAlgorithmIdentifier(&p, (int32)(end - p), &lcrl->sigAlg, &plen)
- < 0) {
- psTraceCrypto("Couldn't parse crl sig algorithm identifier\n");
- psX509FreeCRL(lcrl);
- return PS_PARSE_FAIL;
- }
+ /* Track tbsCert for signature purposes and for encoding where there
+ is no revokedCertificate entry */
+ sigStart = p;
+ if (getAsnSequence32(&p, (uint32) (end - p), &tbsCertLen, 0) < 0)
+ {
+ psTraceCrypto("Initial parse error in psX509ParseCRL\n");
+ return PS_PARSE_FAIL;
+ }
+ start = p;
+ if (end > p && *p == ASN_INTEGER)
+ {
+ version = 0;
+ if (getAsnInteger(&p, (uint32) (end - p), &version) < 0 || version < 0)
+ {
+ psTraceCrypto("Version parse error in psX509ParseCRL.\n");
+ return PS_PARSE_FAIL;
+ }
+ if (version != 1)
+ {
+ psTraceIntCrypto("Version parse: unsupported version requested: "
+ "%d\n", version);
+ return PS_VERSION_UNSUPPORTED;
+ }
+ }
- /*
- Name ::= CHOICE { -- only one possibility for now --
- rdnSequence RDNSequence }
+ /* looking correct. Allocate the psX509Crl_t */
+ if ((lcrl = psMalloc(pool, sizeof(psX509Crl_t))) == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ memset(lcrl, 0, sizeof(psX509Crl_t));
+ lcrl->pool = pool;
- RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+ /* signature */
+ if (getAsnAlgorithmIdentifier(&p, (int32) (end - p), &lcrl->sigAlg, &plen)
+ < 0)
+ {
+ psTraceCrypto("Couldn't parse crl sig algorithm identifier\n");
+ psX509FreeCRL(lcrl);
+ return PS_PARSE_FAIL;
+ }
- DistinguishedName ::= RDNSequence
+ /*
+ Name ::= CHOICE { -- only one possibility for now --
+ rdnSequence RDNSequence }
- RelativeDistinguishedName ::=
- SET SIZE (1 .. MAX) OF AttributeTypeAndValue
- */
- if ((rc = psX509GetDNAttributes(pool, &p, (uint32)(end - p),
- &lcrl->issuer, 0)) < 0) {
- psX509FreeCRL(lcrl);
- psTraceCrypto("Couldn't parse crl issuer DN attributes\n");
- return rc;
- }
+ RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
- /* thisUpdate TIME */
- if ((end - p) < 1 || ((*p != ASN_UTCTIME) && (*p != ASN_GENERALIZEDTIME))) {
- psTraceCrypto("Malformed thisUpdate CRL\n");
- psX509FreeCRL(lcrl);
- return PS_PARSE_FAIL;
- }
- p++;
- if (getAsnLength(&p, (uint32)(end - p), &timelen) < 0 ||
- (uint32)(end - p) < timelen) {
- psTraceCrypto("Malformed thisUpdate CRL\n");
- psX509FreeCRL(lcrl);
- return PS_PARSE_FAIL;
- }
- p += timelen; /* Skip it. Only concerned with expiration */
- /* nextUpdateTIME - Optional... but required by spec */
- if ((end - p) < 1 || ((*p == ASN_UTCTIME) || (*p == ASN_GENERALIZEDTIME))) {
- lcrl->nextUpdateType = *p;
- p++;
- if (getAsnLength(&p, (uint32)(end - p), &timelen) < 0 ||
- (uint32)(end - p) < timelen) {
- psTraceCrypto("Malformed nextUpdateTIME CRL\n");
- psX509FreeCRL(lcrl);
- return PS_PARSE_FAIL;
- }
- if ((lcrl->nextUpdate = psMalloc(pool, timelen + 1)) == NULL) {
- psX509FreeCRL(lcrl);
- return PS_PARSE_FAIL;
- }
- memcpy(lcrl->nextUpdate, p, timelen);
- lcrl->nextUpdate[timelen] = '\0';
- p += timelen;
-
- }
-
-
- /* Need to see if any data left in tbsCertList. Could be no revocations */
- if ((p - start) != tbsCertLen) {
- /*
- revokedCertificates SEQUENCE OF SEQUENCE {
- userCertificate CertificateSerialNumber,
- revocationDate Time,
- crlEntryExtensions Extensions OPTIONAL
- -- if present, shall be v2
- } OPTIONAL,
- */
-
- /* Need to peek at next byte to make sure there are some revoked
- certs here. Could be jumping right to crlExtensions */
- if (*p != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
-
- if (getAsnSequence32(&p, (uint32)(end - p), &glen, 0) < 0) {
- psTraceCrypto("Initial revokedCert error in psX509ParseCRL\n");
- psX509FreeCRL(lcrl);
- return PS_PARSE_FAIL;
- }
+ DistinguishedName ::= RDNSequence
- lcrl->revoked = curr = psMalloc(pool, sizeof(x509revoked_t));
- if (curr == NULL) {
- psX509FreeCRL(lcrl);
- return PS_MEM_FAIL;
- }
- memset(curr, 0x0, sizeof(x509revoked_t));
- while (glen > 0) {
- revStart = p;
- if (getAsnSequence32(&p, (uint32)(end - p), &ilen, 0) < 0) {
- psTraceCrypto("Deep revokedCert error in psX509ParseCRL\n");
- psX509FreeCRL(lcrl);
- return PS_PARSE_FAIL;
- }
- start = p; /* reusing start */
- if ((rc = getSerialNum(pool, &p, ilen, &curr->serial,
- &curr->serialLen)) < 0) {
- psTraceCrypto("ASN serial number parse error\n");
- psX509FreeCRL(lcrl);
- return rc;
- }
- /* skipping time and crlEntryExtensions */
- p += ilen - (uint32)(p - start);
- if (glen < (uint32)(p - revStart)) {
- psTraceCrypto("Deeper revokedCert err in psX509ParseCRL\n");
- psX509FreeCRL(lcrl);
- return PS_PARSE_FAIL;
- }
- glen -= (uint32)(p - revStart);
+ RelativeDistinguishedName ::=
+ SET SIZE (1 .. MAX) OF AttributeTypeAndValue
+ */
+ if ((rc = psX509GetDNAttributes(pool, &p, (uint32) (end - p),
+ &lcrl->issuer, 0)) < 0)
+ {
+ psX509FreeCRL(lcrl);
+ psTraceCrypto("Couldn't parse crl issuer DN attributes\n");
+ return rc;
+ }
- // psTraceBytes("revoked", curr->serial, curr->serialLen);
- if (glen > 0) {
- if ((next = psMalloc(pool, sizeof(x509revoked_t))) == NULL){
- psX509FreeCRL(lcrl);
- return PS_MEM_FAIL;
- }
- memset(next, 0x0, sizeof(x509revoked_t));
- curr->next = next;
- curr = next;
- }
- }
- }
- /* Always treated as OPTIONAL */
- if (getExplicitExtensions(pool, &p, (uint32)(end - p), 0,
- &lcrl->extensions, 0) < 0) {
- psTraceCrypto("Extension parse error in psX509ParseCRL\n");
- psX509FreeCRL(lcrl);
- return PS_PARSE_FAIL;
- }
- //if (lcrl->extensions.ak.keyId) {
- // psTraceBytes("CRL ak", lcrl->extensions.ak.keyId, 20);
- //}
- } /* End tbsCertList */
- sigEnd = p;
+ /* thisUpdate TIME */
+ if ((end - p) < 1 || ((*p != ASN_UTCTIME) && (*p != ASN_GENERALIZEDTIME)))
+ {
+ psTraceCrypto("Malformed thisUpdate CRL\n");
+ psX509FreeCRL(lcrl);
+ return PS_PARSE_FAIL;
+ }
+ timetag = *p;
+ p++;
+ if (getAsnLength(&p, (uint32) (end - p), &timelen) < 0 ||
+ (uint32) (end - p) < timelen)
+ {
+ psTraceCrypto("Malformed thisUpdate CRL\n");
+ psX509FreeCRL(lcrl);
+ return PS_PARSE_FAIL;
+ }
+ if (psBrokenDownTimeImport(
+ &lcrl->thisUpdateBDT, (const char *) p, timelen,
+ timetag == ASN_UTCTIME ?
+ PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0) != PS_SUCCESS)
+ {
+ psTraceCrypto("Malformed thisUpdate CRL\n");
+ psX509FreeCRL(lcrl);
+ return PS_PARSE_FAIL;
+ }
- if (getAsnAlgorithmIdentifier(&p, (int32)(end - p), &oi, &plen) < 0) {
- psX509FreeCRL(lcrl);
- psTraceCrypto("Couldn't parse crl sig algorithm identifier\n");
- return PS_PARSE_FAIL;
- }
- /* must match */
- if (oi != lcrl->sigAlg) {
- psTraceCrypto("Couldn't match crl sig algorithm identifier\n");
- psX509FreeCRL(lcrl);
- return PS_PARSE_FAIL;
- }
+ p += timelen; /* Move p beyond thisUpdate TIME. */
- if ((rc = psX509GetSignature(pool, &p, (uint32)(end - p), &lcrl->sig,
- &lcrl->sigLen)) < 0) {
- psX509FreeCRL(lcrl);
- psTraceCrypto("Couldn't parse signature\n");
- return rc;
- }
-
- /* Perform the hashing for later auth */
- switch (lcrl->sigAlg) {
-#ifdef ENABLE_MD5_SIGNED_CERTS
- case OID_MD5_RSA_SIG:
- lcrl->sigHashLen = MD5_HASH_SIZE;
- break;
-#endif
-#ifdef ENABLE_SHA1_SIGNED_CERTS
- case OID_SHA1_RSA_SIG:
- lcrl->sigHashLen = SHA1_HASH_SIZE;
- break;
-#ifdef USE_ECC
- case OID_SHA1_ECDSA_SIG:
- lcrl->sigHashLen = SHA1_HASH_SIZE;
- break;
-#endif /* USE_ECC */
-#endif /* ENABLE_SHA1_SIGNED_CERTS */
-#ifdef USE_SHA256
- case OID_SHA256_RSA_SIG:
- lcrl->sigHashLen = SHA256_HASH_SIZE;
- break;
-#ifdef USE_ECC
- case OID_SHA256_ECDSA_SIG:
- lcrl->sigHashLen = SHA256_HASH_SIZE;
- break;
-#endif /* USE_ECC */
-#endif /* USE_SHA256 */
-#ifdef USE_SHA384
- case OID_SHA384_RSA_SIG:
- lcrl->sigHashLen = SHA384_HASH_SIZE;
- break;
-#ifdef USE_ECC
- case OID_SHA384_ECDSA_SIG:
- lcrl->sigHashLen = SHA384_HASH_SIZE;
- break;
-#endif /* USE_ECC */
-#endif /* USE_SHA384 */
-#ifdef USE_SHA512
- case OID_SHA512_RSA_SIG:
- lcrl->sigHashLen = SHA512_HASH_SIZE;
- break;
-#ifdef USE_ECC
- case OID_SHA512_ECDSA_SIG:
- lcrl->sigHashLen = SHA512_HASH_SIZE;
- break;
-#endif /* USE_ECC */
-#endif /* USE_SHA512 */
- default:
- psX509FreeCRL(lcrl);
- psTraceCrypto("Need more signature alg support for CRL\n");
- return PS_UNSUPPORTED_FAIL;
- }
+ /* nextUpdateTIME - Optional... but required by spec */
+ if ((end - p) < 1 || ((*p == ASN_UTCTIME) || (*p == ASN_GENERALIZEDTIME)))
+ {
+ lcrl->nextUpdateType = timetag = *p;
+ p++;
+ if (getAsnLength(&p, (uint32) (end - p), &timelen) < 0 ||
+ (uint32) (end - p) < timelen)
+ {
+ psTraceCrypto("Malformed nextUpdateTIME CRL\n");
+ psX509FreeCRL(lcrl);
+ return PS_PARSE_FAIL;
+ }
+ if ((lcrl->nextUpdate = psMalloc(pool, timelen + 1)) == NULL)
+ {
+ psX509FreeCRL(lcrl);
+ return PS_PARSE_FAIL;
+ }
+ memcpy(lcrl->nextUpdate, p, timelen);
+ lcrl->nextUpdate[timelen] = '\0';
- switch(lcrl->sigHashLen) {
-#ifdef ENABLE_MD5_SIGNED_CERTS
- case MD5_HASH_SIZE:
- psMd5Init(&hashCtx.md5);
- psMd5Update(&hashCtx.md5, sigStart, (uint32)(sigEnd - sigStart));
- psMd5Final(&hashCtx.md5, lcrl->sigHash);
- break;
-#endif /* ENABLE_MD5_SIGNED_CERTS */
-#ifdef ENABLE_SHA1_SIGNED_CERTS
- case SHA1_HASH_SIZE:
- psSha1PreInit(&hashCtx.sha1);
- psSha1Init(&hashCtx.sha1);
- psSha1Update(&hashCtx.sha1, sigStart, (uint32)(sigEnd - sigStart));
- psSha1Final(&hashCtx.sha1, lcrl->sigHash);
- break;
-#endif /* ENABLE_SHA1_SIGNED_CERTS */
-#ifdef USE_SHA256
- case SHA256_HASH_SIZE:
- psSha256PreInit(&hashCtx.sha256);
- psSha256Init(&hashCtx.sha256);
- psSha256Update(&hashCtx.sha256, sigStart, (uint32)(sigEnd - sigStart));
- psSha256Final(&hashCtx.sha256, lcrl->sigHash);
- break;
-#endif /* USE_SHA256 */
-#ifdef USE_SHA384
- case SHA384_HASH_SIZE:
- psSha384PreInit(&hashCtx.sha384);
- psSha384Init(&hashCtx.sha384);
- psSha384Update(&hashCtx.sha384, sigStart, (uint32)(sigEnd - sigStart));
- psSha384Final(&hashCtx.sha384, lcrl->sigHash);
- break;
-#endif /* USE_SHA384 */
-#ifdef USE_SHA512
- case SHA512_HASH_SIZE:
- psSha512PreInit(&hashCtx.sha512);
- psSha512Init(&hashCtx.sha512);
- psSha512Update(&hashCtx.sha512, sigStart, (uint32)(sigEnd - sigStart));
- psSha512Final(&hashCtx.sha512, lcrl->sigHash);
- break;
-#endif /* USE_SHA512 */
- default:
- psX509FreeCRL(lcrl);
- psTraceCrypto("Unsupported digest algorithm in CRL\n");
- return PS_UNSUPPORTED_FAIL;
- }
+ if (psBrokenDownTimeImport(
+ &lcrl->nextUpdateBDT, (const char *) p, timelen,
+ timetag == ASN_UTCTIME ?
+ PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0) != PS_SUCCESS)
+ {
+ psTraceCrypto("Malformed thisUpdate CRL\n");
+ psX509FreeCRL(lcrl);
+ return PS_PARSE_FAIL;
+ }
+ p += timelen;
- *crl = lcrl;
-
- return PS_SUCCESS;
+ /* Note: nextUpdate may be in past, but parsing does not
+ check that. */
+ }
+ else
+ {
+ memset(&lcrl->nextUpdateBDT, 0, sizeof(lcrl->nextUpdateBDT));
+ }
+
+ /* Need to see if any data left in tbsCertList. Could be no revocations */
+ if ((p - start) != tbsCertLen)
+ {
+ /*
+ revokedCertificates SEQUENCE OF SEQUENCE {
+ userCertificate CertificateSerialNumber,
+ revocationDate Time,
+ crlEntryExtensions Extensions OPTIONAL
+ -- if present, shall be v2
+ } OPTIONAL,
+ */
+
+ /* Need to peek at next byte to make sure there are some revoked
+ certs here. Could be jumping right to crlExtensions */
+ if (*p != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
+ {
+
+ if (getAsnSequence32(&p, (uint32) (end - p), &glen, 0) < 0)
+ {
+ psTraceCrypto("Initial revokedCert error in psX509ParseCRL\n");
+ psX509FreeCRL(lcrl);
+ return PS_PARSE_FAIL;
+ }
+
+ lcrl->revoked = curr = psMalloc(pool, sizeof(x509revoked_t));
+ if (curr == NULL)
+ {
+ psX509FreeCRL(lcrl);
+ return PS_MEM_FAIL;
+ }
+ memset(curr, 0x0, sizeof(x509revoked_t));
+ while (glen > 0)
+ {
+ revStart = p;
+ if (getAsnSequence32(&p, (uint32) (end - p), &ilen, 0) < 0)
+ {
+ psTraceCrypto("Deep revokedCert error in psX509ParseCRL\n");
+ psX509FreeCRL(lcrl);
+ return PS_PARSE_FAIL;
+ }
+ start = p; /* reusing start */
+ if ((rc = getSerialNum(pool, &p, ilen, &curr->serial,
+ &curr->serialLen)) < 0)
+ {
+ psTraceCrypto("ASN serial number parse error\n");
+ psX509FreeCRL(lcrl);
+ return rc;
+ }
+
+ /* revocationDate */
+ if ((end - p) < 1 || ((*p != ASN_UTCTIME) &&
+ (*p != ASN_GENERALIZEDTIME)))
+ {
+ psTraceCrypto("Malformed revocationDate CRL\n");
+ psX509FreeCRL(lcrl);
+ return PS_PARSE_FAIL;
+ }
+ timetag = *p;
+ p++;
+ if (getAsnLength(&p, (uint32) (end - p), &timelen) < 0 ||
+ (uint32) (end - p) < timelen)
+ {
+ psTraceCrypto("Malformed thisUpdate CRL\n");
+ psX509FreeCRL(lcrl);
+ return PS_PARSE_FAIL;
+ }
+ if (psBrokenDownTimeImport(
+ &curr->revocationDateBDT, (const char *) p,
+ timelen,
+ timetag == ASN_UTCTIME ?
+ PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0) !=
+ PS_SUCCESS)
+ {
+ psTraceCrypto("Malformed thisUpdate CRL\n");
+ psX509FreeCRL(lcrl);
+ return PS_PARSE_FAIL;
+ }
+
+ /* skipping crlEntryExtensions */
+ p += ilen - (uint32) (p - start);
+ if (glen < (uint32) (p - revStart))
+ {
+ psTraceCrypto("Deeper revokedCert err in psX509ParseCRL\n");
+ psX509FreeCRL(lcrl);
+ return PS_PARSE_FAIL;
+ }
+ glen -= (uint32) (p - revStart);
+
+ /* psTraceBytes("revoked", curr->serial, curr->serialLen); */
+ if (glen > 0)
+ {
+ if ((next = psMalloc(pool, sizeof(x509revoked_t))) == NULL)
+ {
+ psX509FreeCRL(lcrl);
+ return PS_MEM_FAIL;
+ }
+ memset(next, 0x0, sizeof(x509revoked_t));
+ curr->next = next;
+ curr = next;
+ }
+ }
+ }
+ /* Always treated as OPTIONAL */
+ if (getExplicitExtensions(pool, &p, (uint32) (end - p), 0,
+ &lcrl->extensions, 0) < 0)
+ {
+ psTraceCrypto("Extension parse error in psX509ParseCRL\n");
+ psX509FreeCRL(lcrl);
+ return PS_PARSE_FAIL;
+ }
+ /* if (lcrl->extensions.ak.keyId) { */
+ /* psTraceBytes("CRL ak", lcrl->extensions.ak.keyId, 20); */
+ /* } */
+ } /* End tbsCertList */
+ sigEnd = p;
+
+ if (getAsnAlgorithmIdentifier(&p, (int32) (end - p), &oi, &plen) < 0)
+ {
+ psX509FreeCRL(lcrl);
+ psTraceCrypto("Couldn't parse crl sig algorithm identifier\n");
+ return PS_PARSE_FAIL;
+ }
+ /* must match */
+ if (oi != lcrl->sigAlg)
+ {
+ psTraceCrypto("Couldn't match crl sig algorithm identifier\n");
+ psX509FreeCRL(lcrl);
+ return PS_PARSE_FAIL;
+ }
+
+ if ((rc = psX509GetSignature(pool, &p, (uint32) (end - p), &lcrl->sig,
+ &lcrl->sigLen)) < 0)
+ {
+ psX509FreeCRL(lcrl);
+ psTraceCrypto("Couldn't parse signature\n");
+ return rc;
+ }
+
+ /* Perform the hashing for later auth */
+ rc = psComputeHashForSig(sigStart, sigEnd - sigStart,
+ lcrl->sigAlg,
+ lcrl->sigHash, &lcrl->sigHashLen);
+ if (rc != PS_SUCCESS)
+ {
+ psX509FreeCRL(lcrl);
+ return rc;
+ }
+
+ *crl = lcrl;
+
+ return PS_SUCCESS;
}
/*
- If the provided cert has a URL based CRL Distribution point, return
- that. The url and urlLen point directly into the cert structure so
- must not be modified.
- */
+ If the provided cert has a URL based CRL Distribution point, return
+ that. The url and urlLen point directly into the cert structure so
+ must not be modified.
+*/
int32 psX509GetCRLdistURL(psX509Cert_t *cert, char **url, uint32_t *urlLen)
{
- x509GeneralName_t *gn;
+ x509GeneralName_t *gn;
- if (cert == NULL) {
- return PS_ARG_FAIL;
- }
- *url = NULL;
- *urlLen = 0;
+ if (cert == NULL)
+ {
+ return PS_ARG_FAIL;
+ }
+ *url = NULL;
+ *urlLen = 0;
- if (cert->extensions.crlDist != NULL) {
- gn = cert->extensions.crlDist;
- while (gn) {
- if (gn->id == 6) { /* Only pass on URI types */
- *url = (char*)gn->data;
- *urlLen = gn->dataLen;
- return PS_TRUE;
- } else {
- psTraceIntCrypto("Unsupported CRL distro point format %d\n",
- gn->id);
- }
- gn = gn->next;
- }
- }
- return PS_FALSE;
+ if (cert->extensions.crlDist != NULL)
+ {
+ gn = cert->extensions.crlDist;
+ while (gn)
+ {
+ if (gn->id == 6) /* Only pass on URI types */
+ {
+ *url = (char *) gn->data;
+ *urlLen = gn->dataLen;
+ return PS_TRUE;
+ }
+ else
+ {
+ psTraceIntCrypto("Unsupported CRL distro point format %d\n",
+ gn->id);
+ }
+ gn = gn->next;
+ }
+ }
+ return PS_FALSE;
}
/******************************************************************************/
-#endif /* USE_CERT_PARSE */
-#endif /* USE_CRL */
+# endif /* USE_CERT_PARSE */
+#endif /* USE_CRL */
diff --git a/crypto/keyformat/pkcs.c b/crypto/keyformat/pkcs.c
index 5d44a7a..3a5949a 100644
--- a/crypto/keyformat/pkcs.c
+++ b/crypto/keyformat/pkcs.c
@@ -1,1815 +1,2078 @@
/**
- * @file pkcs.c
- * @version $Format:%h%d$
+ * @file pkcs.c
+ * @version $Format:%h%d$
*
- * Collection of RSA PKCS standards .
+ * Collection of RSA PKCS standards .
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
/******************************************************************************/
/*
- Pad a value to be encrypted by RSA, according to PKCS#1 v1.5
- http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
- When encrypting a value with RSA, the value is first padded to be
- equal to the public key size using the following method:
- 00 00
- - id denotes a public or private key operation
- - if id is private, data is however many non-zero bytes it takes to pad the
- value to the key length (randomLen = keyLen - 3 - valueLen).
- - if id is public, data is FF for the same length as described above
- - There must be at least 8 bytes of data.
-*/
-int32_t pkcs1Pad(const unsigned char *in, uint16_t inlen,
- unsigned char *out, uint16_t outlen,
- uint8_t cryptType, void *userPtr)
+ Pad a value to be encrypted by RSA, according to PKCS#1 v1.5
+ http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
+ When encrypting a value with RSA, the value is first padded to be
+ equal to the public key size using the following method:
+ 00 00
+ - id denotes a public or private key operation
+ - if id is private, data is however many non-zero bytes it takes to pad the
+ value to the key length (randomLen = keyLen - 3 - valueLen).
+ - if id is public, data is FF for the same length as described above
+ - There must be at least 8 bytes of data.
+ */
+int32_t pkcs1Pad(const unsigned char *in, psSize_t inlen,
+ unsigned char *out, psSize_t outlen,
+ uint8_t cryptType, void *userPtr)
{
- unsigned char *c;
- uint32_t randomLen;
+ unsigned char *c;
+ uint32_t randomLen;
- randomLen = outlen - 3 - inlen;
- if (randomLen < 8) {
- psTraceCrypto("pkcs1Pad failure\n");
- return PS_LIMIT_FAIL;
- }
- c = out;
- *c = 0x00;
- c++;
- *c = (unsigned char)cryptType;
- c++;
- if (cryptType == PS_PUBKEY) {
- while (randomLen > 0) {
- *c++ = 0xFF;
- randomLen--;
- }
- } else {
- if (matrixCryptoGetPrngData(c, randomLen, userPtr) < 0) {
- return PS_PLATFORM_FAIL;
- }
+ randomLen = outlen - 3 - inlen;
+ if (randomLen < 8)
+ {
+ psTraceCrypto("pkcs1Pad failure\n");
+ return PS_LIMIT_FAIL;
+ }
+ c = out;
+ *c = 0x00;
+ c++;
+ *c = (unsigned char) cryptType;
+ c++;
+ if (cryptType == PS_PUBKEY)
+ {
+ while (randomLen > 0)
+ {
+ *c++ = 0xFF;
+ randomLen--;
+ }
+ }
+ else
+ {
+ if (psGetPrngLocked(c, randomLen, userPtr) < 0)
+ {
+ return PS_PLATFORM_FAIL;
+ }
/*
- SECURITY: Read through the random data and change all 0x0 to 0x01.
- This is per spec that no random bytes should be 0
-*/
- while (randomLen > 0) {
- if (*c == 0x0) {
- *c = 0x01;
- }
- randomLen--;
- c++;
- }
- }
- *c = 0x00;
- c++;
- memcpy(c, in, inlen);
+ SECURITY: Read through the random data and change all 0x0 to 0x01.
+ This is per spec that no random bytes should be 0
+ */
+ while (randomLen > 0)
+ {
+ if (*c == 0x0)
+ {
+ *c = 0x01;
+ }
+ randomLen--;
+ c++;
+ }
+ }
+ *c = 0x00;
+ c++;
+ memcpy(c, in, inlen);
- return PS_SUCCESS;
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- Unpad a value decrypted by RSA, according to PKCS#1 v1.5
- http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
+ Unpad a value decrypted by RSA, according to PKCS#1 v1.5
+ http://www.rsasecurity.com/rsalabs/pkcs/pkcs-1/
- When decrypted, the data will look like the pad, including the inital
- byte (00). Form:
- 00 00
+ When decrypted, the data will look like the pad, including the inital
+ byte (00). Form:
+ 00 00
- We don't worry about v2 rollback issues because we don't support v2
-*/
-int32_t pkcs1Unpad(const unsigned char *in, uint16_t inlen,
- unsigned char *out, uint16_t outlen,
- uint8_t decryptType)
+ We don't worry about v2 rollback issues because we don't support v2
+ */
+int32_t pkcs1Unpad(const unsigned char *in, psSize_t inlen,
+ unsigned char *out, psSize_t outlen,
+ uint8_t decryptType)
{
- const unsigned char *c, *end;
+ const unsigned char *c, *end;
- if (inlen < outlen + 10) {
- psTraceCrypto("pkcs1Unpad failure\n");
- return PS_ARG_FAIL;
- }
- c = in;
- end = in + inlen;
+ if (inlen < outlen + 10)
+ {
+ psTraceCrypto("pkcs1Unpad failure\n");
+ return PS_ARG_FAIL;
+ }
+ c = in;
+ end = in + inlen;
- /* Verify the first byte (block type) is correct. */
- if (*c++ != 0x00 || *c != decryptType) {
- psTraceCrypto("pkcs1Unpad parse failure\n");
- return PS_FAILURE;
- }
- c++;
+ /* Verify the first byte (block type) is correct. */
+ if (*c++ != 0x00 || *c != decryptType)
+ {
+ psTraceCrypto("pkcs1Unpad parse failure\n");
+ return PS_FAILURE;
+ }
+ c++;
- /* Skip over the random, non-zero bytes used as padding */
- while (c < end && *c != 0x0) {
- if (decryptType == PS_PUBKEY) {
- if (*c != 0xFF) {
- psTraceCrypto("pkcs1Unpad pubkey parse failure\n");
- return PS_FAILURE;
- }
- }
- c++;
- }
- c++;
+ /* Skip over the random, non-zero bytes used as padding */
+ while (c < end && *c != 0x0)
+ {
+ if (decryptType == PS_PUBKEY)
+ {
+ if (*c != 0xFF)
+ {
+ psTraceCrypto("pkcs1Unpad pubkey parse failure\n");
+ return PS_FAILURE;
+ }
+ }
+ c++;
+ }
+ c++;
/*
- The length of the remaining data should be equal to what was expected
- Combined with the initial length check, there must be >= 8 bytes of pad
- ftp://ftp.rsa.com/pub/pdfs/bulletn7.pdf
-*/
- if ((uint32)(end - c) != outlen) {
- psTraceCrypto("pkcs1Unpad verification failure\n");
- return PS_LIMIT_FAIL;
- }
+ The length of the remaining data should be equal to what was expected
+ Combined with the initial length check, there must be >= 8 bytes of pad
+ ftp://ftp.rsa.com/pub/pdfs/bulletn7.pdf
+ */
+ if ((uint32) (end - c) != outlen)
+ {
+ psTraceCrypto("pkcs1Unpad verification failure\n");
+ return PS_LIMIT_FAIL;
+ }
- /* Copy the value bytes to the out buffer */
- while (c < end) {
- *out = *c;
- out++; c++;
- }
- return PS_SUCCESS;
+ /* Copy the value bytes to the out buffer */
+ while (c < end)
+ {
+ *out = *c;
+ out++; c++;
+ }
+ return PS_SUCCESS;
}
#ifdef USE_PRIVATE_KEY_PARSING
-#ifdef USE_PKCS8
+# ifdef USE_PKCS8
/******************************************************************************/
/**
- Parse PKCS#8 format keys (from DER formatted binary)
+ Parse PKCS#8 format keys (from DER formatted binary)
- 'key' is dynamically allocated and must be freed with psFreePubKey() if
- no error is returned from this API
+ 'key' is dynamically allocated and must be freed with psFreePubKey() if
+ no error is returned from this API
- Unencrypted private keys are supported if 'pass' is NULL
- Encrypted private keys are supported if 'pass' is non-null for the
- des-EDE3-CBC algorithm only (3DES). Other PKCS#5 symmetric algorithms
- are not supported.
+ Unencrypted private keys are supported if 'pass' is NULL
+ Encrypted private keys are supported if 'pass' is non-null for the
+ des-EDE3-CBC algorithm only (3DES). Other PKCS#5 symmetric algorithms
+ are not supported.
- @return < 0 on error, private keysize in bytes on success.
-*/
-int32 pkcs8ParsePrivBin(psPool_t *pool, unsigned char *buf, int32 size,
- char *pass, psPubKey_t *key)
-{
- const unsigned char *end, *p;
- int32 version, oi;
- uint16_t seqlen, len, plen;
-
-#ifdef USE_ECC
- int32 coi;
- const psEccCurve_t *eccSet;
-#endif
-#ifdef USE_PKCS5
- unsigned char desKeyBin[24];
- psCipherContext_t ctx;
- char iv[8], salt[8];
- int32 icount;
-#endif /* USE_PKCS5 */
-
- /* Check for too large (invalid) inputs, unparseable with uint16_t */
- if (size > 65535) {
- return PS_FAILURE;
- }
-
- p = buf;
- end = p + size;
-
- if (pass) {
-#ifdef USE_PKCS5
-/* An encrypted PKCS#8 key has quite a bit more information we must parse
- We actually parse a good bit of PKCS#5 structures here
-*/
- if (getAsnSequence(&p, (int32)(end - p), &seqlen) < 0) {
- return PS_FAILURE;
- }
- if (getAsnAlgorithmIdentifier(&p, (int32)(end - p), &oi, &plen) < 0){
- psTraceCrypto("Couldn't parse PKCS#8 algorithm identifier\n");
- return PS_FAILURE;
- }
- if (oi != OID_PKCS_PBES2 || plen != 53) {
- psTraceCrypto("Only supporting PKCS#8 id-PBES2 OID\n");
- return PS_FAILURE;
- }
- if (getAsnSequence(&p, (int32)(end - p), &seqlen) < 0) {
- return PS_FAILURE;
- }
- if (getAsnAlgorithmIdentifier(&p, (int32)(end - p), &oi, &plen) < 0){
- psTraceCrypto("Couldn't parse PKCS#8 keyDerivationFunc\n");
- return PS_FAILURE;
- }
- if (oi != OID_PKCS_PBKDF2 || plen != 16) {
- psTraceCrypto("Only support PKCS#8 id-PBKDF2 OID\n");
- return PS_FAILURE;
- }
- if (getAsnSequence(&p, (int32)(end - p), &seqlen) < 0) {
- return PS_FAILURE;
- }
- if ((*p++ != ASN_OCTET_STRING) ||
- getAsnLength(&p, (int32)(end - p), &len) < 0 ||
- (uint32)(end - p) < len ||
- len != 8) {
-
- psTraceCrypto("Couldn't parse PKCS#8 param salt\n");
- return PS_FAILURE;
- }
- /* Get the PBKDF2 Salt */
- memcpy(salt, p, 8); p += 8;
- /* Get the PBKDF2 Iteration count (rounds) */
- if (getAsnInteger(&p, (int32)(end - p), &icount) < 0) {
- psTraceCrypto("Couldn't parse PKCS#8 param iterationCount\n");
- return PS_FAILURE;
- }
- /* Get encryptionScheme */
- if (getAsnAlgorithmIdentifier(&p, (int32)(end - p), &oi, &plen)
- < 0){
- psTraceCrypto("Couldn't parse PKCS#8 encryptionScheme\n");
- return PS_FAILURE;
- }
- if (oi != OID_DES_EDE3_CBC || plen != 10) {
- psTraceCrypto("Only support des-EDE3-CBC OID\n");
- return PS_FAILURE;
- }
- if ((uint32)(end - p) < 1) {
- psTraceCrypto("Couldn't parse PKCS#8 param CBC IV\n");
- return PS_FAILURE;
- }
- if ((*p++ != ASN_OCTET_STRING) ||
- getAsnLength(&p, (int32)(end - p), &len) < 0 ||
- (uint32)(end - p) < len ||
- len != DES3_IVLEN) {
-
- psTraceCrypto("Couldn't parse PKCS#8 param CBC IV\n");
- return PS_FAILURE;
- }
- /* Get the 3DES IV */
- memcpy(iv, p, DES3_IVLEN); p += DES3_IVLEN;
-
- /* Now p points to the 3DES encrypted RSA key */
- if ((uint32)(end - p) < 1) {
- psTraceCrypto("Couldn't parse PKCS#8 param CBC IV\n");
- return PS_FAILURE;
- }
- if ((*p++ != ASN_OCTET_STRING) ||
- getAsnLength(&p, (int32)(end - p), &len) < 0 ||
- (uint32)(end - p) < len ||
-#ifdef USE_ECC
- /* May actually be an RSA key, but this check will be OK for now */
- len < MIN_ECC_BITS/8) {
-#else
- len < MIN_RSA_BITS/8) {
-#endif
-
- psTraceCrypto("PKCS#8 decryption error\n");
- return PS_FAILURE;
- }
- /* Derive the 3DES key and decrypt the RSA key*/
- pkcs5pbkdf2((unsigned char*)pass, (int32)strlen(pass),
- (unsigned char*)salt, 8, icount, (unsigned char*)desKeyBin,
- DES3_KEYLEN);
- psDes3Init(&ctx.des3, (unsigned char*)iv, desKeyBin);
- psDes3Decrypt(&ctx.des3, p, (unsigned char*)p, len);
- /* @security SECURITY - we zero out des3 key when done with it */
- memset_s(&ctx, sizeof(psCipherContext_t), 0x0, sizeof(psCipherContext_t));
- memset_s(desKeyBin, DES3_KEYLEN, 0x0, DES3_KEYLEN);
-#else /* !USE_PKCS5 */
-/*
- The private key is encrypted, but PKCS5 support has been turned off
+ @return < 0 on error, private keysize in bytes on success.
*/
- psTraceCrypto("USE_PKCS5 must be enabled for key file password\n");
- return PS_UNSUPPORTED_FAIL;
-#endif /* USE_PKCS5 */
- }
+int32 psPkcs8ParsePrivBin(psPool_t *pool, unsigned char *buf, int32 size,
+ char *pass, psPubKey_t *key)
+{
+ const unsigned char *end, *p;
+ int32 version, oi;
+ psSize_t seqlen, len, plen;
- /* PrivateKeyInfo per PKCS#8 Section 6. */
- if (getAsnSequence(&p, (int32)(end - p), &seqlen) < 0) {
- psTraceCrypto("Initial PrivateKeyInfo parse failure\n");
-#ifdef USE_PKCS5
- if (pass) {
- psTraceCrypto("Is it possible the password is incorrect?\n");
- }
-#endif /* USE_PKCS5 */
- return PS_FAILURE;
- }
- /* Version */
- if (getAsnInteger(&p, (int32)(end - p), &version) < 0 || version != 0) {
- psTraceCrypto("Couldn't parse PKCS#8 algorithm identifier\n");
- return PS_FAILURE;
- }
- /* privateKeyAlgorithmIdentifier */
- if (getAsnAlgorithmIdentifier(&p, (int32)(end - p), &oi, &plen) < 0) {
- psTraceCrypto("Couldn't parse PKCS#8 algorithm identifier\n");
- return PS_FAILURE;
- }
-#ifdef USE_ECC
- if (oi != OID_ECDSA_KEY_ALG && oi != OID_RSA_KEY_ALG) {
- psTraceCrypto("Unsupported public key type in PKCS#8 parse\n");
- return PS_UNSUPPORTED_FAIL;
- }
- if (oi == OID_ECDSA_KEY_ALG) {
- /* Still a curve identifier sitting as param in the SEQUENCE */
- if ((uint32)(end - p) < 1 || *p++ != ASN_OID) {
- psTraceCrypto("Expecting EC curve OID next\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnLength(&p, (uint32)(end - p), &len) < 0 ||
- (uint32)(end - p) < len) {
- psTraceCrypto("Malformed extension length\n");
- return PS_PARSE_FAIL;
- }
- coi = 0;
- while (len > 0) {
- coi += *p; p++;
- len--;
- }
- if (getEccParamByOid(coi, &eccSet) < 0) {
- psTraceCrypto("Unsupported EC curve OID\n");
- return PS_UNSUPPORTED_FAIL;
- }
- }
-#else
- if (oi != OID_RSA_KEY_ALG || plen != 0) {
- psTraceCrypto("Unsupported public key type in PKCS#8 parse\n");
- return PS_UNSUPPORTED_FAIL;
- }
-#endif
- /* PrivateKey Octet Stream */
- if ((uint32)(end - p) < 1) {
- psTraceCrypto("Private Key len failure\n");
- return PS_PARSE_FAIL;
- }
- if ((*p++ != ASN_OCTET_STRING) ||
- getAsnLength(&p, (int32)(end - p), &len) < 0 ||
- (uint32)(end - p) < len) {
- psTraceCrypto("getAsnLength parse error in pkcs8ParsePrivBin\n");
- return PS_FAILURE;
- }
- /* Note len can be zero here */
-#ifdef USE_RSA
- if (oi == OID_RSA_KEY_ALG) {
- /* Create the actual key here from the octet string */
- psRsaInitKey(pool, &key->key.rsa);
- if (psRsaParsePkcs1PrivKey(pool, p, len, &key->key.rsa) < 0) {
- psRsaClearKey(&key->key.rsa);
- return PS_FAILURE;
- }
- key->type = PS_RSA;
- key->keysize = psRsaSize(&key->key.rsa);
- }
-#endif
-#ifdef USE_ECC
- if (oi == OID_ECDSA_KEY_ALG) {
- psEccInitKey(pool, &key->key.ecc, eccSet);
- if (psEccParsePrivKey(pool, p, len, &key->key.ecc, eccSet) < 0) {
- return PS_FAILURE;
- }
- key->type = PS_ECC;
- key->keysize = psEccSize(&key->key.ecc);
- }
-#endif
- p += len;
+# ifdef USE_ECC
+ int32 coi;
+ const psEccCurve_t *eccSet;
+# endif
+# ifdef USE_PKCS5
+ unsigned char desKeyBin[24];
+ psCipherContext_t ctx;
+ char iv[8], salt[8];
+ int32 icount;
+# endif /* USE_PKCS5 */
- plen = (int32)(end - p);
- if (plen > 0) {
- /* attributes [0] Attributes OPTIONAL */
- if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
- p++;
- if (getAsnLength(&p, (int32)(end - p), &len) < 0 ||
- (uint32)(end - p) < len) {
+ /* Check for too large (invalid) inputs, unparseable with uint16_t */
+ if (size > 65535)
+ {
+ return PS_FAILURE;
+ }
- psTraceCrypto("Error parsing pkcs#8 PrivateKey attributes\n");
- return PS_FAILURE;
- }
- /* Ignore any attributes */
- p += len;
- plen = (int32)(end - p);
- }
- /* Any remaining bytes should be non ASN.1 bytes that correspond
- to the 3DES block padding */
- while (p < end) {
- if (*p++ != (char)plen) {
- goto PKCS8_FAIL;
- }
- }
- }
+ p = buf;
+ end = p + size;
- return PS_SUCCESS;
+ if (pass)
+ {
+# ifdef USE_PKCS5
+/* An encrypted PKCS#8 key has quite a bit more information we must parse
+ We actually parse a good bit of PKCS#5 structures here
+ */
+ if (getAsnSequence(&p, (int32) (end - p), &seqlen) < 0)
+ {
+ return PS_FAILURE;
+ }
+ if (getAsnAlgorithmIdentifier(&p, (int32) (end - p), &oi, &plen) < 0)
+ {
+ psTraceCrypto("Couldn't parse PKCS#8 algorithm identifier\n");
+ return PS_FAILURE;
+ }
+ if (oi != OID_PKCS_PBES2 || plen != 53)
+ {
+ psTraceCrypto("Only supporting PKCS#8 id-PBES2 OID\n");
+ return PS_FAILURE;
+ }
+ if (getAsnSequence(&p, (int32) (end - p), &seqlen) < 0)
+ {
+ return PS_FAILURE;
+ }
+ if (getAsnAlgorithmIdentifier(&p, (int32) (end - p), &oi, &plen) < 0)
+ {
+ psTraceCrypto("Couldn't parse PKCS#8 keyDerivationFunc\n");
+ return PS_FAILURE;
+ }
+ if (oi != OID_PKCS_PBKDF2 || plen != 16)
+ {
+ psTraceCrypto("Only support PKCS#8 id-PBKDF2 OID\n");
+ return PS_FAILURE;
+ }
+ if (getAsnSequence(&p, (int32) (end - p), &seqlen) < 0)
+ {
+ return PS_FAILURE;
+ }
+ if ((*p++ != ASN_OCTET_STRING) ||
+ getAsnLength(&p, (int32) (end - p), &len) < 0 ||
+ (uint32) (end - p) < len ||
+ len != 8)
+ {
+
+ psTraceCrypto("Couldn't parse PKCS#8 param salt\n");
+ return PS_FAILURE;
+ }
+ /* Get the PBKDF2 Salt */
+ memcpy(salt, p, 8); p += 8;
+ /* Get the PBKDF2 Iteration count (rounds) */
+ if (getAsnInteger(&p, (int32) (end - p), &icount) < 0)
+ {
+ psTraceCrypto("Couldn't parse PKCS#8 param iterationCount\n");
+ return PS_FAILURE;
+ }
+ /* Get encryptionScheme */
+ if (getAsnAlgorithmIdentifier(&p, (int32) (end - p), &oi, &plen)
+ < 0)
+ {
+ psTraceCrypto("Couldn't parse PKCS#8 encryptionScheme\n");
+ return PS_FAILURE;
+ }
+ if (oi != OID_DES_EDE3_CBC || plen != 10)
+ {
+ psTraceCrypto("Only support des-EDE3-CBC OID\n");
+ return PS_FAILURE;
+ }
+ if ((uint32) (end - p) < 1)
+ {
+ psTraceCrypto("Couldn't parse PKCS#8 param CBC IV\n");
+ return PS_FAILURE;
+ }
+ if ((*p++ != ASN_OCTET_STRING) ||
+ getAsnLength(&p, (int32) (end - p), &len) < 0 ||
+ (uint32) (end - p) < len ||
+ len != DES3_IVLEN)
+ {
+
+ psTraceCrypto("Couldn't parse PKCS#8 param CBC IV\n");
+ return PS_FAILURE;
+ }
+ /* Get the 3DES IV */
+ memcpy(iv, p, DES3_IVLEN); p += DES3_IVLEN;
+
+ /* Now p points to the 3DES encrypted RSA key */
+ if ((uint32) (end - p) < 1)
+ {
+ psTraceCrypto("Couldn't parse PKCS#8 param CBC IV\n");
+ return PS_FAILURE;
+ }
+ if ((*p++ != ASN_OCTET_STRING) ||
+ getAsnLength(&p, (int32) (end - p), &len) < 0 ||
+ (uint32) (end - p) < len ||
+# ifdef USE_ECC
+ /* May actually be an RSA key, but this check will be OK for now */
+ len < MIN_ECC_BITS / 8)
+ {
+# else
+ len < MIN_RSA_BITS / 8) {
+# endif
+
+ psTraceCrypto("PKCS#8 decryption error\n");
+ return PS_FAILURE;
+ }
+ /* Derive the 3DES key and decrypt the RSA key*/
+ psPkcs5Pbkdf2((unsigned char *) pass, (int32) strlen(pass),
+ (unsigned char *) salt, 8, icount, (unsigned char *) desKeyBin,
+ DES3_KEYLEN);
+ psDes3Init(&ctx.des3, (unsigned char *) iv, desKeyBin);
+ psDes3Decrypt(&ctx.des3, p, (unsigned char *) p, len);
+ /* @security SECURITY - we zero out des3 key when done with it */
+ memset_s(&ctx, sizeof(psCipherContext_t), 0x0, sizeof(psCipherContext_t));
+ memset_s(desKeyBin, DES3_KEYLEN, 0x0, DES3_KEYLEN);
+# else /* !USE_PKCS5 */
+/*
+ The private key is encrypted, but PKCS5 support has been turned off
+ */
+ psTraceCrypto("USE_PKCS5 must be enabled for key file password\n");
+ return PS_UNSUPPORTED_FAIL;
+# endif /* USE_PKCS5 */
+ }
+
+ /* PrivateKeyInfo per PKCS#8 Section 6. */
+ if (getAsnSequence(&p, (int32) (end - p), &seqlen) < 0)
+ {
+ psTraceCrypto("Initial PrivateKeyInfo parse failure\n");
+# ifdef USE_PKCS5
+ if (pass)
+ {
+ psTraceCrypto("Is it possible the password is incorrect?\n");
+ }
+# endif /* USE_PKCS5 */
+ return PS_FAILURE;
+ }
+ /* Version */
+ if (getAsnInteger(&p, (int32) (end - p), &version) < 0 || version != 0)
+ {
+ psTraceCrypto("Couldn't parse PKCS#8 algorithm identifier\n");
+ return PS_FAILURE;
+ }
+ /* privateKeyAlgorithmIdentifier */
+ if (getAsnAlgorithmIdentifier(&p, (int32) (end - p), &oi, &plen) < 0)
+ {
+ psTraceCrypto("Couldn't parse PKCS#8 algorithm identifier\n");
+ return PS_FAILURE;
+ }
+# ifdef USE_ECC
+ if (oi != OID_ECDSA_KEY_ALG && oi != OID_RSA_KEY_ALG)
+ {
+ psTraceCrypto("Unsupported public key type in PKCS#8 parse\n");
+ return PS_UNSUPPORTED_FAIL;
+ }
+ if (oi == OID_ECDSA_KEY_ALG)
+ {
+ /* Still a curve identifier sitting as param in the SEQUENCE */
+ if ((uint32) (end - p) < 1 || *p++ != ASN_OID)
+ {
+ psTraceCrypto("Expecting EC curve OID next\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnLength(&p, (uint32) (end - p), &len) < 0 ||
+ (uint32) (end - p) < len)
+ {
+ psTraceCrypto("Malformed extension length\n");
+ return PS_PARSE_FAIL;
+ }
+ coi = 0;
+ while (len > 0)
+ {
+ coi += *p; p++;
+ len--;
+ }
+ if (getEccParamByOid(coi, &eccSet) < 0)
+ {
+ psTraceCrypto("Unsupported EC curve OID\n");
+ return PS_UNSUPPORTED_FAIL;
+ }
+ }
+# else
+ if (oi != OID_RSA_KEY_ALG || plen != 0)
+ {
+ psTraceCrypto("Unsupported public key type in PKCS#8 parse\n");
+ return PS_UNSUPPORTED_FAIL;
+ }
+# endif
+ /* PrivateKey Octet Stream */
+ if ((uint32) (end - p) < 1)
+ {
+ psTraceCrypto("Private Key len failure\n");
+ return PS_PARSE_FAIL;
+ }
+ if ((*p++ != ASN_OCTET_STRING) ||
+ getAsnLength(&p, (int32) (end - p), &len) < 0 ||
+ (uint32) (end - p) < len)
+ {
+ psTraceCrypto("getAsnLength parse error in psPkcs8ParsePrivBin\n");
+ return PS_FAILURE;
+ }
+ /* Note len can be zero here */
+# ifdef USE_RSA
+ if (oi == OID_RSA_KEY_ALG)
+ {
+ /* Create the actual key here from the octet string */
+ psRsaInitKey(pool, &key->key.rsa);
+ if (psRsaParsePkcs1PrivKey(pool, p, len, &key->key.rsa) < 0)
+ {
+ psRsaClearKey(&key->key.rsa);
+ return PS_FAILURE;
+ }
+ key->type = PS_RSA;
+ key->keysize = psRsaSize(&key->key.rsa);
+ }
+# endif
+# ifdef USE_ECC
+ if (oi == OID_ECDSA_KEY_ALG)
+ {
+ psEccInitKey(pool, &key->key.ecc, eccSet);
+ if (psEccParsePrivKey(pool, p, len, &key->key.ecc, eccSet) < 0)
+ {
+ return PS_FAILURE;
+ }
+ key->type = PS_ECC;
+ key->keysize = psEccSize(&key->key.ecc);
+ }
+# endif
+ p += len;
+
+ plen = (int32) (end - p);
+ if (plen > 0)
+ {
+ /* attributes [0] Attributes OPTIONAL */
+ if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
+ {
+ p++;
+ if (getAsnLength(&p, (int32) (end - p), &len) < 0 ||
+ (uint32) (end - p) < len)
+ {
+
+ psTraceCrypto("Error parsing pkcs#8 PrivateKey attributes\n");
+ return PS_FAILURE;
+ }
+ /* Ignore any attributes */
+ p += len;
+ plen = (int32) (end - p);
+ }
+ /* Any remaining bytes should be non ASN.1 bytes that correspond
+ to the 3DES block padding */
+ while (p < end)
+ {
+ if (*p++ != (char) plen)
+ {
+ goto PKCS8_FAIL;
+ }
+ }
+ }
+
+ return PS_SUCCESS;
PKCS8_FAIL:
- psClearPubKey(key);
- psTraceCrypto("Did not parse key in PKCS#8 parse\n");
- return PS_FAILURE;
+ psClearPubKey(key);
+ psTraceCrypto("Did not parse key in PKCS#8 parse\n");
+ return PS_FAILURE;
}
-#ifdef MATRIX_USE_FILE_SYSTEM
-#ifdef USE_PKCS12
+# ifdef MATRIX_USE_FILE_SYSTEM
+# ifdef USE_PKCS12
/******************************************************************************/
/*
- A PKCS #7 ContentInfo, whose contentType is signedData in public-key
- integrity mode and data in password integrity mode.
+ A PKCS #7 ContentInfo, whose contentType is signedData in public-key
+ integrity mode and data in password integrity mode.
- Returns integrity mode or < 0 on failure
-*/
-#define PASSWORD_INTEGRITY 1
-#define PUBKEY_INTEGRITY 2
+ Returns integrity mode or < 0 on failure
+ */
+# define PASSWORD_INTEGRITY 1
+# define PUBKEY_INTEGRITY 2
static int32 psParseIntegrityMode(const unsigned char **buf, int32 totLen)
{
- const unsigned char *p, *end;
- uint16_t totcontentlen, len, oiLen;
- int32 rc, oi;
+ const unsigned char *p, *end;
+ psSize_t totcontentlen, len, oiLen;
+ int32 rc, oi;
- p = *buf;
- end = p + totLen;
+ p = *buf;
+ end = p + totLen;
- if ((rc = getAsnAlgorithmIdentifier(&p, totLen, &oi, &oiLen)) < 0) {
- psTraceCrypto("Initial integrity parse error\n");
- return rc;
- }
+ if ((rc = getAsnAlgorithmIdentifier(&p, totLen, &oi, &oiLen)) < 0)
+ {
+ psTraceCrypto("Initial integrity parse error\n");
+ return rc;
+ }
- if (oi == OID_PKCS7_DATA) {
- /* Data ::= OCTET STRING */
- if (*p++ != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
- return PS_PARSE_FAIL;
- }
- if ((rc = getAsnLength(&p, (int32)(end - p), &len)) < 0) {
- return PS_PARSE_FAIL;
- }
- if ((*p++ != ASN_OCTET_STRING) ||
- getAsnLength(&p, (int32)(end - p), &totcontentlen) < 0) {
- psTraceCrypto("Couldn't parse data from ContentInfo\n");
- return PS_FAILURE;
- }
- rc = PASSWORD_INTEGRITY;
- } else if (oi == OID_PKCS7_SIGNED_DATA) {
- psTraceCrypto("SignedData integrity mode not supported\n");
- return PS_UNSUPPORTED_FAIL;
- /* rc = PUBKEY_INTEGRITY; */
- } else {
- psTraceCrypto("Unknown integrity mode\n");
- return PS_UNSUPPORTED_FAIL;
- }
+ if (oi == OID_PKCS7_DATA)
+ {
+ /* Data ::= OCTET STRING */
+ if (*p++ != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
+ {
+ return PS_PARSE_FAIL;
+ }
+ if ((rc = getAsnLength(&p, (int32) (end - p), &len)) < 0)
+ {
+ return PS_PARSE_FAIL;
+ }
+ if ((*p++ != ASN_OCTET_STRING) ||
+ getAsnLength(&p, (int32) (end - p), &totcontentlen) < 0)
+ {
+ psTraceCrypto("Couldn't parse data from ContentInfo\n");
+ return PS_FAILURE;
+ }
+ rc = PASSWORD_INTEGRITY;
+ }
+ else if (oi == OID_PKCS7_SIGNED_DATA)
+ {
+ psTraceCrypto("SignedData integrity mode not supported\n");
+ return PS_UNSUPPORTED_FAIL;
+ /* rc = PUBKEY_INTEGRITY; */
+ }
+ else
+ {
+ psTraceCrypto("Unknown integrity mode\n");
+ return PS_UNSUPPORTED_FAIL;
+ }
- *buf = (unsigned char*)p;
- return rc;
+ *buf = (unsigned char *) p;
+ return rc;
}
/******************************************************************************/
/*
- Generate a key given a password, salt and iteration value.
+ Generate a key given a password, salt and iteration value.
- B.2 General method from PKCS#12
+ B.2 General method from PKCS#12
- Assumptions: hash is SHA-1, password is < 128 bytes
-*/
+ Assumptions: hash is SHA-1, password is < 128 bytes
+ */
static int32 pkcs12pbe(psPool_t *pool, unsigned char *password, uint32 passLen,
- unsigned char *salt, int saltLen, int32 iter, int32 id,
- unsigned char **out, uint32 *outlen)
+ unsigned char *salt, int saltLen, int32 iter, int32 id,
+ unsigned char **out, uint32 *outlen)
{
- psSha1_t ctx;
- pstm_int bigb, bigone, bigtmp;
- unsigned char diversifier[64], saltpass[192], hash[SHA1_HASH_SIZE];
- unsigned char B[65];
- unsigned char *p, *front;
- int32 i, j, copy, count, cpyLen, binsize, plen;
+ psSha1_t ctx;
+ pstm_int bigb, bigone, bigtmp;
+ unsigned char diversifier[64], saltpass[192], hash[SHA1_HASH_SIZE];
+ unsigned char B[65];
+ unsigned char *p, *front;
+ int32 i, j, copy, count, cpyLen, binsize, plen;
- *out = NULL;
- memset(diversifier, id, 64);
+ *out = NULL;
+ memset(diversifier, id, 64);
- for (i = 0; i < 64;) {
- if ((64 - i) < saltLen) {
- memcpy(&saltpass[i], salt, 64 - i);
- i = 64;
- } else {
- memcpy(&saltpass[i], salt, saltLen);
- i += saltLen;
- }
- }
+ for (i = 0; i < 64; )
+ {
+ if ((64 - i) < saltLen)
+ {
+ memcpy(&saltpass[i], salt, 64 - i);
+ i = 64;
+ }
+ else
+ {
+ memcpy(&saltpass[i], salt, saltLen);
+ i += saltLen;
+ }
+ }
- plen = 64 * ((passLen + 64 - 1) / 64);
- if (plen + 64 > 192) {
- return PS_UNSUPPORTED_FAIL;
- }
- for (i = 0; i < plen; i++) {
- saltpass[64 + i] = password[i % passLen];
- }
+ plen = 64 * ((passLen + 64 - 1) / 64);
+ if (plen + 64 > 192)
+ {
+ return PS_UNSUPPORTED_FAIL;
+ }
+ for (i = 0; i < plen; i++)
+ {
+ saltpass[64 + i] = password[i % passLen];
+ }
- if (*outlen == SHA1_HASH_SIZE) {
- count = 1;
- } else {
- count = (*outlen/SHA1_HASH_SIZE) + 1;
- }
- cpyLen = *outlen;
+ if (*outlen == SHA1_HASH_SIZE)
+ {
+ count = 1;
+ }
+ else
+ {
+ count = (*outlen / SHA1_HASH_SIZE) + 1;
+ }
+ cpyLen = *outlen;
- front = p = psMalloc(pool, cpyLen);
- if (front == NULL) {
- return PS_MEM_FAIL;
- }
+ front = p = psMalloc(pool, cpyLen);
+ if (front == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
- while (count) {
- psSha1Init(&ctx);
- psSha1Update(&ctx, diversifier, 64);
- psSha1Update(&ctx, saltpass, 64 + plen);
- psSha1Final(&ctx, hash);
- for (j = 1; j < iter; j++) {
- psSha1Init(&ctx);
- psSha1Update(&ctx, hash, SHA1_HASH_SIZE);
- psSha1Final(&ctx, hash);
- }
- /* Copy into outgoing key now */
- copy = min(cpyLen, SHA1_HASH_SIZE);
- memcpy(p, hash, copy);
- p += copy;
- count--;
- cpyLen -= copy;
+ while (count)
+ {
+ psSha1Init(&ctx);
+ psSha1Update(&ctx, diversifier, 64);
+ psSha1Update(&ctx, saltpass, 64 + plen);
+ psSha1Final(&ctx, hash);
+ for (j = 1; j < iter; j++)
+ {
+ psSha1Init(&ctx);
+ psSha1Update(&ctx, hash, SHA1_HASH_SIZE);
+ psSha1Final(&ctx, hash);
+ }
+ /* Copy into outgoing key now */
+ copy = min(cpyLen, SHA1_HASH_SIZE);
+ memcpy(p, hash, copy);
+ p += copy;
+ count--;
+ cpyLen -= copy;
- if (cpyLen > 0) {
- /* manipulate saltpass */
- for (j = 0; j < 64; j++) {
- B[j] = hash[j % SHA1_HASH_SIZE];
- }
- if (pstm_init_for_read_unsigned_bin(pool, &bigb, 64) < 0) {
- psFree(front, pool);
- return PS_MEM_FAIL;
- }
- if (pstm_read_unsigned_bin(&bigb, B, 64) < 0) {
- pstm_clear(&bigb);
- psFree(front, pool);
- return PS_MEM_FAIL;
- }
- if (pstm_init_for_read_unsigned_bin(pool, &bigone, 1) < 0) {
- pstm_clear(&bigb);
- psFree(front, pool);
- return PS_MEM_FAIL;
- }
- pstm_set(&bigone, 1);
- if (pstm_add(&bigb, &bigone, &bigb) < 0) {
- pstm_clear(&bigone);
- pstm_clear(&bigb);
- psFree(front, pool);
- return PS_MEM_FAIL;
- }
- pstm_clear(&bigone);
- for (j = 0; j < 64 + plen; j+=64) {
- if (pstm_init_for_read_unsigned_bin(pool, &bigtmp, 64) < 0) {
- pstm_clear(&bigone);
- pstm_clear(&bigb);
- psFree(front, pool);
- return PS_MEM_FAIL;
- }
- if (pstm_read_unsigned_bin(&bigtmp, saltpass + j, 64) < 0) {
- pstm_clear(&bigone);
- pstm_clear(&bigb);
- pstm_clear(&bigtmp);
- psFree(front, pool);
- return PS_MEM_FAIL;
- }
- if (pstm_add(&bigb, &bigtmp, &bigtmp) < 0) {
- pstm_clear(&bigone);
- pstm_clear(&bigb);
- pstm_clear(&bigtmp);
- psFree(front, pool);
- return PS_MEM_FAIL;
- }
- binsize = pstm_unsigned_bin_size(&bigtmp);
- if (binsize > 64) {
- psAssert(binsize == 65);
- if (pstm_to_unsigned_bin(pool, &bigtmp, B) < 0) {
- pstm_clear(&bigone);
- pstm_clear(&bigb);
- pstm_clear(&bigtmp);
- psFree(front, pool);
- return PS_MEM_FAIL;
- }
- memcpy(saltpass + j, B + 1, 64); /* truncate */
- } else if (binsize < 64) {
- psAssert(binsize == 63);
- memset(saltpass + j, 0x0, 1); /* pad with a zero */
- if (pstm_to_unsigned_bin(pool, &bigtmp, saltpass + j + 1) < 0) {
- pstm_clear(&bigone);
- pstm_clear(&bigb);
- pstm_clear(&bigtmp);
- psFree(front, pool);
- return PS_MEM_FAIL;
- }
- } else {
- if (pstm_to_unsigned_bin(pool, &bigtmp, saltpass + j) < 0) {
- pstm_clear(&bigone);
- pstm_clear(&bigb);
- pstm_clear(&bigtmp);
- psFree(front, pool);
- return PS_MEM_FAIL;
- }
- }
- pstm_clear(&bigtmp);
- }
- pstm_clear(&bigone);
- pstm_clear(&bigb);
- }
- }
+ if (cpyLen > 0)
+ {
+ /* manipulate saltpass */
+ for (j = 0; j < 64; j++)
+ {
+ B[j] = hash[j % SHA1_HASH_SIZE];
+ }
+ if (pstm_init_for_read_unsigned_bin(pool, &bigb, 64) < 0)
+ {
+ psFree(front, pool);
+ return PS_MEM_FAIL;
+ }
+ if (pstm_read_unsigned_bin(&bigb, B, 64) < 0)
+ {
+ pstm_clear(&bigb);
+ psFree(front, pool);
+ return PS_MEM_FAIL;
+ }
+ if (pstm_init_for_read_unsigned_bin(pool, &bigone, 1) < 0)
+ {
+ pstm_clear(&bigb);
+ psFree(front, pool);
+ return PS_MEM_FAIL;
+ }
+ pstm_set(&bigone, 1);
+ if (pstm_add(&bigb, &bigone, &bigb) < 0)
+ {
+ pstm_clear(&bigone);
+ pstm_clear(&bigb);
+ psFree(front, pool);
+ return PS_MEM_FAIL;
+ }
+ pstm_clear(&bigone);
+ for (j = 0; j < 64 + plen; j += 64)
+ {
+ if (pstm_init_for_read_unsigned_bin(pool, &bigtmp, 64) < 0)
+ {
+ pstm_clear(&bigone);
+ pstm_clear(&bigb);
+ psFree(front, pool);
+ return PS_MEM_FAIL;
+ }
+ if (pstm_read_unsigned_bin(&bigtmp, saltpass + j, 64) < 0)
+ {
+ pstm_clear(&bigone);
+ pstm_clear(&bigb);
+ pstm_clear(&bigtmp);
+ psFree(front, pool);
+ return PS_MEM_FAIL;
+ }
+ if (pstm_add(&bigb, &bigtmp, &bigtmp) < 0)
+ {
+ pstm_clear(&bigone);
+ pstm_clear(&bigb);
+ pstm_clear(&bigtmp);
+ psFree(front, pool);
+ return PS_MEM_FAIL;
+ }
+ binsize = pstm_unsigned_bin_size(&bigtmp);
+ if (binsize > 64)
+ {
+ psAssert(binsize == 65);
+ if (pstm_to_unsigned_bin(pool, &bigtmp, B) < 0)
+ {
+ pstm_clear(&bigone);
+ pstm_clear(&bigb);
+ pstm_clear(&bigtmp);
+ psFree(front, pool);
+ return PS_MEM_FAIL;
+ }
+ memcpy(saltpass + j, B + 1, 64); /* truncate */
+ }
+ else if (binsize < 64)
+ {
+ psAssert(binsize == 63);
+ memset(saltpass + j, 0x0, 1); /* pad with a zero */
+ if (pstm_to_unsigned_bin(pool, &bigtmp, saltpass + j + 1) < 0)
+ {
+ pstm_clear(&bigone);
+ pstm_clear(&bigb);
+ pstm_clear(&bigtmp);
+ psFree(front, pool);
+ return PS_MEM_FAIL;
+ }
+ }
+ else
+ {
+ if (pstm_to_unsigned_bin(pool, &bigtmp, saltpass + j) < 0)
+ {
+ pstm_clear(&bigone);
+ pstm_clear(&bigb);
+ pstm_clear(&bigtmp);
+ psFree(front, pool);
+ return PS_MEM_FAIL;
+ }
+ }
+ pstm_clear(&bigtmp);
+ }
+ pstm_clear(&bigone);
+ pstm_clear(&bigb);
+ }
+ }
- *out = front;
- return PS_SUCCESS;
+ *out = front;
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- Return value is how many bytes were parsed out of buf
-*/
+ Return value is how many bytes were parsed out of buf
+ */
static int32 pkcs12import(psPool_t *pool, const unsigned char **buf,
- uint16_t bufLen, unsigned char *password, uint16_t passLen,
- unsigned char **plaintext, uint16_t *ptLen)
+ psSize_t bufLen, unsigned char *password, psSize_t passLen,
+ unsigned char **plaintext, psSize_t *ptLen)
{
- psCipherContext_t ctx;
- const unsigned char *p, *start, *end;
- unsigned char *iv, *decryptKey, *pt;
- unsigned char salt[8];
- int32 rc, oi, asnint;
- uint32_t keyLen, ivLen;
- uint16_t tmplen, tmpint;
- short cipher;
- const short armor = PBE12;
+ psCipherContext_t ctx;
+ const unsigned char *p, *start, *end;
+ unsigned char *iv, *decryptKey, *pt;
+ unsigned char salt[8];
+ int32 rc, oi, asnint;
+ uint32_t keyLen, ivLen;
+ psSize_t tmplen, tmpint;
+ short cipher;
+ const short armor = PBE12;
- *plaintext = NULL;
- *ptLen = 0;
- decryptKey = NULL;
+ *plaintext = NULL;
+ *ptLen = 0;
+ decryptKey = NULL;
- p = start = *buf;
- end = p + bufLen;
+ p = start = *buf;
+ end = p + bufLen;
- /* Encryption Algorithm */
- if ((rc = getAsnAlgorithmIdentifier(&p, (int32)(end - p), &oi,
- &tmpint)) < 0) {
- psTraceCrypto("Initial pkcs12import parse failure\n");
- return rc;
- }
+ /* Encryption Algorithm */
+ if ((rc = getAsnAlgorithmIdentifier(&p, (int32) (end - p), &oi,
+ &tmpint)) < 0)
+ {
+ psTraceCrypto("Initial pkcs12import parse failure\n");
+ return rc;
+ }
- if (oi == OID_PKCS_PBESHA40RC2) {
-#ifdef USE_RC2
- cipher = AUTH_SAFE_RC2;
- keyLen = 8;
-#else
- psTraceCrypto("Must enable USE_RC2 in cryptoConfig.h to parse\n");
- return PS_UNSUPPORTED_FAIL;
-#endif
- } else if (oi == OID_PKCS_PBESHA3DES3) {
- cipher = AUTH_SAFE_3DES;
- keyLen = DES3_KEYLEN;
- } else {
- psTraceIntCrypto("Unsupported PBE algorithm %d\n", oi);
- return PS_UNSUPPORTED_FAIL;
- }
+ if (oi == OID_PKCS_PBESHA40RC2)
+ {
+# ifdef USE_RC2
+ cipher = AUTH_SAFE_RC2;
+ keyLen = 8;
+# else
+ psTraceCrypto("Must enable USE_RC2 in cryptoConfig.h to parse\n");
+ return PS_UNSUPPORTED_FAIL;
+# endif
+ }
+ else if (oi == OID_PKCS_PBESHA3DES3)
+ {
+ cipher = AUTH_SAFE_3DES;
+ keyLen = DES3_KEYLEN;
+ }
+ else
+ {
+ psTraceIntCrypto("Unsupported PBE algorithm %d\n", oi);
+ return PS_UNSUPPORTED_FAIL;
+ }
- if (armor == PBE12) {
- /* If PKCS12 param will be
- pkcs-12PbeParams ::= SEQUENCE {
- salt OCTET STRING,
- iterations INTEGER
- }
- */
- if ((rc = getAsnSequence(&p, (int32)(end - p), &tmplen)) < 0) {
- psTraceCrypto("Initial PBE12 parse failure\n");
- return rc;
- }
- /* salt len */
- if ((uint32)(end - p) < 1 || (*p++ != ASN_OCTET_STRING) ||
- getAsnLength(&p, (int32)(end - p), &tmplen) < 0 ||
- (uint32)(end - p) < tmplen ||
- tmplen != 8) {
+ if (armor == PBE12)
+ {
+ /* If PKCS12 param will be
+ pkcs-12PbeParams ::= SEQUENCE {
+ salt OCTET STRING,
+ iterations INTEGER
+ }
+ */
+ if ((rc = getAsnSequence(&p, (int32) (end - p), &tmplen)) < 0)
+ {
+ psTraceCrypto("Initial PBE12 parse failure\n");
+ return rc;
+ }
+ /* salt len */
+ if ((uint32) (end - p) < 1 || (*p++ != ASN_OCTET_STRING) ||
+ getAsnLength(&p, (int32) (end - p), &tmplen) < 0 ||
+ (uint32) (end - p) < tmplen ||
+ tmplen != 8)
+ {
- psTraceCrypto("Bad salt length parsing import\n");
- return PS_PARSE_FAIL;
- }
- memcpy(salt, p, tmplen);
- p += tmplen;
- /* iteration count */
- if (getAsnInteger(&p, (int32)(end - p), &asnint) < 0) {
- return PS_PARSE_FAIL;
- }
- if (pkcs12pbe(pool, password, passLen, salt, 8, asnint,
- PKCS12_KEY_ID, &decryptKey, &keyLen) < 0) {
- psTraceCrypto("Error generating pkcs12 key\n");
- return PS_UNSUPPORTED_FAIL;
- }
- ivLen = 8;
- if (pkcs12pbe(pool, password, passLen, salt, 8, asnint,
- PKCS12_IV_ID, &iv, &ivLen) < 0) {
- psTraceCrypto("Error generating pkcs12 iv\n");
- if (decryptKey) {
- memset_s(decryptKey, keyLen, 0x0, keyLen);
- psFree(decryptKey, pool);
- }
- return PS_UNSUPPORTED_FAIL;
- }
- }
+ psTraceCrypto("Bad salt length parsing import\n");
+ return PS_PARSE_FAIL;
+ }
+ memcpy(salt, p, tmplen);
+ p += tmplen;
+ /* iteration count */
+ if (getAsnInteger(&p, (int32) (end - p), &asnint) < 0)
+ {
+ return PS_PARSE_FAIL;
+ }
+ if (pkcs12pbe(pool, password, passLen, salt, 8, asnint,
+ PKCS12_KEY_ID, &decryptKey, &keyLen) < 0)
+ {
+ psTraceCrypto("Error generating pkcs12 key\n");
+ return PS_UNSUPPORTED_FAIL;
+ }
+ ivLen = 8;
+ if (pkcs12pbe(pool, password, passLen, salt, 8, asnint,
+ PKCS12_IV_ID, &iv, &ivLen) < 0)
+ {
+ psTraceCrypto("Error generating pkcs12 iv\n");
+ if (decryptKey)
+ {
+ memset_s(decryptKey, keyLen, 0x0, keyLen);
+ psFree(decryptKey, pool);
+ }
+ return PS_UNSUPPORTED_FAIL;
+ }
+ }
- /* Got the keys but we still need to find the start of the encrypted data.
- Have seen a few different BER variations at this point in the spec
- depending on what wrapper we are in. Try all that we know about
- */
- if ((uint32)(end - p) < 1) {
- return PS_PARSE_FAIL;
- }
- if (*p == (ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE)) {
- p++;
- if ((rc = getAsnLength(&p, (int32)(end - p), &tmplen)) < 0) {
- if (decryptKey) {
- memset_s(decryptKey, keyLen, 0x0, keyLen);
- psFree(decryptKey, pool);
- }
- psFree(iv, pool);
- return PS_PARSE_FAIL;
- }
- } else if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
- p++;
- if ((rc = getAsnLength(&p, (int32)(end - p), &tmplen)) < 0) {
- if (decryptKey) {
- memset_s(decryptKey, keyLen, 0x0, keyLen);
- psFree(decryptKey, pool);
- }
- psFree(iv, pool);
- return PS_PARSE_FAIL;
- }
- if ((uint32)(end - p) < 1 ||
- *p++ != ASN_OCTET_STRING ||
- getAsnLength(&p, (int32)(end - p), &tmplen) < 0) {
- if (decryptKey) {
- memset_s(decryptKey, keyLen, 0x0, keyLen);
- psFree(decryptKey, pool);
- }
- psFree(iv, pool);
- return PS_PARSE_FAIL;
- }
- } else if (*p == ASN_OCTET_STRING) {
- p++;
- if ((rc = getAsnLength(&p, (int32)(end - p), &tmplen)) < 0) {
- if (decryptKey) {
- memset_s(decryptKey, keyLen, 0x0, keyLen);
- psFree(decryptKey, pool);
- }
- psFree(iv, pool);
- return PS_PARSE_FAIL;
- }
- } else {
- psTraceCrypto("Error finding ciphertext in pkcs12import\n");
- if (decryptKey) {
- memset_s(decryptKey, keyLen, 0x0, keyLen);
- psFree(decryptKey, pool);
- }
- psFree(iv, pool);
- return PS_PARSE_FAIL;
- }
+ /* Got the keys but we still need to find the start of the encrypted data.
+ Have seen a few different BER variations at this point in the spec
+ depending on what wrapper we are in. Try all that we know about
+ */
+ if ((uint32) (end - p) < 1)
+ {
+ return PS_PARSE_FAIL;
+ }
+ if (*p == (ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE))
+ {
+ p++;
+ if ((rc = getAsnLength(&p, (int32) (end - p), &tmplen)) < 0)
+ {
+ if (decryptKey)
+ {
+ memset_s(decryptKey, keyLen, 0x0, keyLen);
+ psFree(decryptKey, pool);
+ }
+ psFree(iv, pool);
+ return PS_PARSE_FAIL;
+ }
+ }
+ else if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
+ {
+ p++;
+ if ((rc = getAsnLength(&p, (int32) (end - p), &tmplen)) < 0)
+ {
+ if (decryptKey)
+ {
+ memset_s(decryptKey, keyLen, 0x0, keyLen);
+ psFree(decryptKey, pool);
+ }
+ psFree(iv, pool);
+ return PS_PARSE_FAIL;
+ }
+ if ((uint32) (end - p) < 1 ||
+ *p++ != ASN_OCTET_STRING ||
+ getAsnLength(&p, (int32) (end - p), &tmplen) < 0)
+ {
+ if (decryptKey)
+ {
+ memset_s(decryptKey, keyLen, 0x0, keyLen);
+ psFree(decryptKey, pool);
+ }
+ psFree(iv, pool);
+ return PS_PARSE_FAIL;
+ }
+ }
+ else if (*p == ASN_OCTET_STRING)
+ {
+ p++;
+ if ((rc = getAsnLength(&p, (int32) (end - p), &tmplen)) < 0)
+ {
+ if (decryptKey)
+ {
+ memset_s(decryptKey, keyLen, 0x0, keyLen);
+ psFree(decryptKey, pool);
+ }
+ psFree(iv, pool);
+ return PS_PARSE_FAIL;
+ }
+ }
+ else
+ {
+ psTraceCrypto("Error finding ciphertext in pkcs12import\n");
+ if (decryptKey)
+ {
+ memset_s(decryptKey, keyLen, 0x0, keyLen);
+ psFree(decryptKey, pool);
+ }
+ psFree(iv, pool);
+ return PS_PARSE_FAIL;
+ }
- if (tmplen < 1 || (uint32)(end - p) < tmplen) {
- return PS_PARSE_FAIL;
- }
+ if (tmplen < 1 || (uint32) (end - p) < tmplen)
+ {
+ return PS_PARSE_FAIL;
+ }
- /* Don't decrypt in-situ because we'll need to MAC this all later */
- if ((pt = psMalloc(pool, tmplen)) == NULL) {
- psTraceCrypto("Out-of-memory. Increase SSL_KEY_POOL_SIZE\n");
- if (decryptKey) {
- memset_s(decryptKey, keyLen, 0x0, keyLen);
- psFree(decryptKey, pool);
- }
- psFree(iv, pool);
- return PS_MEM_FAIL;
- }
- if (cipher == AUTH_SAFE_3DES) {
- if ((rc = psDes3Init(&ctx.des3, iv, decryptKey)) < 0) {
- memset_s(&ctx, sizeof(psCipherContext_t), 0x0, sizeof(psCipherContext_t));
- if (decryptKey) {
- memset_s(decryptKey, keyLen, 0x0, keyLen);
- psFree(decryptKey, pool);
- }
- psFree(iv, pool);
- psFree(pt, pool);
- return rc;
- }
- psDes3Decrypt(&ctx.des3, p, pt, tmplen);
- }
-#ifdef USE_RC2
- if (cipher == AUTH_SAFE_RC2) {
+ /* Don't decrypt in-situ because we'll need to MAC this all later */
+ if ((pt = psMalloc(pool, tmplen)) == NULL)
+ {
+ psTraceCrypto("Out-of-memory. Increase SSL_KEY_POOL_SIZE\n");
+ if (decryptKey)
+ {
+ memset_s(decryptKey, keyLen, 0x0, keyLen);
+ psFree(decryptKey, pool);
+ }
+ psFree(iv, pool);
+ return PS_MEM_FAIL;
+ }
+ if (cipher == AUTH_SAFE_3DES)
+ {
+ if ((rc = psDes3Init(&ctx.des3, iv, decryptKey)) < 0)
+ {
+ memset_s(&ctx, sizeof(psCipherContext_t), 0x0, sizeof(psCipherContext_t));
+ if (decryptKey)
+ {
+ memset_s(decryptKey, keyLen, 0x0, keyLen);
+ psFree(decryptKey, pool);
+ }
+ psFree(iv, pool);
+ psFree(pt, pool);
+ return rc;
+ }
+ psDes3Decrypt(&ctx.des3, p, pt, tmplen);
+ }
+# ifdef USE_RC2
+ if (cipher == AUTH_SAFE_RC2)
+ {
- /* This is a 40-bit RC2! */
- if ((rc = psRc2Init(&ctx.rc2, iv, decryptKey, 5)) < 0) {
- memset_s(&ctx, sizeof(psCipherContext_t), 0x0, sizeof(psCipherContext_t));
- if (decryptKey) {
- memset_s(decryptKey, keyLen, 0x0, keyLen);
- psFree(decryptKey, pool);
- }
- psFree(iv, pool);
- psFree(pt, pool);
- return rc;
- }
- if ((rc = psRc2Decrypt(&ctx.rc2, p, pt, tmplen)) < 0) {
- memset_s(&ctx, sizeof(psCipherContext_t), 0x0, sizeof(psCipherContext_t));
- if (decryptKey) {
- memset_s(decryptKey, keyLen, 0x0, keyLen);
- psFree(decryptKey, pool);
- }
- psFree(iv, pool);
- psFree(pt, pool);
- return rc;
- }
- }
-#endif /* USE_RC2 */
+ /* This is a 40-bit RC2! */
+ if ((rc = psRc2Init(&ctx.rc2, iv, decryptKey, 5)) < 0)
+ {
+ memset_s(&ctx, sizeof(psCipherContext_t), 0x0, sizeof(psCipherContext_t));
+ if (decryptKey)
+ {
+ memset_s(decryptKey, keyLen, 0x0, keyLen);
+ psFree(decryptKey, pool);
+ }
+ psFree(iv, pool);
+ psFree(pt, pool);
+ return rc;
+ }
+ if ((rc = psRc2Decrypt(&ctx.rc2, p, pt, tmplen)) < 0)
+ {
+ memset_s(&ctx, sizeof(psCipherContext_t), 0x0, sizeof(psCipherContext_t));
+ if (decryptKey)
+ {
+ memset_s(decryptKey, keyLen, 0x0, keyLen);
+ psFree(decryptKey, pool);
+ }
+ psFree(iv, pool);
+ psFree(pt, pool);
+ return rc;
+ }
+ }
+# endif /* USE_RC2 */
- if (decryptKey) {
- memset_s(decryptKey, keyLen, 0x0, keyLen);
- psFree(decryptKey, pool);
- }
- psFree(iv, pool);
+ if (decryptKey)
+ {
+ memset_s(decryptKey, keyLen, 0x0, keyLen);
+ psFree(decryptKey, pool);
+ }
+ psFree(iv, pool);
- *plaintext = pt;
- *ptLen = tmplen;
- return (int32)(p - start);
+ *plaintext = pt;
+ *ptLen = tmplen;
+ return (int32) (p - start);
}
/******************************************************************************/
/*
- Determines what the safebag is and loads the material into the users
- data structure (cert or private key)
-*/
+ Determines what the safebag is and loads the material into the users
+ data structure (cert or private key)
+ */
static int32 parseSafeContents(psPool_t *pool, unsigned char *password,
- uint32 passLen, psX509Cert_t **cert, psPubKey_t *privKey,
- unsigned char *buf, uint32 totlen)
+ uint32 passLen, psX509Cert_t **cert, psPubKey_t *privKey,
+ unsigned char *buf, uint32 totlen)
{
- psX509Cert_t *currCert, *frontCert;
- const unsigned char *p, *end;
- unsigned char *pt, *safeLen;
- uint16_t tmplen, cryptlen, tmpint;
- int32 rc, bagoi, certoi;
-#ifdef PARSE_PKCS12_SAFE_ATTRIBS
- uint32 attriblen;
- int32 attriboi;
-#endif
+ psX509Cert_t *currCert, *frontCert;
+ const unsigned char *p, *end;
+ unsigned char *pt, *safeLen;
+ psSize_t tmplen, cryptlen, tmpint;
+ int32 rc, bagoi, certoi;
- p = buf;
- end = p + totlen;
+# ifdef PARSE_PKCS12_SAFE_ATTRIBS
+ uint32 attriblen;
+ int32 attriboi;
+# endif
- /* SafeContents ::= SEQUENCE OF SafeBag
+ p = buf;
+ end = p + totlen;
- SafeBag ::= SEQUENCE {
- bagId BAG-TYPE.&id ({PKCS12BagSet})
- bagValue [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}),
- bagAttributes SET OF PKCS12Attribute OPTIONAL
- } */
- if ((rc = getAsnSequence(&p, (int32)(end - p), &tmplen)) < 0) {
- psTraceCrypto("Initial SafeContents parse failure\n");
- return rc;
- }
+ /* SafeContents ::= SEQUENCE OF SafeBag
- end = p + tmplen;
+ SafeBag ::= SEQUENCE {
+ bagId BAG-TYPE.&id ({PKCS12BagSet})
+ bagValue [0] EXPLICIT BAG-TYPE.&Type({PKCS12BagSet}{@bagId}),
+ bagAttributes SET OF PKCS12Attribute OPTIONAL
+ } */
+ if ((rc = getAsnSequence(&p, (int32) (end - p), &tmplen)) < 0)
+ {
+ psTraceCrypto("Initial SafeContents parse failure\n");
+ return rc;
+ }
- while (p < end) {
- /*
- bagtypes OBJECT IDENTIFIER ::= {pkcs-12 10 1}
+ end = p + tmplen;
- BAG-TYPE ::= TYPE-IDENTIFIER
- keyBag BAG-TYPE ::= {KeyBag IDENTIFIED BY {bagtypes 1}}
- pkcs8ShroudedKeyBag BAG-TYPE ::= {PKCS8ShroudedKeyBag IDENTIFIED BY
- {bagtypes 2}}
- certBag BAG-TYPE ::= {CertBag IDENTIFIED BY {bagtypes 3}}
- crlBag BAG-TYPE ::= {CRLBag IDENTIFIED BY {bagtypes 4}}
- secretBag BAG-TYPE ::= {SecretBag IDENTIFIED BY {bagtypes 5}}
- safeContentsBag BAG-TYPE ::= {SafeContents IDENTIFIED BY
- {bagtypes 6}}
+ while (p < end)
+ {
+ /*
+ bagtypes OBJECT IDENTIFIER ::= {pkcs-12 10 1}
- PKCS12BagSet BAG-TYPE ::= {
- keyBag | pkcs8ShroudedKeyBag | certBag | crlBag | secretBag |
- safeContentsBag, ... -- For future extensions}
+ BAG-TYPE ::= TYPE-IDENTIFIER
+ keyBag BAG-TYPE ::= {KeyBag IDENTIFIED BY {bagtypes 1}}
+ pkcs8ShroudedKeyBag BAG-TYPE ::= {PKCS8ShroudedKeyBag IDENTIFIED BY
+ {bagtypes 2}}
+ certBag BAG-TYPE ::= {CertBag IDENTIFIED BY {bagtypes 3}}
+ crlBag BAG-TYPE ::= {CRLBag IDENTIFIED BY {bagtypes 4}}
+ secretBag BAG-TYPE ::= {SecretBag IDENTIFIED BY {bagtypes 5}}
+ safeContentsBag BAG-TYPE ::= {SafeContents IDENTIFIED BY
+ {bagtypes 6}}
- */
- if ((rc = getAsnAlgorithmIdentifier(&p, (int32)(end - p), &bagoi,
- &tmpint)) < 0) {
- psTraceCrypto("Initial BagType parse failure\n");
- return rc;
- }
- safeLen = (unsigned char*)p + tmpint;
- if (*p++ != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
- return PS_PARSE_FAIL;
- }
- if ((rc = getAsnLength(&p, (int32)(end - p), &tmplen)) < 0) {
- return PS_PARSE_FAIL;
- }
+ PKCS12BagSet BAG-TYPE ::= {
+ keyBag | pkcs8ShroudedKeyBag | certBag | crlBag | secretBag |
+ safeContentsBag, ... -- For future extensions}
- switch (bagoi) {
- case OID_PKCS12_BAG_TYPE_CERT:
- /*
- CertBag ::= SEQUENCE {
- certId BAG-TYPE.&id ({CertTypes}),
- certValue [0] EXPLICIT BAG-TYPE.&Type ({CertTypes}{@certId}) }
+ */
+ if ((rc = getAsnAlgorithmIdentifier(&p, (int32) (end - p), &bagoi,
+ &tmpint)) < 0)
+ {
+ psTraceCrypto("Initial BagType parse failure\n");
+ return rc;
+ }
+ safeLen = (unsigned char *) p + tmpint;
+ if (*p++ != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
+ {
+ return PS_PARSE_FAIL;
+ }
+ if ((rc = getAsnLength(&p, (int32) (end - p), &tmplen)) < 0)
+ {
+ return PS_PARSE_FAIL;
+ }
- x509Certificate BAG-TYPE ::=
- {OCTET STRING IDENTIFIED BY {certTypes 1}}
- -- DER-encoded X.509 certificate stored in OCTET STRING
- sdsiCertificate BAG-TYPE ::=
- {IA5String IDENTIFIED BY {certTypes 2}}
- -- Base64-encoded SDSI certificate stored in IA5String
+ switch (bagoi)
+ {
+ case OID_PKCS12_BAG_TYPE_CERT:
+ /*
+ CertBag ::= SEQUENCE {
+ certId BAG-TYPE.&id ({CertTypes}),
+ certValue [0] EXPLICIT BAG-TYPE.&Type ({CertTypes}{@certId}) }
- CertTypes BAG-TYPE ::= {
- x509Certificate |
- sdsiCertificate,
- ... -- For future extensions
- }
- */
- if ((rc = getAsnAlgorithmIdentifier(&p, (int32)(end - p),
- &certoi, &tmpint)) < 0) {
- psTraceCrypto("Initial CertBag parse failure\n");
- return rc;
- }
- if (certoi != OID_PKCS9_CERT_TYPE_X509) {
- psTraceIntCrypto("Unsupported CertBag type %d\n", certoi);
- return PS_UNSUPPORTED_FAIL;
- }
- if (*p++ != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
- return PS_PARSE_FAIL;
- }
- if ((rc = getAsnLength(&p, (int32)(end - p), &tmplen)) < 0) {
- return rc;
- }
- if ((*p++ != ASN_OCTET_STRING) ||
- getAsnLength(&p, (int32)(end - p), &tmplen) < 0) {
- psTraceCrypto("Couldn't extract X509 CertBag\n");
- return PS_FAILURE;
- }
- /* Support cert chains */
- currCert = frontCert = *cert;
- while (currCert != NULL) {
- currCert = currCert->next;
- }
- if ((rc = psX509ParseCert(pool, p, tmplen, &currCert,
- CERT_STORE_UNPARSED_BUFFER)) < 0) {
- psX509FreeCert(currCert);
- *cert = NULL;
- psTraceCrypto("Couldn't parse certificate from CertBag\n");
- return rc;
- }
- if (*cert == NULL) {
- *cert = currCert;
- } else {
- while (frontCert->next != NULL) {
- frontCert = frontCert->next;
- }
- frontCert->next = currCert;
- }
- p += rc;
- break;
+ x509Certificate BAG-TYPE ::=
+ {OCTET STRING IDENTIFIED BY {certTypes 1}}
+ -- DER-encoded X.509 certificate stored in OCTET STRING
+ sdsiCertificate BAG-TYPE ::=
+ {IA5String IDENTIFIED BY {certTypes 2}}
+ -- Base64-encoded SDSI certificate stored in IA5String
- case OID_PKCS12_BAG_TYPE_SHROUD:
- /* A PKCS8ShroudedKeyBag holds a private key, which has been
- shrouded in accordance with PKCS #8. Note that a
- PKCS8ShroudedKeyBag holds only one shrouded private key. */
- if (getAsnSequence(&p, (int32)(end - p), &tmplen) < 0) {
- psTraceCrypto("Initial PKCS8 ShroudKeyBag parse failure\n");
- return PS_PARSE_FAIL;
- }
- if ((rc = pkcs12import(pool, &p,
- (int32)(end - p), password, passLen, &pt, &cryptlen)) < 0) {
- psTraceIntCrypto("Import failed from AuthSafe %d\n", rc);
- return rc;
- }
- p += rc;
- /* Result of decrypt will be a PKCS#8 key */
- if ((rc = pkcs8ParsePrivBin(pool, pt, cryptlen, NULL, privKey))
- < 0) {
- psFree(pt, pool);
- psTraceIntCrypto("Failed shroud PKCS8 key parse %d\n", rc);
- return rc;
- }
- psFree(pt, pool);
- p += cryptlen;
- break;
- case OID_PKCS12_BAG_TYPE_KEY:
- if ((rc = pkcs8ParsePrivBin(pool, (unsigned char*)p, tmplen,
- NULL, privKey)) < 0) {
- psTraceIntCrypto("Failed PKCS8 key parse %d\n", rc);
- return rc;
- }
- p += tmplen;
- break;
- default:
- psTraceIntCrypto("Unsupported BAG_TYPE %d\n", bagoi);
- return PS_UNSUPPORTED_FAIL;
- }
+ CertTypes BAG-TYPE ::= {
+ x509Certificate |
+ sdsiCertificate,
+ ... -- For future extensions
+ }
+ */
+ if ((rc = getAsnAlgorithmIdentifier(&p, (int32) (end - p),
+ &certoi, &tmpint)) < 0)
+ {
+ psTraceCrypto("Initial CertBag parse failure\n");
+ return rc;
+ }
+ if (certoi != OID_PKCS9_CERT_TYPE_X509)
+ {
+ psTraceIntCrypto("Unsupported CertBag type %d\n", certoi);
+ return PS_UNSUPPORTED_FAIL;
+ }
+ if (*p++ != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
+ {
+ return PS_PARSE_FAIL;
+ }
+ if ((rc = getAsnLength(&p, (int32) (end - p), &tmplen)) < 0)
+ {
+ return rc;
+ }
+ if ((*p++ != ASN_OCTET_STRING) ||
+ getAsnLength(&p, (int32) (end - p), &tmplen) < 0)
+ {
+ psTraceCrypto("Couldn't extract X509 CertBag\n");
+ return PS_FAILURE;
+ }
+ /* Support cert chains */
+ currCert = frontCert = *cert;
+ while (currCert != NULL)
+ {
+ currCert = currCert->next;
+ }
+ if ((rc = psX509ParseCert(pool, p, tmplen, &currCert,
+ CERT_STORE_UNPARSED_BUFFER)) < 0)
+ {
+ psX509FreeCert(currCert);
+ *cert = NULL;
+ psTraceCrypto("Couldn't parse certificate from CertBag\n");
+ return rc;
+ }
+ if (*cert == NULL)
+ {
+ *cert = currCert;
+ }
+ else
+ {
+ while (frontCert->next != NULL)
+ {
+ frontCert = frontCert->next;
+ }
+ frontCert->next = currCert;
+ }
+ p += rc;
+ break;
- /* Attributes are at the end of the data */
- while (p != safeLen) {
-#ifdef PARSE_PKCS12_SAFE_ATTRIBS
- /**/
- if ((rc = getAsnSet(&p, (int32)(end - p), &attriblen)) < 0) {
- return rc;
- }
- if ((rc = getAsnAlgorithmIdentifier(&p, (int32)(end - p), &attriboi,
- &pLen)) < 0) {
- return rc;
- }
- if ((rc = getAsnSet(&p, (int32)(end - p), &attriblen)) < 0) {
- return rc;
- }
- if ((*p++ != ASN_OCTET_STRING) ||
- getAsnLength(&p, (int32)(end - p), &tmplen) < 0) {
- psTraceCrypto("Couldn't parse PKCS#8 param salt\n");
- return PS_FAILURE;
- }
- p += tmplen;
-#else
- p = safeLen;
-#endif
- }
- }
- return totlen;
+ case OID_PKCS12_BAG_TYPE_SHROUD:
+ /* A PKCS8ShroudedKeyBag holds a private key, which has been
+ shrouded in accordance with PKCS #8. Note that a
+ PKCS8ShroudedKeyBag holds only one shrouded private key. */
+ if (getAsnSequence(&p, (int32) (end - p), &tmplen) < 0)
+ {
+ psTraceCrypto("Initial PKCS8 ShroudKeyBag parse failure\n");
+ return PS_PARSE_FAIL;
+ }
+ if ((rc = pkcs12import(pool, &p,
+ (int32) (end - p), password, passLen, &pt, &cryptlen)) < 0)
+ {
+ psTraceIntCrypto("Import failed from AuthSafe %d\n", rc);
+ return rc;
+ }
+ p += rc;
+ /* Result of decrypt will be a PKCS#8 key */
+ if ((rc = psPkcs8ParsePrivBin(pool, pt, cryptlen, NULL, privKey))
+ < 0)
+ {
+ psFree(pt, pool);
+ psTraceIntCrypto("Failed shroud PKCS8 key parse %d\n", rc);
+ return rc;
+ }
+ psFree(pt, pool);
+ p += cryptlen;
+ break;
+ case OID_PKCS12_BAG_TYPE_KEY:
+ if ((rc = psPkcs8ParsePrivBin(pool, (unsigned char *) p, tmplen,
+ NULL, privKey)) < 0)
+ {
+ psTraceIntCrypto("Failed PKCS8 key parse %d\n", rc);
+ return rc;
+ }
+ p += tmplen;
+ break;
+ default:
+ psTraceIntCrypto("Unsupported BAG_TYPE %d\n", bagoi);
+ return PS_UNSUPPORTED_FAIL;
+ }
+
+ /* Attributes are at the end of the data */
+ while (p != safeLen)
+ {
+# ifdef PARSE_PKCS12_SAFE_ATTRIBS
+ /**/
+ if ((rc = getAsnSet(&p, (int32) (end - p), &attriblen)) < 0)
+ {
+ return rc;
+ }
+ if ((rc = getAsnAlgorithmIdentifier(&p, (int32) (end - p), &attriboi,
+ &pLen)) < 0)
+ {
+ return rc;
+ }
+ if ((rc = getAsnSet(&p, (int32) (end - p), &attriblen)) < 0)
+ {
+ return rc;
+ }
+ if ((*p++ != ASN_OCTET_STRING) ||
+ getAsnLength(&p, (int32) (end - p), &tmplen) < 0)
+ {
+ psTraceCrypto("Couldn't parse PKCS#8 param salt\n");
+ return PS_FAILURE;
+ }
+ p += tmplen;
+# else
+ p = safeLen;
+# endif
+ }
+ }
+ return totlen;
}
/******************************************************************************/
/*
- AuthenticatedSafe ::= SEQUENCE OF ContentInfo
- -- Data if unencrypted
- -- EncryptedData if password-encrypted
- -- EnvelopedData if public key-encrypted
-*/
+ AuthenticatedSafe ::= SEQUENCE OF ContentInfo
+ -- Data if unencrypted
+ -- EncryptedData if password-encrypted
+ -- EnvelopedData if public key-encrypted
+ */
static int32 psParseAuthenticatedSafe(psPool_t *pool, psX509Cert_t **cert,
- psPubKey_t *privKey, unsigned char *importPass, int32 ipassLen,
- unsigned char **buf, int32 totLen)
+ psPubKey_t *privKey, unsigned char *importPass, int32 ipassLen,
+ unsigned char **buf, int32 totLen)
{
- const unsigned char *p, *end;
- unsigned char *pt;
- uint16_t tmplen, tmpint;
- int32_t asnint;
- int32 rc, oi;
+ const unsigned char *p, *end;
+ unsigned char *pt;
+ psSize_t tmplen, tmpint;
+ int32_t asnint;
+ int32 rc, oi;
- p = *buf;
- end = p + totLen;
- if ((rc = getAsnSequence(&p, (int32)(end - p), &tmplen)) < 0) {
- psTraceCrypto("Initial authenticated safe parse failure\n");
- return rc;
- }
+ p = *buf;
+ end = p + totLen;
+ if ((rc = getAsnSequence(&p, (int32) (end - p), &tmplen)) < 0)
+ {
+ psTraceCrypto("Initial authenticated safe parse failure\n");
+ return rc;
+ }
- end = p + tmplen; /* Set end to be end of authSafe for list walk */
+ end = p + tmplen; /* Set end to be end of authSafe for list walk */
- while (p < end) {
- if ((rc = getAsnAlgorithmIdentifier(&p, (int32)(end - p), &oi,
- &tmpint)) < 0) {
- psTraceCrypto("Initial content info parse failure\n");
- return rc;
- }
- if (oi == OID_PKCS7_ENCRYPTED_DATA) {
- /* password protected mode */
- if (*p++ != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
- psTraceCrypto("Initial pkcs7 encrypted data parse failure\n");
- return PS_PARSE_FAIL;
- }
- if ((rc = getAsnLength(&p, (int32)(end - p), &tmplen)) < 0) {
- return PS_PARSE_FAIL;
- }
- /* EncryptedData ::= SEQUENCE {
- version Version,
- encryptedContentInfo EncryptedContentInfo } */
- if ((rc = getAsnSequence(&p, (int32)(end - p), &tmplen)) < 0) {
- return rc;
- }
- /* Version */
- if (getAsnInteger(&p, (int32)(end - p), &asnint) < 0 ||
- asnint != 0) {
- psTraceIntCrypto("Unsupported encryptd data version %d\n",
- asnint);
- return PS_UNSUPPORTED_FAIL;
- }
- /*
- EncryptedContentInfo ::= SEQUENCE {
- contentType ContentType,
- contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
- encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL }
+ while (p < end)
+ {
+ if ((rc = getAsnAlgorithmIdentifier(&p, (int32) (end - p), &oi,
+ &tmpint)) < 0)
+ {
+ psTraceCrypto("Initial content info parse failure\n");
+ return rc;
+ }
+ if (oi == OID_PKCS7_ENCRYPTED_DATA)
+ {
+ /* password protected mode */
+ if (*p++ != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
+ {
+ psTraceCrypto("Initial pkcs7 encrypted data parse failure\n");
+ return PS_PARSE_FAIL;
+ }
+ if ((rc = getAsnLength(&p, (int32) (end - p), &tmplen)) < 0)
+ {
+ return PS_PARSE_FAIL;
+ }
+ /* EncryptedData ::= SEQUENCE {
+ version Version,
+ encryptedContentInfo EncryptedContentInfo } */
+ if ((rc = getAsnSequence(&p, (int32) (end - p), &tmplen)) < 0)
+ {
+ return rc;
+ }
+ /* Version */
+ if (getAsnInteger(&p, (int32) (end - p), &asnint) < 0 ||
+ asnint != 0)
+ {
+ psTraceIntCrypto("Unsupported encryptd data version %d\n",
+ asnint);
+ return PS_UNSUPPORTED_FAIL;
+ }
+ /*
+ EncryptedContentInfo ::= SEQUENCE {
+ contentType ContentType,
+ contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
+ encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL }
- 5.1 2b) If SCi is to be encrypted with a password, make a
- ContentInfo CIi of type EncryptedData. The encryptedContentInfo
- field of CIi has its contentType field set to data and its
- encryptedContent field set to the encryption of the BER-encoding
- of SCi (note that the tag and length octets shall be present). */
- if ((rc = getAsnAlgorithmIdentifier(&p, (int32)(end - p), &oi,
- &tmpint)) < 0) {
- psTraceCrypto("Initial EncryptedContentInfo parse failure\n");
- return rc;
- }
- psAssert(oi == OID_PKCS7_DATA);
+ 5.1 2b) If SCi is to be encrypted with a password, make a
+ ContentInfo CIi of type EncryptedData. The encryptedContentInfo
+ field of CIi has its contentType field set to data and its
+ encryptedContent field set to the encryption of the BER-encoding
+ of SCi (note that the tag and length octets shall be present). */
+ if ((rc = getAsnAlgorithmIdentifier(&p, (int32) (end - p), &oi,
+ &tmpint)) < 0)
+ {
+ psTraceCrypto("Initial EncryptedContentInfo parse failure\n");
+ return rc;
+ }
+ psAssert(oi == OID_PKCS7_DATA);
- if ((rc = pkcs12import(pool, &p, (int32)(end - p), importPass,
- ipassLen, &pt, &tmplen)) < 0) {
- psTraceIntCrypto("Import failed from AuthSafe %d\n", rc);
- return rc;
- }
- p += rc;
+ if ((rc = pkcs12import(pool, &p, (int32) (end - p), importPass,
+ ipassLen, &pt, &tmplen)) < 0)
+ {
+ psTraceIntCrypto("Import failed from AuthSafe %d\n", rc);
+ return rc;
+ }
+ p += rc;
- /* pt is now a BER-encoded SafeContents */
- if ((rc = parseSafeContents(pool, importPass, ipassLen, cert,
- privKey, pt, tmplen)) < 0) {
- psTraceCrypto("Error parsing encrypted safe contents\n");
- psTraceCrypto("Is it possible the password is incorrect?\n");
- psFree(pt, pool);
- return rc;
- }
- psFree(pt, pool);
- p += rc;
- } else if (oi == OID_PKCS7_DATA) {
- /* Data ::= OCTET STRING */
- if (*p++ != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED)) {
- psTraceCrypto("Initial pkcs7 data parse failure\n");
- return PS_PARSE_FAIL;
- }
- if ((rc = getAsnLength(&p, (int32)(end - p), &tmplen)) < 0) {
- return PS_PARSE_FAIL;
- }
- if (*p++ != ASN_OCTET_STRING || getAsnLength(&p,
- (int32)(end - p), &tmplen) < 0) {
- return PS_PARSE_FAIL;
- }
- if ((rc = parseSafeContents(pool, importPass, ipassLen, cert,
- privKey, (unsigned char*)p, tmplen)) < 0) {
- psTraceCrypto("Error parsing plaintext safe contents\n");
- return rc;
- }
- p += rc;
- } else {
- psTraceIntCrypto("Unsupported PKCS7 data type parse %d\n", oi);
- return PS_UNSUPPORTED_FAIL;
- }
- }
+ /* pt is now a BER-encoded SafeContents */
+ if ((rc = parseSafeContents(pool, importPass, ipassLen, cert,
+ privKey, pt, tmplen)) < 0)
+ {
+ psTraceCrypto("Error parsing encrypted safe contents\n");
+ psTraceCrypto("Is it possible the password is incorrect?\n");
+ psFree(pt, pool);
+ return rc;
+ }
+ psFree(pt, pool);
+ p += rc;
+ }
+ else if (oi == OID_PKCS7_DATA)
+ {
+ /* Data ::= OCTET STRING */
+ if (*p++ != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
+ {
+ psTraceCrypto("Initial pkcs7 data parse failure\n");
+ return PS_PARSE_FAIL;
+ }
+ if ((rc = getAsnLength(&p, (int32) (end - p), &tmplen)) < 0)
+ {
+ return PS_PARSE_FAIL;
+ }
+ if (*p++ != ASN_OCTET_STRING || getAsnLength(&p,
+ (int32) (end - p), &tmplen) < 0)
+ {
+ return PS_PARSE_FAIL;
+ }
+ if ((rc = parseSafeContents(pool, importPass, ipassLen, cert,
+ privKey, (unsigned char *) p, tmplen)) < 0)
+ {
+ psTraceCrypto("Error parsing plaintext safe contents\n");
+ return rc;
+ }
+ p += rc;
+ }
+ else
+ {
+ psTraceIntCrypto("Unsupported PKCS7 data type parse %d\n", oi);
+ return PS_UNSUPPORTED_FAIL;
+ }
+ }
- *buf = (unsigned char*)p;
- return PS_SUCCESS;
+ *buf = (unsigned char *) p;
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- MacData ::= SEQUENCE {
- mac DigestInfo,
- macSalt OCTET STRING,
- iterations INTEGER DEFAULT 1
- }
-*/
+ MacData ::= SEQUENCE {
+ mac DigestInfo,
+ macSalt OCTET STRING,
+ iterations INTEGER DEFAULT 1
+ }
+ */
int32 psPkcs12Parse(psPool_t *pool, psX509Cert_t **cert, psPubKey_t *privKey,
- const unsigned char *file, int32 flags, unsigned char *password,
- int32 pLen, unsigned char *macPass, int32 macPassLen)
+ const unsigned char *file, int32 flags, unsigned char *password,
+ int32 pLen, unsigned char *macPass, int32 macPassLen)
{
- psHmacSha1_t hmac;
- const unsigned char *p, *end, *macStart, *macEnd;
- unsigned char *fileBuf, *macKey;
- unsigned char iwidePass[128]; /* 63 char password max */
- unsigned char mwidePass[128];
- unsigned char mac[SHA1_HASH_SIZE];
- unsigned char macSalt[20];
- unsigned char digest[SHA1_HASH_SIZE];
- uint16_t tmplen, tmpint;
- uint32 digestLen, macKeyLen;
- int32 fsize, i, j, rc, mpassLen, ipassLen, integrity, oi, asnint;
+ psHmacSha1_t hmac;
+ const unsigned char *p, *end, *macStart, *macEnd;
+ unsigned char *fileBuf, *macKey;
+ unsigned char iwidePass[128]; /* 63 char password max */
+ unsigned char mwidePass[128];
+ unsigned char mac[SHA1_HASH_SIZE];
+ unsigned char macSalt[20];
+ unsigned char digest[SHA1_HASH_SIZE];
+ psSize_t tmplen, tmpint;
+ uint32 digestLen, macKeyLen;
+ int32 fsize, i, j, rc, mpassLen, ipassLen, integrity, oi, asnint;
- *cert = NULL;
- if ((rc = psGetFileBuf(pool, (char *)file, &fileBuf, &fsize)) < PS_SUCCESS){
- psTraceStrCrypto("Couldn't open PKCS#12 file %s\n", (char*)file);
- return rc;
- }
- p = fileBuf;
- end = p + fsize;
+ *cert = NULL;
+ if ((rc = psGetFileBuf(pool, (char *) file, &fileBuf, &fsize)) < PS_SUCCESS)
+ {
+ psTraceStrCrypto("Couldn't open PKCS#12 file %s\n", (char *) file);
+ return rc;
+ }
+ p = fileBuf;
+ end = p + fsize;
- /* Begin with a PFX
- PFX ::= SEQUENCE {
- version INTEGER {v3(3)}(v3,...),
- authSafe ContentInfo,
- macData MacData OPTIONAL } */
- if ((rc = getAsnSequence(&p, (int32)(end - p), &tmplen)) < 0) {
- psTraceCrypto("Initial PKCS#12 parse fail\n");
- goto ERR_FBUF;
- }
- /* Version */
- if (getAsnInteger(&p, (int32)(end - p), &asnint) < 0 || asnint != 3) {
- psTraceIntCrypto("Unsupported PKCS#12 version %d\n", asnint);
- rc = PS_UNSUPPORTED_FAIL;
- goto ERR_FBUF;
- }
+ /* Begin with a PFX
+ PFX ::= SEQUENCE {
+ version INTEGER {v3(3)}(v3,...),
+ authSafe ContentInfo,
+ macData MacData OPTIONAL } */
+ if ((rc = getAsnSequence(&p, (int32) (end - p), &tmplen)) < 0)
+ {
+ psTraceCrypto("Initial PKCS#12 parse fail\n");
+ goto ERR_FBUF;
+ }
+ /* Version */
+ if (getAsnInteger(&p, (int32) (end - p), &asnint) < 0 || asnint != 3)
+ {
+ psTraceIntCrypto("Unsupported PKCS#12 version %d\n", asnint);
+ rc = PS_UNSUPPORTED_FAIL;
+ goto ERR_FBUF;
+ }
- /* Content type is the integrity mode (4 of the spec).
- signedData for public-key integrity or data for password integrity */
- if ((integrity = psParseIntegrityMode(&p, (int32)(end - p)))
- < PS_SUCCESS) {
- psTraceCrypto("Couldn't determine PKCS#12 integrity\n");
- rc = integrity;
- goto ERR_FBUF;
- }
+ /* Content type is the integrity mode (4 of the spec).
+ signedData for public-key integrity or data for password integrity */
+ if ((integrity = psParseIntegrityMode(&p, (int32) (end - p)))
+ < PS_SUCCESS)
+ {
+ psTraceCrypto("Couldn't determine PKCS#12 integrity\n");
+ rc = integrity;
+ goto ERR_FBUF;
+ }
- /* Passwords are wide BMPString types
- ipass is import password
- mpass is MAC password */
- ipassLen = (pLen * 2) + 2; /* 2 for each char put double 0x0 to terminate */
- memset(iwidePass, 0x0, ipassLen);
- for (i = 1, j = 0; i < ipassLen - 1; i += 2, j++) {
- iwidePass[i] = password[j];
- }
+ /* Passwords are wide BMPString types
+ ipass is import password
+ mpass is MAC password */
+ ipassLen = (pLen * 2) + 2; /* 2 for each char put double 0x0 to terminate */
+ memset(iwidePass, 0x0, ipassLen);
+ for (i = 1, j = 0; i < ipassLen - 1; i += 2, j++)
+ {
+ iwidePass[i] = password[j];
+ }
- /* Content data is an AuthenticatedSafe */
- macStart = p;
- if ((rc = psParseAuthenticatedSafe(pool, cert, privKey, iwidePass, ipassLen,
- (unsigned char**)&p, (int32)(end - p))) < PS_SUCCESS) {
- psTraceIntCrypto("PKCS#12 AuthenticatedSafe parse failure %d\n", rc);
- goto ERR_FBUF;
- }
- macEnd = p;
+ /* Content data is an AuthenticatedSafe */
+ macStart = p;
+ if ((rc = psParseAuthenticatedSafe(pool, cert, privKey, iwidePass, ipassLen,
+ (unsigned char **) &p, (int32) (end - p))) < PS_SUCCESS)
+ {
+ psTraceIntCrypto("PKCS#12 AuthenticatedSafe parse failure %d\n", rc);
+ goto ERR_FBUF;
+ }
+ macEnd = p;
- /* Integrity validation */
- if (integrity == PASSWORD_INTEGRITY) {
- mpassLen = (macPassLen * 2) + 2;
- memset(mwidePass, 0x0, mpassLen);
- for (i = 1, j = 0; i < mpassLen - 1; i += 2, j++) {
- mwidePass[i] = macPass[j];
- }
- /* MacData ::= SEQUENCE {
- mac DigestInfo,
- macSalt OCTET STRING,
- iterations INTEGER DEFAULT 1
- -- Note: The default is for historical reasons and its use is
- -- deprecated. A higher value, like 1024 is recommended. } */
- if ((rc = getAsnSequence(&p, (int32)(end - p), &tmplen)) < 0) {
- psTraceCrypto("Initial password integrity parse failure\n");
- goto ERR_FBUF;
- }
- /* DigestInfo ::= SEQUENCE {
- digestAlgorithm DigestAlgorithmIdentifier,
- digest Digest } */
- if ((rc = getAsnSequence(&p, (int32)(end - p), &tmplen)) < 0) {
- psTraceCrypto("Sequence password integrity parse failure\n");
- goto ERR_FBUF;
- }
- if ((rc = getAsnAlgorithmIdentifier(&p, (uint32)(end - p),
- &oi, &tmpint)) < 0) {
- psTraceCrypto("Algorithm password integrity parse failure\n");
- goto ERR_FBUF;
- }
- if ((*p++ != ASN_OCTET_STRING) ||
- getAsnLength(&p, (int32)(end - p), &tmplen) < 0) {
- psTraceCrypto("Octet digest password integrity parse failure\n");
- rc = PS_PARSE_FAIL;
- goto ERR_FBUF;
- }
- memcpy(digest, p, tmplen);
- p += tmplen;
- if ((*p++ != ASN_OCTET_STRING) ||
- getAsnLength(&p, (int32)(end - p), &tmplen) < 0) {
- psTraceCrypto("Octet macSalt password integrity parse failure\n");
- rc = PS_PARSE_FAIL;
- goto ERR_FBUF;
- }
- if (tmplen > 20) {
- psTraceCrypto("macSalt length too long\n");
- rc = PS_PARSE_FAIL;
- goto ERR_FBUF;
- }
- memcpy(macSalt, p, tmplen);
- p += tmplen;
- /* Iteration count */
- if (p != end) {
- if (getAsnInteger(&p, (int32)(end - p), &asnint) < 0) {
- psTraceCrypto("Iteration password integrity parse failure\n");
- rc = PS_PARSE_FAIL;
- goto ERR_FBUF;
- }
- } else {
- asnint = 0;
- }
- psAssert(p == end); /* That's all folks */
+ /* Integrity validation */
+ if (integrity == PASSWORD_INTEGRITY)
+ {
+ mpassLen = (macPassLen * 2) + 2;
+ memset(mwidePass, 0x0, mpassLen);
+ for (i = 1, j = 0; i < mpassLen - 1; i += 2, j++)
+ {
+ mwidePass[i] = macPass[j];
+ }
+ /* MacData ::= SEQUENCE {
+ mac DigestInfo,
+ macSalt OCTET STRING,
+ iterations INTEGER DEFAULT 1
+ -- Note: The default is for historical reasons and its use is
+ -- deprecated. A higher value, like 1024 is recommended. } */
+ if ((rc = getAsnSequence(&p, (int32) (end - p), &tmplen)) < 0)
+ {
+ psTraceCrypto("Initial password integrity parse failure\n");
+ goto ERR_FBUF;
+ }
+ /* DigestInfo ::= SEQUENCE {
+ digestAlgorithm DigestAlgorithmIdentifier,
+ digest Digest } */
+ if ((rc = getAsnSequence(&p, (int32) (end - p), &tmplen)) < 0)
+ {
+ psTraceCrypto("Sequence password integrity parse failure\n");
+ goto ERR_FBUF;
+ }
+ if ((rc = getAsnAlgorithmIdentifier(&p, (uint32) (end - p),
+ &oi, &tmpint)) < 0)
+ {
+ psTraceCrypto("Algorithm password integrity parse failure\n");
+ goto ERR_FBUF;
+ }
+ if ((*p++ != ASN_OCTET_STRING) ||
+ getAsnLength(&p, (int32) (end - p), &tmplen) < 0)
+ {
+ psTraceCrypto("Octet digest password integrity parse failure\n");
+ rc = PS_PARSE_FAIL;
+ goto ERR_FBUF;
+ }
+ memcpy(digest, p, tmplen);
+ p += tmplen;
+ if ((*p++ != ASN_OCTET_STRING) ||
+ getAsnLength(&p, (int32) (end - p), &tmplen) < 0)
+ {
+ psTraceCrypto("Octet macSalt password integrity parse failure\n");
+ rc = PS_PARSE_FAIL;
+ goto ERR_FBUF;
+ }
+ if (tmplen > 20)
+ {
+ psTraceCrypto("macSalt length too long\n");
+ rc = PS_PARSE_FAIL;
+ goto ERR_FBUF;
+ }
+ memcpy(macSalt, p, tmplen);
+ p += tmplen;
+ /* Iteration count */
+ if (p != end)
+ {
+ if (getAsnInteger(&p, (int32) (end - p), &asnint) < 0)
+ {
+ psTraceCrypto("Iteration password integrity parse failure\n");
+ rc = PS_PARSE_FAIL;
+ goto ERR_FBUF;
+ }
+ }
+ else
+ {
+ asnint = 0;
+ }
+ psAssert(p == end); /* That's all folks */
- if (oi == OID_SHA1_ALG) {
- /* When password integrity mode is used to secure a PFX PDU,
- an SHA-1 HMAC is computed on the BER-encoding of the contents
- of the content field of the authSafe field in the PFX PDU */
- macKeyLen = 20;
- if (pkcs12pbe(pool, mwidePass, mpassLen, macSalt, tmplen,
- asnint, PKCS12_MAC_ID, &macKey, &macKeyLen) < 0) {
- psTraceCrypto("Error generating pkcs12 hmac key\n");
- rc = PS_UNSUPPORTED_FAIL;
- goto ERR_FBUF;
- }
- digestLen = (uint32)(macEnd - macStart);
- psHmacSha1Init(&hmac, macKey, macKeyLen);
- psHmacSha1Update(&hmac, macStart, digestLen);
- psHmacSha1Final(&hmac, mac);
- psFree(macKey, pool);
- if (memcmp(digest, mac, SHA1_HASH_SIZE) != 0) {
- psTraceCrypto("CAUTION: PKCS#12 MAC did not validate\n");
- }
- } else {
- psTraceCrypto("PKCS#12 must use SHA1 HMAC validation\n");
- rc = PS_UNSUPPORTED_FAIL;
- goto ERR_FBUF;
- }
+ if (oi == OID_SHA1_ALG)
+ {
+ /* When password integrity mode is used to secure a PFX PDU,
+ an SHA-1 HMAC is computed on the BER-encoding of the contents
+ of the content field of the authSafe field in the PFX PDU */
+ macKeyLen = 20;
+ if (pkcs12pbe(pool, mwidePass, mpassLen, macSalt, tmplen,
+ asnint, PKCS12_MAC_ID, &macKey, &macKeyLen) < 0)
+ {
+ psTraceCrypto("Error generating pkcs12 hmac key\n");
+ rc = PS_UNSUPPORTED_FAIL;
+ goto ERR_FBUF;
+ }
+ digestLen = (uint32) (macEnd - macStart);
+ psHmacSha1Init(&hmac, macKey, macKeyLen);
+ psHmacSha1Update(&hmac, macStart, digestLen);
+ psHmacSha1Final(&hmac, mac);
+ psFree(macKey, pool);
+ if (memcmp(digest, mac, SHA1_HASH_SIZE) != 0)
+ {
+ psTraceCrypto("CAUTION: PKCS#12 MAC did not validate\n");
+ }
+ }
+ else
+ {
+ psTraceCrypto("PKCS#12 must use SHA1 HMAC validation\n");
+ rc = PS_UNSUPPORTED_FAIL;
+ goto ERR_FBUF;
+ }
- }
- rc = PS_SUCCESS;
+ }
+ rc = PS_SUCCESS;
ERR_FBUF:
- memset_s(iwidePass, sizeof(iwidePass), 0x0, sizeof(iwidePass));
- memset_s(mwidePass, sizeof(mwidePass), 0x0, sizeof(mwidePass));
- psFree(fileBuf, pool);
- return rc;
+ memset_s(iwidePass, sizeof(iwidePass), 0x0, sizeof(iwidePass));
+ memset_s(mwidePass, sizeof(mwidePass), 0x0, sizeof(mwidePass));
+ psFree(fileBuf, pool);
+ return rc;
}
-#endif /* USE_PKCS12 */
-#endif /* MATRIX_USE_FILE_SYSTEM */
+# endif /* USE_PKCS12 */
+# endif /* MATRIX_USE_FILE_SYSTEM */
-#endif /* USE_PKCS8 */
+# endif /* USE_PKCS8 */
-#ifdef MATRIX_USE_FILE_SYSTEM
+# ifdef MATRIX_USE_FILE_SYSTEM
-#if defined(USE_PKCS5) && defined(USE_PBKDF1)
+# if defined(USE_PKCS5) && defined(USE_PBKDF1)
/******************************************************************************/
/*
- Convert an ASCII hex representation to a binary buffer.
- Decode enough data out of 'hex' buffer to produce 'binlen' bytes in 'bin'
- Two digits of ASCII hex map to the high and low nybbles (in that order),
- so this function assumes that 'hex' points to 2x 'binlen' bytes of data.
- Return the number of bytes processed from hex (2x binlen) or < 0 on error.
-*/
+ Convert an ASCII hex representation to a binary buffer.
+ Decode enough data out of 'hex' buffer to produce 'binlen' bytes in 'bin'
+ Two digits of ASCII hex map to the high and low nybbles (in that order),
+ so this function assumes that 'hex' points to 2x 'binlen' bytes of data.
+ Return the number of bytes processed from hex (2x binlen) or < 0 on error.
+ */
static int32 hexToBinary(unsigned char *hex, unsigned char *bin, int32 binlen)
{
- unsigned char *end, c, highOrder;
+ unsigned char *end, c, highOrder;
- highOrder = 1;
- for (end = hex + binlen * 2; hex < end; hex++) {
- c = *hex;
- if ('0' <= c && c <='9') {
- c -= '0';
- } else if ('a' <= c && c <='f') {
- c -= ('a' - 10);
- } else if ('A' <= c && c <='F') {
- c -= ('A' - 10);
- } else {
- psTraceCrypto("hexToBinary failure\n");
- return PS_FAILURE;
- }
- if (highOrder++ & 0x1) {
- *bin = c << 4;
- } else {
- *bin |= c;
- bin++;
- }
- }
- return binlen * 2;
+ highOrder = 1;
+ for (end = hex + binlen * 2; hex < end; hex++)
+ {
+ c = *hex;
+ if ('0' <= c && c <= '9')
+ {
+ c -= '0';
+ }
+ else if ('a' <= c && c <= 'f')
+ {
+ c -= ('a' - 10);
+ }
+ else if ('A' <= c && c <= 'F')
+ {
+ c -= ('A' - 10);
+ }
+ else
+ {
+ psTraceCrypto("hexToBinary failure\n");
+ return PS_FAILURE;
+ }
+ if (highOrder++ & 0x1)
+ {
+ *bin = c << 4;
+ }
+ else
+ {
+ *bin |= c;
+ bin++;
+ }
+ }
+ return binlen * 2;
}
-#endif /* USE_PKCS5 && USE_PBKDF1 */
+# endif /* USE_PKCS5 && USE_PBKDF1 */
-#ifdef USE_RSA
-int32_t pkcs1ParsePubFile(psPool_t *pool, const char *fileName, psRsaKey_t *key)
+# ifdef USE_RSA
+int32_t psPkcs1ParsePubFile(psPool_t *pool, const char *fileName, psRsaKey_t *key)
{
- unsigned char *DERout;
- unsigned char sha1KeyHash[SHA1_HASH_SIZE];
- const unsigned char *p, *end;
- int32_t rc, oi;
- uint16_t DERlen, seqlen, plen;
-
- /* Had to tweak pkcs1DecodePrivFile to accept PUBLIC KEY headers */
- if ((rc = pkcs1DecodePrivFile(pool, fileName, NULL, &DERout, &DERlen))
- < PS_SUCCESS) {
- return rc;
- }
-
- p = DERout;
- end = p + DERlen;
-
- if (getAsnSequence(&p, (int32)(end - p), &seqlen) < 0) {
- psTraceCrypto("Couldn't parse PKCS#1 RSA public key file\n");
- goto pubKeyFail;
- }
- if (getAsnAlgorithmIdentifier(&p, (int32)(end - p), &oi, &plen) < 0) {
- psTraceCrypto("Couldn't parse PKCS#1 RSA public key file\n");
- goto pubKeyFail;
- }
- if (oi != OID_RSA_KEY_ALG) {
- psTraceCrypto("Couldn't parse PKCS#1 RSA public key file\n");
- goto pubKeyFail;
- }
- if (psRsaParseAsnPubKey(pool, &p,(int32)(end - p), key, sha1KeyHash) < 0) {
- psTraceCrypto("Couldn't parse PKCS#1 RSA public key file\n");
- goto pubKeyFail;
- }
+ unsigned char *DERout;
+ unsigned char sha1KeyHash[SHA1_HASH_SIZE];
+ const unsigned char *p, *end;
+ int32_t rc, oi;
+ psSize_t DERlen, seqlen, plen;
+
+ /* Had to tweak psPkcs1DecodePrivFile to accept PUBLIC KEY headers */
+ if ((rc = psPkcs1DecodePrivFile(pool, fileName, NULL, &DERout, &DERlen))
+ < PS_SUCCESS)
+ {
+ return rc;
+ }
+
+ p = DERout;
+ end = p + DERlen;
+
+ if (getAsnSequence(&p, (int32) (end - p), &seqlen) < 0)
+ {
+ psTraceCrypto("Couldn't parse PKCS#1 RSA public key file\n");
+ goto pubKeyFail;
+ }
+ if (getAsnAlgorithmIdentifier(&p, (int32) (end - p), &oi, &plen) < 0)
+ {
+ psTraceCrypto("Couldn't parse PKCS#1 RSA public key file\n");
+ goto pubKeyFail;
+ }
+ if (oi != OID_RSA_KEY_ALG)
+ {
+ psTraceCrypto("Couldn't parse PKCS#1 RSA public key file\n");
+ goto pubKeyFail;
+ }
+ if (psRsaParseAsnPubKey(pool, &p, (int32) (end - p), key, sha1KeyHash) < 0)
+ {
+ psTraceCrypto("Couldn't parse PKCS#1 RSA public key file\n");
+ goto pubKeyFail;
+ }
+
+ psFree(DERout, pool);
+ return PS_SUCCESS;
- psFree(DERout, pool);
- return PS_SUCCESS;
-
pubKeyFail:
- psFree(DERout, pool);
- return PS_PARSE_FAIL;
+ psFree(DERout, pool);
+ return PS_PARSE_FAIL;
}
/******************************************************************************/
/**
- Parse a PEM format private key file.
+ Parse a PEM format private key file.
- @pre File must be a PEM format RSA keys.
- @return < 0 on error
-*/
-int32_t pkcs1ParsePrivFile(psPool_t *pool, const char *fileName,
- const char *password, psRsaKey_t *key)
+ @pre File must be a PEM format RSA keys.
+ @return < 0 on error
+ */
+int32_t psPkcs1ParsePrivFile(psPool_t *pool, const char *fileName,
+ const char *password, psRsaKey_t *key)
{
- unsigned char *DERout;
- int32_t rc;
- uint16_t DERlen;
-#ifdef USE_PKCS8
- psPubKey_t pubkey;
-#endif
+ unsigned char *DERout;
+ int32_t rc;
+ psSize_t DERlen;
- if ((rc = pkcs1DecodePrivFile(pool, fileName, password, &DERout, &DERlen))
- < PS_SUCCESS) {
- return rc;
- }
+# ifdef USE_PKCS8
+ psPubKey_t pubkey;
+# endif
- if ((rc = psRsaParsePkcs1PrivKey(pool, DERout, DERlen, key)) < 0) {
-#ifdef USE_PKCS8
- /* This logic works for processing PKCS#8 files because the above file
- and bin decodes will always leave the unprocessed buffer intact and
- the password protection is done in the internal ASN.1 encoding */
- if ((rc = pkcs8ParsePrivBin(pool, DERout, DERlen, (char*)password,
- &pubkey)) < 0) {
- psFree(DERout, pool);
- return rc;
- }
- rc = psRsaCopyKey(key, &pubkey.key.rsa);
- psClearPubKey(&pubkey);
-#else
- psFree(DERout, pool);
- return rc;
-#endif
- }
+ if ((rc = psPkcs1DecodePrivFile(pool, fileName, password, &DERout, &DERlen))
+ < PS_SUCCESS)
+ {
+ return rc;
+ }
- psFree(DERout, pool);
- return rc;
+ if ((rc = psRsaParsePkcs1PrivKey(pool, DERout, DERlen, key)) < 0)
+ {
+# ifdef USE_PKCS8
+ /* This logic works for processing PKCS#8 files because the above file
+ and bin decodes will always leave the unprocessed buffer intact and
+ the password protection is done in the internal ASN.1 encoding */
+ if ((rc = psPkcs8ParsePrivBin(pool, DERout, DERlen, (char *) password,
+ &pubkey)) < 0)
+ {
+ psFree(DERout, pool);
+ return rc;
+ }
+ rc = psRsaCopyKey(key, &pubkey.key.rsa);
+ psClearPubKey(&pubkey);
+# else
+ psFree(DERout, pool);
+ return rc;
+# endif
+ }
+
+ psFree(DERout, pool);
+ return rc;
}
-#endif /* USE_RSA */
+# endif /* USE_RSA */
/******************************************************************************/
/**
- Return the DER stream from a private key PEM file.
+ Return the DER stream from a private key PEM file.
- Memory info:
- Caller must call psFree on DERout on function success
-*/
-int32_t pkcs1DecodePrivFile(psPool_t *pool, const char *fileName,
- const char *password, unsigned char **DERout, uint16_t *DERlen)
+ Memory info:
+ Caller must call psFree on DERout on function success
+ */
+int32_t psPkcs1DecodePrivFile(psPool_t *pool, const char *fileName,
+ const char *password, unsigned char **DERout, psSize_t *DERlen)
{
- unsigned char *keyBuf, *dout;
- char *start, *end, *endTmp;
- int32 keyBufLen, rc;
- uint32 PEMlen = 0;
-#if defined(USE_PKCS5) && defined(USE_PBKDF1)
- psDes3_t dctx;
- psAesCbc_t actx;
- unsigned char passKey[32]; /* AES-256 max */
- unsigned char cipherIV[16]; /* AES-256 max */
- int32 tmp, encrypted = 0;
+ unsigned char *keyBuf, *dout;
+ char *start, *end, *endTmp;
+ int32 keyBufLen, rc;
+ uint32 PEMlen = 0;
- static const char des3encryptHeader[] = "DEK-Info: DES-EDE3-CBC,";
- static const char aes128encryptHeader[] = "DEK-Info: AES-128-CBC,";
-#endif /* USE_PKCS5 && USE_PBKDF1 */
+# if defined(USE_PKCS5) && defined(USE_PBKDF1)
+ psDes3_t dctx;
+ psAesCbc_t actx;
+ unsigned char passKey[32]; /* AES-256 max */
+ unsigned char cipherIV[16]; /* AES-256 max */
+ int32 tmp, encrypted = 0;
- if (fileName == NULL) {
- psTraceCrypto("No fileName passed to pkcs1DecodePrivFile\n");
- return PS_ARG_FAIL;
- }
- if ((rc = psGetFileBuf(pool, fileName, &keyBuf, &keyBufLen)) < PS_SUCCESS) {
- return rc;
- }
- start = end = NULL;
+ static const char des3encryptHeader[] = "DEK-Info: DES-EDE3-CBC,";
+ static const char aes128encryptHeader[] = "DEK-Info: AES-128-CBC,";
+# endif /* USE_PKCS5 && USE_PBKDF1 */
- /* Check header and encryption parameters. */
- if (((start = strstr((char*)keyBuf, "-----BEGIN")) != NULL) &&
- ((start = strstr((char*)keyBuf, "PRIVATE KEY-----")) != NULL) &&
- ((end = strstr(start, "-----END")) != NULL) &&
- ((endTmp = strstr(end, "PRIVATE KEY-----")) != NULL)) {
- start += strlen("PRIVATE KEY-----");
- while (*start == '\x0d' || *start == '\x0a') {
- start++;
- }
- PEMlen = (uint32)(end - start);
- } else if (((start = strstr((char*)keyBuf, "-----BEGIN")) != NULL) &&
- ((start = strstr((char*)keyBuf, "PUBLIC KEY-----")) != NULL) &&
- ((end = strstr(start, "-----END")) != NULL) &&
- ((endTmp = strstr(end, "PUBLIC KEY-----")) != NULL)) {
- start += strlen("PUBLIC KEY-----");
- while (*start == '\x0d' || *start == '\x0a') {
- start++;
- }
- PEMlen = (uint32)(end - start);
- } else {
- psTraceCrypto("File buffer does not look to be in PKCS#1 PEM format\n");
- psFree(keyBuf, pool);
- return PS_PARSE_FAIL;
- }
+ if (fileName == NULL)
+ {
+ psTraceCrypto("No fileName passed to psPkcs1DecodePrivFile\n");
+ return PS_ARG_FAIL;
+ }
+ if ((rc = psGetFileBuf(pool, fileName, &keyBuf, &keyBufLen)) < PS_SUCCESS)
+ {
+ return rc;
+ }
+ start = end = NULL;
- if (strstr((char*)keyBuf, "Proc-Type:") &&
- strstr((char*)keyBuf, "4,ENCRYPTED")) {
-#if defined(USE_PKCS5) && defined(USE_PBKDF1)
- if (password == NULL) {
- psTraceCrypto("No password given for encrypted private key file\n");
- psFree(keyBuf, pool);
- return PS_ARG_FAIL;
- }
- if ((start = strstr((char*)keyBuf, des3encryptHeader)) != NULL) {
- start += strlen(des3encryptHeader);
- encrypted = 1;
- /* we assume here that header points to at least 16 bytes of data */
- tmp = hexToBinary((unsigned char*)start, cipherIV, DES3_IVLEN);
- } else if ((start = strstr((char*)keyBuf, aes128encryptHeader))
- != NULL) {
- start += strlen(aes128encryptHeader);
- encrypted = 2;
- /* we assume here that header points to at least 32 bytes of data */
- tmp = hexToBinary((unsigned char*)start, cipherIV, 16);
- } else {
- psTraceCrypto("Unrecognized private key file encoding\n");
- psFree(keyBuf, pool);
- return PS_PARSE_FAIL;
- }
+ /* Check header and encryption parameters. */
+ if (((start = strstr((char *) keyBuf, "-----BEGIN")) != NULL) &&
+ ((start = strstr((char *) keyBuf, "PRIVATE KEY-----")) != NULL) &&
+ ((end = strstr(start, "-----END")) != NULL) &&
+ ((endTmp = strstr(end, "PRIVATE KEY-----")) != NULL))
+ {
+ start += strlen("PRIVATE KEY-----");
+ while (*start == '\x0d' || *start == '\x0a')
+ {
+ start++;
+ }
+ PEMlen = (uint32) (end - start);
+ }
+ else if (((start = strstr((char *) keyBuf, "-----BEGIN")) != NULL) &&
+ ((start = strstr((char *) keyBuf, "PUBLIC KEY-----")) != NULL) &&
+ ((end = strstr(start, "-----END")) != NULL) &&
+ ((endTmp = strstr(end, "PUBLIC KEY-----")) != NULL))
+ {
+ start += strlen("PUBLIC KEY-----");
+ while (*start == '\x0d' || *start == '\x0a')
+ {
+ start++;
+ }
+ PEMlen = (uint32) (end - start);
+ }
+ else
+ {
+ psTraceCrypto("File buffer does not look to be in PKCS#1 PEM format\n");
+ psFree(keyBuf, pool);
+ return PS_PARSE_FAIL;
+ }
- if (tmp < 0) {
- psTraceCrypto("Invalid private key file salt\n");
- psFree(keyBuf, pool);
- return PS_FAILURE;
- }
- start += tmp;
- if (pkcs5pbkdf1((unsigned char*)password, strlen(password),
- cipherIV, 1, (unsigned char*)passKey) < 0) {
- psTraceCrypto("pkcs5pbkdf1 failed\n");
- psFree(keyBuf, pool);
- return PS_FAILURE;
- }
- PEMlen = (int32)(end - start);
-#else /* !USE_PKCS5 || !USE_PBKDF1 */
- /* The private key is encrypted, but PKCS5 support has been turned off */
-#ifndef USE_PKCS5
- psTraceCrypto("USE_PKCS5 must be enabled for key file password\n");
-#endif /* USE_PKCS5 */
-#ifndef USE_PBKDF1
- psTraceCrypto("USE_PBKDF1 must be enabled for key file password\n");
-#endif /* USE_PBKDF1 */
- psFree(keyBuf, pool);
- return PS_UNSUPPORTED_FAIL;
-#endif /* USE_PKCS5 && USE_PBKDF1 */
- }
+ if (strstr((char *) keyBuf, "Proc-Type:") &&
+ strstr((char *) keyBuf, "4,ENCRYPTED"))
+ {
+# if defined(USE_PKCS5) && defined(USE_PBKDF1)
+ if (password == NULL)
+ {
+ psTraceCrypto("No password given for encrypted private key file\n");
+ psFree(keyBuf, pool);
+ return PS_ARG_FAIL;
+ }
+ if ((start = strstr((char *) keyBuf, des3encryptHeader)) != NULL)
+ {
+ start += strlen(des3encryptHeader);
+ encrypted = 1;
+ /* we assume here that header points to at least 16 bytes of data */
+ tmp = hexToBinary((unsigned char *) start, cipherIV, DES3_IVLEN);
+ }
+ else if ((start = strstr((char *) keyBuf, aes128encryptHeader))
+ != NULL)
+ {
+ start += strlen(aes128encryptHeader);
+ encrypted = 2;
+ /* we assume here that header points to at least 32 bytes of data */
+ tmp = hexToBinary((unsigned char *) start, cipherIV, 16);
+ }
+ else
+ {
+ psTraceCrypto("Unrecognized private key file encoding\n");
+ psFree(keyBuf, pool);
+ return PS_PARSE_FAIL;
+ }
- /* Take the raw input and do a base64 decode */
- dout = psMalloc(pool, PEMlen);
- if (dout == NULL) {
- psFree(keyBuf, pool);
- psError("Memory allocation error in pkcs1DecodePrivFile\n");
- return PS_MEM_FAIL;
- }
- *DERlen = PEMlen;
- if ((rc = psBase64decode((unsigned char*)start, PEMlen, dout,
- DERlen)) < 0) {
- psTraceCrypto("Error base64 decode of private key\n");
- if (password) {
- psTraceCrypto("Is it possible the password is incorrect?\n");
- }
- psFree(dout, pool);
- psFree(keyBuf, pool);
- return rc;
- }
- psFree(keyBuf, pool);
+ if (tmp < 0)
+ {
+ psTraceCrypto("Invalid private key file salt\n");
+ psFree(keyBuf, pool);
+ return PS_FAILURE;
+ }
+ start += tmp;
+ if (psPkcs5Pbkdf1((unsigned char *) password, strlen(password),
+ cipherIV, 1, (unsigned char *) passKey) < 0)
+ {
+ psTraceCrypto("psPkcs5Pbkdf1 failed\n");
+ psFree(keyBuf, pool);
+ return PS_FAILURE;
+ }
+ PEMlen = (int32) (end - start);
+# else /* !USE_PKCS5 || !USE_PBKDF1 */
+ /* The private key is encrypted, but PKCS5 support has been turned off */
+# ifndef USE_PKCS5
+ psTraceCrypto("USE_PKCS5 must be enabled for key file password\n");
+# endif /* USE_PKCS5 */
+# ifndef USE_PBKDF1
+ psTraceCrypto("USE_PBKDF1 must be enabled for key file password\n");
+# endif /* USE_PBKDF1 */
+ psFree(keyBuf, pool);
+ return PS_UNSUPPORTED_FAIL;
+# endif /* USE_PKCS5 && USE_PBKDF1 */
+ }
-#if defined(USE_PKCS5) && defined(USE_PBKDF1)
- if (encrypted == 1 && password) {
- psDes3Init(&dctx, cipherIV, passKey);
- psDes3Decrypt(&dctx, dout, dout, *DERlen);
- memset_s(&dctx, sizeof(psDes3_t), 0x0, sizeof(psDes3_t));
- }
- if (encrypted == 2 && password) {
- /* AES 128 */
- psAesInitCBC(&actx, cipherIV, passKey, 16, PS_AES_DECRYPT);
- psAesDecryptCBC(&actx, dout, dout, *DERlen);
- memset_s(&actx, sizeof(psAesCbc_t), 0x0, sizeof(psAesCbc_t));
- }
- /* SECURITY - zero out keys when finished */
- memset_s(passKey, sizeof(passKey), 0x0, sizeof(passKey));
-#endif /* USE_PKCS5 && USE_PBKDF1 */
- *DERout = dout;
+ /* Take the raw input and do a base64 decode */
+ dout = psMalloc(pool, PEMlen);
+ if (dout == NULL)
+ {
+ psFree(keyBuf, pool);
+ psError("Memory allocation error in psPkcs1DecodePrivFile\n");
+ return PS_MEM_FAIL;
+ }
+ *DERlen = PEMlen;
+ if ((rc = psBase64decode((unsigned char *) start, PEMlen, dout,
+ DERlen)) < 0)
+ {
+ psTraceCrypto("Error base64 decode of private key\n");
+ if (password)
+ {
+ psTraceCrypto("Is it possible the password is incorrect?\n");
+ }
+ psFree(dout, pool);
+ psFree(keyBuf, pool);
+ return rc;
+ }
+ psFree(keyBuf, pool);
- return PS_SUCCESS;
+# if defined(USE_PKCS5) && defined(USE_PBKDF1)
+ if (encrypted == 1 && password)
+ {
+ psDes3Init(&dctx, cipherIV, passKey);
+ psDes3Decrypt(&dctx, dout, dout, *DERlen);
+ memset_s(&dctx, sizeof(psDes3_t), 0x0, sizeof(psDes3_t));
+ }
+ if (encrypted == 2 && password)
+ {
+ /* AES 128 */
+ psAesInitCBC(&actx, cipherIV, passKey, 16, PS_AES_DECRYPT);
+ psAesDecryptCBC(&actx, dout, dout, *DERlen);
+ memset_s(&actx, sizeof(psAesCbc_t), 0x0, sizeof(psAesCbc_t));
+ }
+ /* SECURITY - zero out keys when finished */
+ memset_s(passKey, sizeof(passKey), 0x0, sizeof(passKey));
+# endif /* USE_PKCS5 && USE_PBKDF1 */
+ *DERout = dout;
+
+ return PS_SUCCESS;
}
-#endif /* MATRIX_USE_FILE_SYSTEM */
-#endif /* USE_PRIVATE_KEY_PARSING */
+# endif /* MATRIX_USE_FILE_SYSTEM */
+#endif /* USE_PRIVATE_KEY_PARSING */
/******************************************************************************/
/******************************************************************************/
#ifdef USE_PKCS5
-#ifdef USE_PBKDF1
+# ifdef USE_PBKDF1
/******************************************************************************/
/*
- Generate a key given a password and salt value.
- PKCS#5 2.0 PBKDF1 key derivation format with MD5 and count == 1 per:
- http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html
+ Generate a key given a password and salt value.
+ PKCS#5 2.0 PBKDF1 key derivation format with MD5 and count == 1 per:
+ http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html
- This key is compatible with the algorithm used by OpenSSL to encrypt keys
- generated with 'openssl genrsa'. If other encryption formats are used
- (for example PBKDF2), or an iteration count != 1 is used, they are not
- compatible with this simple implementation. OpenSSL provides many options
- for converting key formats to the one used here.
+ This key is compatible with the algorithm used by OpenSSL to encrypt keys
+ generated with 'openssl genrsa'. If other encryption formats are used
+ (for example PBKDF2), or an iteration count != 1 is used, they are not
+ compatible with this simple implementation. OpenSSL provides many options
+ for converting key formats to the one used here.
- A 3DES key is 24 bytes long, to generate it with this algorithm,
- we md5 hash the password and salt for the first 16 bytes. We then
- hash these first 16 bytes with the password and salt again, generating
- another 16 bytes. We take the first 16 bytes and 8 of the second 16 to
- form the 24 byte key.
+ A 3DES key is 24 bytes long, to generate it with this algorithm,
+ we md5 hash the password and salt for the first 16 bytes. We then
+ hash these first 16 bytes with the password and salt again, generating
+ another 16 bytes. We take the first 16 bytes and 8 of the second 16 to
+ form the 24 byte key.
- salt is assumed to point to 8 bytes of data
- key is assumed to point to 24 bytes of data
+ salt is assumed to point to 8 bytes of data
+ key is assumed to point to 24 bytes of data
*/
-int32_t pkcs5pbkdf1(unsigned char *pass, uint32 passlen, unsigned char *salt,
- int32 iter, unsigned char *key)
+int32_t psPkcs5Pbkdf1(unsigned char *pass, uint32 passlen, unsigned char *salt,
+ int32 iter, unsigned char *key)
{
- int32_t rc;
- psDigestContext_t md;
- unsigned char md5[MD5_HASH_SIZE];
- psAssert(iter == 1);
+ int32_t rc;
+ psDigestContext_t md;
+ unsigned char md5[MD5_HASH_SIZE];
- rc = psMd5Init(&md.md5);
- if (rc != PS_SUCCESS) {
- psTraceCrypto("psMd5Init failed. Please ensure non-FIPS mode.\n");
- return rc;
- }
- psMd5Update(&md.md5, pass, passlen);
- psMd5Update(&md.md5, salt, 8);
- psMd5Final(&md.md5, md5);
- memcpy(key, md5, MD5_HASH_SIZE);
+ psAssert(iter == 1);
- rc = psMd5Init(&md.md5);
- if (rc != PS_SUCCESS) {
- psTraceCrypto("psMd5Init failed. Please ensure non-FIPS mode.\n");
- return rc;
- }
+ rc = psMd5Init(&md.md5);
+ if (rc != PS_SUCCESS)
+ {
+ psTraceCrypto("psMd5Init failed. Please ensure non-FIPS mode.\n");
+ return rc;
+ }
+ psMd5Update(&md.md5, pass, passlen);
+ psMd5Update(&md.md5, salt, 8);
+ psMd5Final(&md.md5, md5);
+ memcpy(key, md5, MD5_HASH_SIZE);
- psMd5Update(&md.md5, md5, MD5_HASH_SIZE);
- psMd5Update(&md.md5, pass, passlen);
- psMd5Update(&md.md5, salt, 8);
- psMd5Final(&md.md5, md5);
- memcpy(key + MD5_HASH_SIZE, md5, 24 - MD5_HASH_SIZE);
+ rc = psMd5Init(&md.md5);
+ if (rc != PS_SUCCESS)
+ {
+ psTraceCrypto("psMd5Init failed. Please ensure non-FIPS mode.\n");
+ return rc;
+ }
- memset_s(md5, MD5_HASH_SIZE, 0x0, MD5_HASH_SIZE);
- memset_s(&md, sizeof(psDigestContext_t), 0x0, sizeof(psDigestContext_t));
- return PS_SUCCESS;
+ psMd5Update(&md.md5, md5, MD5_HASH_SIZE);
+ psMd5Update(&md.md5, pass, passlen);
+ psMd5Update(&md.md5, salt, 8);
+ psMd5Final(&md.md5, md5);
+ memcpy(key + MD5_HASH_SIZE, md5, 24 - MD5_HASH_SIZE);
+
+ memset_s(md5, MD5_HASH_SIZE, 0x0, MD5_HASH_SIZE);
+ memset_s(&md, sizeof(psDigestContext_t), 0x0, sizeof(psDigestContext_t));
+ return PS_SUCCESS;
}
-#endif /* USE_PBKDF1 */
+# endif /* USE_PBKDF1 */
-#if defined(USE_HMAC_SHA1)
+# if defined(USE_HMAC_SHA1)
/******************************************************************************/
/*
- Generate a key given a password, salt and iteration value.
- PKCS#5 2.0 PBKDF2 key derivation format with HMAC-SHA per:
- http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html
+ Generate a key given a password, salt and iteration value.
+ PKCS#5 2.0 PBKDF2 key derivation format with HMAC-SHA per:
+ http://www.rsasecurity.com/rsalabs/pkcs/pkcs-5/index.html
- Given a password, a salt, and an iteration count (rounds), generate a
- key suitable for encrypting data with 3DES, AES, etc.
- key should point to storage as large as kLen
-*/
-void pkcs5pbkdf2(unsigned char *password, uint32 pLen,
- unsigned char *salt, uint32 sLen, int32 rounds,
- unsigned char *key, uint32 kLen)
+ Given a password, a salt, and an iteration count (rounds), generate a
+ key suitable for encrypting data with 3DES, AES, etc.
+ key should point to storage as large as kLen
+ */
+void psPkcs5Pbkdf2(unsigned char *password, uint32 pLen,
+ unsigned char *salt, uint32 sLen, int32 rounds,
+ unsigned char *key, uint32 kLen)
{
- int32 itts;
- uint32 blkno;
- unsigned long stored, left, i;
- unsigned char buf[2][SHA1_HASH_SIZE];
- psHmacSha1_t hmac;
+ int32 itts;
+ uint32 blkno;
+ unsigned long stored, left, i;
+ unsigned char buf[2][SHA1_HASH_SIZE];
+ psHmacSha1_t hmac;
- psAssert(password && salt && key && kLen);
+ psAssert(password && salt && key && kLen);
- left = kLen;
- blkno = 1;
- stored = 0;
- while (left != 0) {
- /* process block number blkno */
- memset(buf[0], 0x0, SHA1_HASH_SIZE * 2);
+ left = kLen;
+ blkno = 1;
+ stored = 0;
+ while (left != 0)
+ {
+ /* process block number blkno */
+ memset(buf[0], 0x0, SHA1_HASH_SIZE * 2);
- /* store current block number and increment for next pass */
- STORE32H(blkno, buf[1]);
- ++blkno;
+ /* store current block number and increment for next pass */
+ STORE32H(blkno, buf[1]);
+ ++blkno;
- /* get PRF(P, S||int(blkno)) */
- psHmacSha1Init(&hmac, password, pLen);
- psHmacSha1Update(&hmac, salt, sLen);
- psHmacSha1Update(&hmac, buf[1], 4);
- psHmacSha1Final(&hmac, buf[0]);
+ /* get PRF(P, S||int(blkno)) */
+ psHmacSha1Init(&hmac, password, pLen);
+ psHmacSha1Update(&hmac, salt, sLen);
+ psHmacSha1Update(&hmac, buf[1], 4);
+ psHmacSha1Final(&hmac, buf[0]);
- /* now compute repeated and XOR it in buf[1] */
- memcpy(buf[1], buf[0], SHA1_HASH_SIZE);
- for (itts = 1; itts < rounds; ++itts) {
- psHmacSha1Init(&hmac, password, pLen);
- psHmacSha1Update(&hmac, buf[0], SHA1_HASH_SIZE);
- psHmacSha1Final(&hmac, buf[0]);
- for (i = 0; i < SHA1_HASH_SIZE; i++) {
- buf[1][i] ^= buf[0][i];
- }
- }
- /* now emit upto x bytes of buf[1] to output */
- for (i = 0; i < SHA1_HASH_SIZE && left != 0; ++i) {
- key[stored++] = buf[1][i];
- --left;
- }
- }
+ /* now compute repeated and XOR it in buf[1] */
+ memcpy(buf[1], buf[0], SHA1_HASH_SIZE);
+ for (itts = 1; itts < rounds; ++itts)
+ {
+ psHmacSha1Init(&hmac, password, pLen);
+ psHmacSha1Update(&hmac, buf[0], SHA1_HASH_SIZE);
+ psHmacSha1Final(&hmac, buf[0]);
+ for (i = 0; i < SHA1_HASH_SIZE; i++)
+ {
+ buf[1][i] ^= buf[0][i];
+ }
+ }
+ /* now emit upto x bytes of buf[1] to output */
+ for (i = 0; i < SHA1_HASH_SIZE && left != 0; ++i)
+ {
+ key[stored++] = buf[1][i];
+ --left;
+ }
+ }
- memset_s(buf, SHA1_HASH_SIZE * 2, 0x0, SHA1_HASH_SIZE * 2);
- memset_s(&hmac, sizeof(psHmacSha1_t), 0x0, sizeof(psHmacSha1_t));
+ memset_s(buf, SHA1_HASH_SIZE * 2, 0x0, SHA1_HASH_SIZE * 2);
+ memset_s(&hmac, sizeof(psHmacSha1_t), 0x0, sizeof(psHmacSha1_t));
}
-#endif /* USE_HMAC && USE_SHA1 */
-#endif /* USE_PKCS5 */
+# endif /* USE_HMAC && USE_SHA1 */
+#endif /* USE_PKCS5 */
#if defined(USE_DH) && defined(MATRIX_USE_FILE_SYSTEM)
/******************************************************************************/
/**
- Extract Diffie-Hellman parameters from a PEM encoded file.
- This API decodes the PEM format and passes the ASN.1 encoded parameters
- to pkcs3ParseDhParamBin() to parse the ASN.1.
+ Extract Diffie-Hellman parameters from a PEM encoded file.
+ This API decodes the PEM format and passes the ASN.1 encoded parameters
+ to psPkcs3ParseDhParamBin() to parse the ASN.1.
- @param pool Memory pool
- @param[in] fileName File name of PEM encoded ASN.1 to load.
- @param[in,out] params Allocated parameter structure to receive parsed
- params.
- @return < on error.
-*/
-int32_t pkcs3ParseDhParamFile(psPool_t *pool, const char *fileName, psDhParams_t *params)
+ @param pool Memory pool
+ @param[in] fileName File name of PEM encoded ASN.1 to load.
+ @param[in,out] params Allocated parameter structure to receive parsed
+ params.
+ @return < on error.
+ */
+int32_t psPkcs3ParseDhParamFile(psPool_t *pool, const char *fileName, psDhParams_t *params)
{
- unsigned char *pemOut, *p;
- char *dhFileBuf, *start, *end;
- int32_t rc;
- uint16_t baseLen, pemOutLen;
- int32_t dhFileLen;
+ unsigned char *pemOut, *p;
+ char *dhFileBuf, *start, *end;
+ int32_t rc;
+ psSize_t baseLen, pemOutLen;
+ int32_t dhFileLen;
- if (!params || !fileName) {
- return PS_ARG_FAIL;
- }
- /* This is part of key assignment at startup. Base pool is fine here */
- if ((rc = psGetFileBuf(pool, fileName,
- (unsigned char **)&dhFileBuf, &dhFileLen)) < 0) {
- return rc;
- }
- /* Set end to end of file buffer */
- end = dhFileBuf + dhFileLen;
- /* Set start to start of token */
- if ((start = strstr(dhFileBuf, "-----BEGIN DH PARAMETERS-----")) == NULL) {
- psTraceStrCrypto("Error parsing dh file buffer header: %s\n", fileName);
- psFree(dhFileBuf, pool);
- return PS_PARSE_FAIL;
- }
- /* Move start to start of PEM data, skipping CR/LF */
- start += 29; /* strlen("-----BEGIN DH PARAMETERS-----"); */
- while (start < end && (*start == '\x0d' || *start == '\x0a')) {
- start++;
- }
- /* Set end to end token */
- if ((end = strstr(start, "-----END DH PARAMETERS-----")) == NULL) {
- psTraceStrCrypto("Error parsing dh file buffer footer: %s\n", fileName);
- psFree(dhFileBuf, pool);
- return PS_PARSE_FAIL;
- }
- baseLen = (uint16_t)(end - start);
+ if (!params || !fileName)
+ {
+ return PS_ARG_FAIL;
+ }
+ /* This is part of key assignment at startup. Base pool is fine here */
+ if ((rc = psGetFileBuf(pool, fileName,
+ (unsigned char **) &dhFileBuf, &dhFileLen)) < 0)
+ {
+ return rc;
+ }
+ /* Set end to end of file buffer */
+ end = dhFileBuf + dhFileLen;
+ /* Set start to start of token */
+ if ((start = strstr(dhFileBuf, "-----BEGIN DH PARAMETERS-----")) == NULL)
+ {
+ psTraceStrCrypto("Error parsing dh file buffer header: %s\n", fileName);
+ psFree(dhFileBuf, pool);
+ return PS_PARSE_FAIL;
+ }
+ /* Move start to start of PEM data, skipping CR/LF */
+ start += 29; /* strlen("-----BEGIN DH PARAMETERS-----"); */
+ while (start < end && (*start == '\x0d' || *start == '\x0a'))
+ {
+ start++;
+ }
+ /* Set end to end token */
+ if ((end = strstr(start, "-----END DH PARAMETERS-----")) == NULL)
+ {
+ psTraceStrCrypto("Error parsing dh file buffer footer: %s\n", fileName);
+ psFree(dhFileBuf, pool);
+ return PS_PARSE_FAIL;
+ }
+ baseLen = (uint16_t) (end - start);
- p = NULL;
- p = pemOut = psMalloc(pool, baseLen);
- if (p == NULL) {
- psError("Memory allocation error in pkcs3ParseDhParamFile\n");
- psFree(dhFileBuf, pool);
- return PS_MEM_FAIL;
- }
+ p = NULL;
+ p = pemOut = psMalloc(pool, baseLen);
+ if (p == NULL)
+ {
+ psError("Memory allocation error in psPkcs3ParseDhParamFile\n");
+ psFree(dhFileBuf, pool);
+ return PS_MEM_FAIL;
+ }
- pemOutLen = baseLen;
- if (psBase64decode((unsigned char *)start, baseLen, p, &pemOutLen) != 0) {
- psFree(dhFileBuf, pool);
- psFree(pemOut, pool);
- return PS_PARSE_FAIL;
- }
- psFree(dhFileBuf, pool);
+ pemOutLen = baseLen;
+ if (psBase64decode((unsigned char *) start, baseLen, p, &pemOutLen) != 0)
+ {
+ psFree(dhFileBuf, pool);
+ psFree(pemOut, pool);
+ return PS_PARSE_FAIL;
+ }
+ psFree(dhFileBuf, pool);
- if ((rc = pkcs3ParseDhParamBin(pool, p, pemOutLen, params)) < 0) {
- psFree(pemOut, pool);
- return rc;
- }
- psFree(pemOut, pool);
- return 0;
+ if ((rc = psPkcs3ParseDhParamBin(pool, p, pemOutLen, params)) < 0)
+ {
+ psFree(pemOut, pool);
+ return rc;
+ }
+ psFree(pemOut, pool);
+ return 0;
}
#endif /* USE_DH && MATRIX_USE_FILE_SYSTEM */
@@ -1818,119 +2081,143 @@ int32_t pkcs3ParseDhParamFile(psPool_t *pool, const char *fileName, psDhParams_t
/******************************************************************************/
#if defined(USE_PKCS1_OAEP) || defined(USE_PKCS1_PSS)
/*
- The reason we weren't able to create a callback structure for the hash
- routines was because of the Mac relocation build errors related to
- the register usage when assembly code is used in pstm
-*/
+ The reason we weren't able to create a callback structure for the hash
+ routines was because of the Mac relocation build errors related to
+ the register usage when assembly code is used in pstm
+ */
/******************************************************************************/
/*
- Perform PKCS #1 Mask Generation Function (internal)
- pool Memory pool
- seed The seed for MGF1
- seedlen The length of the seed
- hash_idx The index of the hash desired
- mask [out] The destination
- masklen The length of the mask desired
- return 0 if successful
-*/
+ Perform PKCS #1 Mask Generation Function (internal)
+ pool Memory pool
+ seed The seed for MGF1
+ seedlen The length of the seed
+ hash_idx The index of the hash desired
+ mask [out] The destination
+ masklen The length of the mask desired
+ return 0 if successful
+ */
static int32 pkcs_1_mgf1(psPool_t *pool, const unsigned char *seed,
- unsigned long seedlen, int32 hash_idx, unsigned char *mask,
- unsigned long masklen)
+ unsigned long seedlen, int32 hash_idx, unsigned char *mask,
+ unsigned long masklen)
{
- unsigned long hLen, x;
- uint32 counter;
- psDigestContext_t md;
- unsigned char *buf;
+ unsigned long hLen, x;
+ uint32 counter;
+ psDigestContext_t md;
+ unsigned char *buf;
- if ((seed == NULL) || (mask == NULL)) {
- return -1;
- }
- hLen = 0;
+ if ((seed == NULL) || (mask == NULL))
+ {
+ return -1;
+ }
+ hLen = 0;
/*
- Get hash output size. Index has already been verified by caller so
- don't need 'else' error cases
-*/
- if (hash_idx == PKCS1_SHA1_ID) {
- hLen = SHA1_HASH_SIZE;
- } else if (hash_idx == PKCS1_MD5_ID) {
- hLen = MD5_HASH_SIZE;
-#ifdef USE_SHA256
- } else if (hash_idx == PKCS1_SHA256_ID) {
- hLen = SHA256_HASH_SIZE;
-#endif
-#ifdef USE_SHA384
- } else if (hash_idx == PKCS1_SHA384_ID) {
- hLen = SHA384_HASH_SIZE;
-#endif
-#ifdef USE_SHA512
- } else if (hash_idx == PKCS1_SHA512_ID) {
- hLen = SHA512_HASH_SIZE;
-#endif
- } else {
- return PS_UNSUPPORTED_FAIL;
- }
+ Get hash output size. Index has already been verified by caller so
+ don't need 'else' error cases
+ */
+ if (hash_idx == PKCS1_SHA1_ID)
+ {
+ hLen = SHA1_HASH_SIZE;
+ }
+ else if (hash_idx == PKCS1_MD5_ID)
+ {
+ hLen = MD5_HASH_SIZE;
+# ifdef USE_SHA256
+ }
+ else if (hash_idx == PKCS1_SHA256_ID)
+ {
+ hLen = SHA256_HASH_SIZE;
+# endif
+# ifdef USE_SHA384
+ }
+ else if (hash_idx == PKCS1_SHA384_ID)
+ {
+ hLen = SHA384_HASH_SIZE;
+# endif
+# ifdef USE_SHA512
+ }
+ else if (hash_idx == PKCS1_SHA512_ID)
+ {
+ hLen = SHA512_HASH_SIZE;
+# endif
+ }
+ else
+ {
+ return PS_UNSUPPORTED_FAIL;
+ }
- buf = psMalloc(pool, hLen);
- if (buf == NULL) {
- psTraceCrypto("Memory allocation error in MGF\n");
- return -1;
- }
+ buf = psMalloc(pool, hLen);
+ if (buf == NULL)
+ {
+ psTraceCrypto("Memory allocation error in MGF\n");
+ return -1;
+ }
/*
- Start counter
-*/
- counter = 0;
+ Start counter
+ */
+ counter = 0;
- while (masklen > 0) {
- /* handle counter */
- STORE32H(counter, buf);
- ++counter;
+ while (masklen > 0)
+ {
+ /* handle counter */
+ STORE32H(counter, buf);
+ ++counter;
/*
- Get hash of seed || counter
-*/
- if (hash_idx == PKCS1_SHA1_ID) {
- psSha1Init(&md.sha1);
- psSha1Update(&md.sha1, seed, seedlen);
- psSha1Update(&md.sha1, buf, 4);
- psSha1Final(&md.sha1, buf);
-#ifdef USE_MD5
- } else if (hash_idx == PKCS1_MD5_ID) {
- psMd5Init(&md.md5);
- psMd5Update(&md.md5, seed, seedlen);
- psMd5Update(&md.md5, buf, 4);
- psMd5Final(&md.md5, buf);
-#endif /* USE_MD5 */
-#ifdef USE_SHA256
- } else if (hash_idx == PKCS1_SHA256_ID) {
- psSha256Init(&md.sha256);
- psSha256Update(&md.sha256, seed, seedlen);
- psSha256Update(&md.sha256, buf, 4);
- psSha256Final(&md.sha256, buf);
-#endif
-#ifdef USE_SHA384
- } else if (hash_idx == PKCS1_SHA384_ID) {
- psSha384Init(&md.sha384);
- psSha384Update(&md.sha384, seed, seedlen);
- psSha384Update(&md.sha384, buf, 4);
- psSha384Final(&md.sha384, buf);
-#endif
-#ifdef USE_SHA512
- } else if (hash_idx == PKCS1_SHA512_ID) {
- psSha512Init(&md.sha512);
- psSha512Update(&md.sha512, seed, seedlen);
- psSha512Update(&md.sha512, buf, 4);
- psSha512Final(&md.sha512, buf);
-#endif
- }
+ Get hash of seed || counter
+ */
+ if (hash_idx == PKCS1_SHA1_ID)
+ {
+ psSha1Init(&md.sha1);
+ psSha1Update(&md.sha1, seed, seedlen);
+ psSha1Update(&md.sha1, buf, 4);
+ psSha1Final(&md.sha1, buf);
+# ifdef USE_MD5
+ }
+ else if (hash_idx == PKCS1_MD5_ID)
+ {
+ psMd5Init(&md.md5);
+ psMd5Update(&md.md5, seed, seedlen);
+ psMd5Update(&md.md5, buf, 4);
+ psMd5Final(&md.md5, buf);
+# endif /* USE_MD5 */
+# ifdef USE_SHA256
+ }
+ else if (hash_idx == PKCS1_SHA256_ID)
+ {
+ psSha256Init(&md.sha256);
+ psSha256Update(&md.sha256, seed, seedlen);
+ psSha256Update(&md.sha256, buf, 4);
+ psSha256Final(&md.sha256, buf);
+# endif
+# ifdef USE_SHA384
+ }
+ else if (hash_idx == PKCS1_SHA384_ID)
+ {
+ psSha384Init(&md.sha384);
+ psSha384Update(&md.sha384, seed, seedlen);
+ psSha384Update(&md.sha384, buf, 4);
+ psSha384Final(&md.sha384, buf);
+# endif
+# ifdef USE_SHA512
+ }
+ else if (hash_idx == PKCS1_SHA512_ID)
+ {
+ psSha512Init(&md.sha512);
+ psSha512Update(&md.sha512, seed, seedlen);
+ psSha512Update(&md.sha512, buf, 4);
+ psSha512Final(&md.sha512, buf);
+# endif
+ }
- /* store it */
- for (x = 0; x < hLen && masklen > 0; x++, masklen--) {
- *mask++ = buf[x];
- }
- }
+ /* store it */
+ for (x = 0; x < hLen && masklen > 0; x++, masklen--)
+ {
+ *mask++ = buf[x];
+ }
+ }
- psFree(buf, pool);
- return PS_SUCCESS;
+ psFree(buf, pool);
+ return PS_SUCCESS;
}
#endif /* defined(USE_PKCS1_OAEP) || defined(USE_PKCS1_PSS) */
@@ -1938,443 +2225,499 @@ static int32 pkcs_1_mgf1(psPool_t *pool, const unsigned char *seed,
#ifdef USE_PKCS1_OAEP
/******************************************************************************/
/*
- PKCS #1 v2.00 OAEP encode
- pool Memory pool
- msg The data to encode
- msglen The length of the data to encode (octets)
- lparam A session or system parameter (can be NULL)
- lparamlen The length of the lparam data
- seed Reserved for vector testing. Should be NULL
- seedLen Reserved for vector testing. Should be 0
- modulus_bitlen The bit length of the RSA modulus
- hash_idx The index of the hash desired (see psHashList table above)
- out [out] The destination for the encoded data
- outlen [in/out] The max size and resulting size of the encoded data
+ PKCS #1 v2.00 OAEP encode
+ pool Memory pool
+ msg The data to encode
+ msglen The length of the data to encode (octets)
+ lparam A session or system parameter (can be NULL)
+ lparamlen The length of the lparam data
+ seed Reserved for vector testing. Should be NULL
+ seedLen Reserved for vector testing. Should be 0
+ modulus_bitlen The bit length of the RSA modulus
+ hash_idx The index of the hash desired (see psHashList table above)
+ out [out] The destination for the encoded data
+ outlen [in/out] The max size and resulting size of the encoded data
- return 0 if successful, -1 on failure
-*/
-int32 pkcs1OaepEncode(psPool_t *pool, const unsigned char *msg, uint32 msglen,
- const unsigned char *lparam, uint32 lparamlen,
- unsigned char *seed, uint32 seedLen,
- uint32 modulus_bitlen, int32 hash_idx,
- unsigned char *out, uint16_t *outlen)
+ return 0 if successful, -1 on failure
+ */
+int32 psPkcs1OaepEncode(psPool_t *pool, const unsigned char *msg, uint32 msglen,
+ const unsigned char *lparam, uint32 lparamlen,
+ unsigned char *seed, uint32 seedLen,
+ uint32 modulus_bitlen, int32 hash_idx,
+ unsigned char *out, psSize_t *outlen)
{
- unsigned char *DB, *lseed, *mask;
- uint32 hLen, x, y, modulus_len;
- int32 err;
- psDigestContext_t md;
+ unsigned char *DB, *lseed, *mask;
+ uint32 hLen, x, y, modulus_len;
+ int32 err;
+ psDigestContext_t md;
- if ((msg == NULL) || (out == NULL) || (outlen == NULL) || (hash_idx < 0)) {
- psTraceStrCrypto("Bad parameter to OAEP encode\n", NULL);
- return PS_ARG_FAIL;
- }
+ if ((msg == NULL) || (out == NULL) || (outlen == NULL) || (hash_idx < 0))
+ {
+ psTraceStrCrypto("Bad parameter to OAEP encode\n", NULL);
+ return PS_ARG_FAIL;
+ }
/*
- Verify hash routines
-*/
- if (hash_idx == PKCS1_SHA1_ID) {
- hLen = SHA1_HASH_SIZE;
- } else if (hash_idx == PKCS1_MD5_ID) {
-#ifdef USE_MD5
- hLen = MD5_HASH_SIZE;
-#else
- psTraceCrypto("MD5 not supported in this build.");
- psTraceCrypto(" Please enable USE_MD5\n");
- return PS_UNSUPPORTED_FAIL;
-#endif /* USE_MD5 */
- } else {
- psTraceStrCrypto("Bad hash index to OAEP encode\n", NULL);
- return PS_ARG_FAIL;
- }
+ Verify hash routines
+ */
+ if (hash_idx == PKCS1_SHA1_ID)
+ {
+ hLen = SHA1_HASH_SIZE;
+ }
+ else if (hash_idx == PKCS1_MD5_ID)
+ {
+# ifdef USE_MD5
+ hLen = MD5_HASH_SIZE;
+# else
+ psTraceCrypto("MD5 not supported in this build.");
+ psTraceCrypto(" Please enable USE_MD5\n");
+ return PS_UNSUPPORTED_FAIL;
+# endif /* USE_MD5 */
+ }
+ else
+ {
+ psTraceStrCrypto("Bad hash index to OAEP encode\n", NULL);
+ return PS_ARG_FAIL;
+ }
/*
- Seed should be generated randomly below but this helps for test vectors
-*/
- if (seed != NULL && seedLen != hLen) {
- psTraceIntCrypto("Seed must be length of %d\n", hLen);
- return PS_ARG_FAIL;
- }
+ Seed should be generated randomly below but this helps for test vectors
+ */
+ if (seed != NULL && seedLen != hLen)
+ {
+ psTraceIntCrypto("Seed must be length of %d\n", hLen);
+ return PS_ARG_FAIL;
+ }
- modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
+ modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
/*
- Test message size
-*/
- if ((2*hLen >= (modulus_len - 2)) || (msglen > (modulus_len - 2*hLen - 2))) {
- psTraceStrCrypto("Bad message size to OAEP encode\n", NULL);
- return PS_LIMIT_FAIL;
- }
+ Test message size
+ */
+ if ((2 * hLen >= (modulus_len - 2)) || (msglen > (modulus_len - 2 * hLen - 2)))
+ {
+ psTraceStrCrypto("Bad message size to OAEP encode\n", NULL);
+ return PS_LIMIT_FAIL;
+ }
/*
- Allocate ram for DB/mask/salt of size modulus_len
-*/
- lseed = NULL;
- DB = psMalloc(pool, modulus_len);
- mask = psMalloc(pool, modulus_len);
- if (DB == NULL || mask == NULL) {
- if (DB != NULL) {
- psFree(DB, pool);
- }
- if (mask != NULL) {
- psFree(mask, pool);
- }
- psTraceCrypto("Memory allocation error in OAEP encode\n");
- return PS_MEM_FAIL;
- }
+ Allocate ram for DB/mask/salt of size modulus_len
+ */
+ lseed = NULL;
+ DB = psMalloc(pool, modulus_len);
+ mask = psMalloc(pool, modulus_len);
+ if (DB == NULL || mask == NULL)
+ {
+ if (DB != NULL)
+ {
+ psFree(DB, pool);
+ }
+ if (mask != NULL)
+ {
+ psFree(mask, pool);
+ }
+ psTraceCrypto("Memory allocation error in OAEP encode\n");
+ return PS_MEM_FAIL;
+ }
/*
- Create lhash for DB block format:
+ Create lhash for DB block format:
- DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes
-*/
- x = modulus_len;
+ DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes
+ */
+ x = modulus_len;
- if (lparam != NULL) {
- if (hash_idx == PKCS1_SHA1_ID) {
- psSha1Init(&md.sha1);
- psSha1Update(&md.sha1, lparam, lparamlen);
- psSha1Final(&md.sha1, DB);
- }
-#ifdef USE_MD5
- else {
- psMd5Init(&md.md5);
- psMd5Update(&md.md5, lparam, lparamlen);
- psMd5Final(&md.md5, DB);
- }
-#endif /* USE_MD5 */
- } else {
- /* can't pass hash a NULL so use DB with zero length */
- if (hash_idx == PKCS1_SHA1_ID) {
- psSha1Init(&md.sha1);
- psSha1Update(&md.sha1, DB, 0);
- psSha1Final(&md.sha1, DB);
- }
-#ifdef USE_MD5
- else {
- psMd5Init(&md.md5);
- psMd5Update(&md.md5, DB, 0);
- psMd5Final(&md.md5, DB);
- }
-#endif /* USE_MD5 */
- }
+ if (lparam != NULL)
+ {
+ if (hash_idx == PKCS1_SHA1_ID)
+ {
+ psSha1Init(&md.sha1);
+ psSha1Update(&md.sha1, lparam, lparamlen);
+ psSha1Final(&md.sha1, DB);
+ }
+# ifdef USE_MD5
+ else
+ {
+ psMd5Init(&md.md5);
+ psMd5Update(&md.md5, lparam, lparamlen);
+ psMd5Final(&md.md5, DB);
+ }
+# endif /* USE_MD5 */
+ }
+ else
+ {
+ /* can't pass hash a NULL so use DB with zero length */
+ if (hash_idx == PKCS1_SHA1_ID)
+ {
+ psSha1Init(&md.sha1);
+ psSha1Update(&md.sha1, DB, 0);
+ psSha1Final(&md.sha1, DB);
+ }
+# ifdef USE_MD5
+ else
+ {
+ psMd5Init(&md.md5);
+ psMd5Update(&md.md5, DB, 0);
+ psMd5Final(&md.md5, DB);
+ }
+# endif /* USE_MD5 */
+ }
/*
- Append PS then 0x01 (to lhash)
-*/
- x = hLen;
- y = modulus_len - msglen - 2*hLen - 2;
- memset(DB+x, 0, y);
- x += y;
+ Append PS then 0x01 (to lhash)
+ */
+ x = hLen;
+ y = modulus_len - msglen - 2 * hLen - 2;
+ memset(DB + x, 0, y);
+ x += y;
- DB[x++] = 0x01;
+ DB[x++] = 0x01;
/*
- Message (length = msglen)
-*/
- memcpy(DB+x, msg, msglen);
- x += msglen;
+ Message (length = msglen)
+ */
+ memcpy(DB + x, msg, msglen);
+ x += msglen;
/*
- Use matrixCryptoGetPrngData to choose a random seed (if not provided)
-*/
- if (seed != NULL) {
- lseed = seed;
- } else {
- lseed = psMalloc(pool, hLen);
- if (lseed == NULL) {
- err = PS_MEM_FAIL;
- goto LBL_ERR;
- }
- if (matrixCryptoGetPrngData(lseed, hLen, NULL) != (int32)hLen) {
- psTraceCrypto("matrixCryptoGetPrngData fail in OAEP encode\n");
- err = PS_PLATFORM_FAIL;
- goto LBL_ERR;
- }
- }
+ Use psGetPrngLocked to choose a random seed (if not provided)
+ */
+ if (seed != NULL)
+ {
+ lseed = seed;
+ }
+ else
+ {
+ lseed = psMalloc(pool, hLen);
+ if (lseed == NULL)
+ {
+ err = PS_MEM_FAIL;
+ goto LBL_ERR;
+ }
+ if (psGetPrngLocked(lseed, hLen, NULL) != (int32) hLen)
+ {
+ psTraceCrypto("psGetPrngLocked fail in OAEP encode\n");
+ err = PS_PLATFORM_FAIL;
+ goto LBL_ERR;
+ }
+ }
/*
- Compute MGF1 of seed (k - hlen - 1)
-*/
- if ((err = pkcs_1_mgf1(pool, lseed, hLen, hash_idx, mask,
- modulus_len - hLen - 1)) != PS_SUCCESS) {
- psTraceStrCrypto("MGF for seed failed in OAEP encode\n", NULL);
- goto LBL_ERR;
- }
+ Compute MGF1 of seed (k - hlen - 1)
+ */
+ if ((err = pkcs_1_mgf1(pool, lseed, hLen, hash_idx, mask,
+ modulus_len - hLen - 1)) != PS_SUCCESS)
+ {
+ psTraceStrCrypto("MGF for seed failed in OAEP encode\n", NULL);
+ goto LBL_ERR;
+ }
/*
- xor against DB
-*/
- for (y = 0; y < (modulus_len - hLen - 1); y++) {
- DB[y] ^= mask[y];
- }
+ xor against DB
+ */
+ for (y = 0; y < (modulus_len - hLen - 1); y++)
+ {
+ DB[y] ^= mask[y];
+ }
/*
- Compute MGF1 of maskedDB (hLen)
-*/
- if ((err = pkcs_1_mgf1(pool, DB, modulus_len - hLen - 1, hash_idx,
- mask, hLen)) != PS_SUCCESS) {
- psTraceStrCrypto("MGF for DB failed in OAEP encode\n", NULL);
- goto LBL_ERR;
- }
+ Compute MGF1 of maskedDB (hLen)
+ */
+ if ((err = pkcs_1_mgf1(pool, DB, modulus_len - hLen - 1, hash_idx,
+ mask, hLen)) != PS_SUCCESS)
+ {
+ psTraceStrCrypto("MGF for DB failed in OAEP encode\n", NULL);
+ goto LBL_ERR;
+ }
/*
- XOR against seed
-*/
- for (y = 0; y < hLen; y++) {
- lseed[y] ^= mask[y];
- }
+ XOR against seed
+ */
+ for (y = 0; y < hLen; y++)
+ {
+ lseed[y] ^= mask[y];
+ }
/*
- Create string of length modulus_len
-*/
- if (*outlen < modulus_len) {
- psTraceStrCrypto("Bad outlen in OAEP encode\n", NULL);
- err = -1;
- goto LBL_ERR;
- }
+ Create string of length modulus_len
+ */
+ if (*outlen < modulus_len)
+ {
+ psTraceStrCrypto("Bad outlen in OAEP encode\n", NULL);
+ err = -1;
+ goto LBL_ERR;
+ }
/*
- Start output which is 0x00 || maskedSeed || maskedDB
-*/
- x = 0;
- out[x++] = 0x00;
- memcpy(out+x, lseed, hLen);
- x += hLen;
- memcpy(out+x, DB, modulus_len - hLen - 1);
- x += modulus_len - hLen - 1;
+ Start output which is 0x00 || maskedSeed || maskedDB
+ */
+ x = 0;
+ out[x++] = 0x00;
+ memcpy(out + x, lseed, hLen);
+ x += hLen;
+ memcpy(out + x, DB, modulus_len - hLen - 1);
+ x += modulus_len - hLen - 1;
- *outlen = x;
+ *outlen = x;
- err = PS_SUCCESS;
+ err = PS_SUCCESS;
LBL_ERR:
- if (seed == NULL) {
- psFree(lseed, pool);
- }
- psFree(mask, pool);
- psFree(DB, pool);
+ if (seed == NULL)
+ {
+ psFree(lseed, pool);
+ }
+ psFree(mask, pool);
+ psFree(DB, pool);
- return err;
+ return err;
}
/******************************************************************************/
/*
- PKCS #1 v2.00 OAEP decode
- pool Memory pool
- msg The encoded data to decode
- msglen The length of the encoded data (octets)
- lparam The session or system data (can be NULL)
- lparamlen The length of the lparam
- modulus_bitlen The bit length of the RSA modulus
- hash_idx The index of the hash desired
- out [out] Destination of decoding
- outlen [in/out] The max size and resulting size of the decoding
+ PKCS #1 v2.00 OAEP decode
+ pool Memory pool
+ msg The encoded data to decode
+ msglen The length of the encoded data (octets)
+ lparam The session or system data (can be NULL)
+ lparamlen The length of the lparam
+ modulus_bitlen The bit length of the RSA modulus
+ hash_idx The index of the hash desired
+ out [out] Destination of decoding
+ outlen [in/out] The max size and resulting size of the decoding
- return 0 if successful
-*/
-int32 pkcs1OaepDecode(psPool_t *pool, const unsigned char *msg, uint32 msglen,
- const unsigned char *lparam, uint32 lparamlen,
- uint32 modulus_bitlen, int32 hash_idx,
- unsigned char *out, uint16_t *outlen)
+ return 0 if successful
+ */
+int32 psPkcs1OaepDecode(psPool_t *pool, const unsigned char *msg, uint32 msglen,
+ const unsigned char *lparam, uint32 lparamlen,
+ uint32 modulus_bitlen, int32 hash_idx,
+ unsigned char *out, psSize_t *outlen)
{
- unsigned char *DB, *seed, *mask;
- uint32 hLen, x, y, modulus_len;
- int32 err;
- psDigestContext_t md;
+ unsigned char *DB, *seed, *mask;
+ uint32 hLen, x, y, modulus_len;
+ int32 err;
+ psDigestContext_t md;
- if ((msg == NULL) || (out == NULL) || (outlen == NULL) || (hash_idx < 0)) {
- psTraceCrypto("Bad parameter to OAEP decode\n");
- return PS_ARG_FAIL;
- }
+ if ((msg == NULL) || (out == NULL) || (outlen == NULL) || (hash_idx < 0))
+ {
+ psTraceCrypto("Bad parameter to OAEP decode\n");
+ return PS_ARG_FAIL;
+ }
/*
- Verify hash routines
-*/
- if (hash_idx == PKCS1_SHA1_ID) {
- hLen = SHA1_HASH_SIZE;
- } else if (hash_idx == PKCS1_MD5_ID) {
-#ifdef USE_MD5
- hLen = MD5_HASH_SIZE;
-#else
- psTraceCrypto("MD5 not supported in this build.");
- psTraceCrypto(" Please enable USE_MD5\n");
- return PS_UNSUPPORTED_FAIL;
-#endif /* USE_MD5 */
- } else {
- psTraceStrCrypto("Bad hash index to OAEP decode\n", NULL);
- return PS_ARG_FAIL;
- }
+ Verify hash routines
+ */
+ if (hash_idx == PKCS1_SHA1_ID)
+ {
+ hLen = SHA1_HASH_SIZE;
+ }
+ else if (hash_idx == PKCS1_MD5_ID)
+ {
+# ifdef USE_MD5
+ hLen = MD5_HASH_SIZE;
+# else
+ psTraceCrypto("MD5 not supported in this build.");
+ psTraceCrypto(" Please enable USE_MD5\n");
+ return PS_UNSUPPORTED_FAIL;
+# endif /* USE_MD5 */
+ }
+ else
+ {
+ psTraceStrCrypto("Bad hash index to OAEP decode\n", NULL);
+ return PS_ARG_FAIL;
+ }
- modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
+ modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
/*
- Test hash/message size
-*/
- if ((2*hLen >= (modulus_len - 2)) || (msglen != modulus_len)) {
- psTraceCrypto("Message/Modulus length mismatch in OAEP decode\n");
- return PS_LIMIT_FAIL;
- }
+ Test hash/message size
+ */
+ if ((2 * hLen >= (modulus_len - 2)) || (msglen != modulus_len))
+ {
+ psTraceCrypto("Message/Modulus length mismatch in OAEP decode\n");
+ return PS_LIMIT_FAIL;
+ }
/*
- Allocate ram for DB/mask/salt of size modulus_len
-*/
- DB = psMalloc(pool, modulus_len);
- mask = psMalloc(pool, modulus_len);
- seed = psMalloc(pool, hLen);
- if (DB == NULL || mask == NULL || seed == NULL) {
- if (DB != NULL) {
- psFree(DB, pool);
- }
- if (mask != NULL) {
- psFree(mask, pool);
- }
- if (seed != NULL) {
- psFree(seed, pool);
- }
- psTraceCrypto("Memory allocation error in OAEP decode\n");
- return -1;
- }
+ Allocate ram for DB/mask/salt of size modulus_len
+ */
+ DB = psMalloc(pool, modulus_len);
+ mask = psMalloc(pool, modulus_len);
+ seed = psMalloc(pool, hLen);
+ if (DB == NULL || mask == NULL || seed == NULL)
+ {
+ if (DB != NULL)
+ {
+ psFree(DB, pool);
+ }
+ if (mask != NULL)
+ {
+ psFree(mask, pool);
+ }
+ if (seed != NULL)
+ {
+ psFree(seed, pool);
+ }
+ psTraceCrypto("Memory allocation error in OAEP decode\n");
+ return -1;
+ }
/*
- It's now in the form
+ It's now in the form
- 0x00 || maskedseed || maskedDB
+ 0x00 || maskedseed || maskedDB
- 1 || hLen || modulus_len - hLen - 1
-*/
- if (msg[0] != 0x00) {
- psTraceCrypto("Message format error in OAEP decode\n");
- err = PS_FAILURE;
- goto LBL_ERR;
- }
+ 1 || hLen || modulus_len - hLen - 1
+ */
+ if (msg[0] != 0x00)
+ {
+ psTraceCrypto("Message format error in OAEP decode\n");
+ err = PS_FAILURE;
+ goto LBL_ERR;
+ }
/*
- Now read the masked seed
-*/
- x = 1;
- memcpy(seed, msg + x, hLen);
- x += hLen;
+ Now read the masked seed
+ */
+ x = 1;
+ memcpy(seed, msg + x, hLen);
+ x += hLen;
/*
- Now read the masked DB
-*/
- memcpy(DB, msg + x, modulus_len - hLen - 1);
- x += modulus_len - hLen - 1;
+ Now read the masked DB
+ */
+ memcpy(DB, msg + x, modulus_len - hLen - 1);
+ x += modulus_len - hLen - 1;
/*
- Compute MGF1 of maskedDB (hLen)
-*/
- if ((err = pkcs_1_mgf1(pool, DB, modulus_len - hLen - 1, hash_idx,
- mask, hLen)) != PS_SUCCESS) {
- psTraceCrypto("MGF for DB failed in OAEP decode\n");
- goto LBL_ERR;
- }
+ Compute MGF1 of maskedDB (hLen)
+ */
+ if ((err = pkcs_1_mgf1(pool, DB, modulus_len - hLen - 1, hash_idx,
+ mask, hLen)) != PS_SUCCESS)
+ {
+ psTraceCrypto("MGF for DB failed in OAEP decode\n");
+ goto LBL_ERR;
+ }
/*
- XOR against seed
-*/
- for (y = 0; y < hLen; y++) {
- seed[y] ^= mask[y];
- }
+ XOR against seed
+ */
+ for (y = 0; y < hLen; y++)
+ {
+ seed[y] ^= mask[y];
+ }
/*
- Compute MGF1 of seed (k - hlen - 1)
-*/
- if ((err = pkcs_1_mgf1(pool, seed, hLen, hash_idx, mask,
- modulus_len - hLen - 1)) != PS_SUCCESS) {
- psTraceCrypto("MGF for seed failed in OAEP decode\n");
- goto LBL_ERR;
- }
+ Compute MGF1 of seed (k - hlen - 1)
+ */
+ if ((err = pkcs_1_mgf1(pool, seed, hLen, hash_idx, mask,
+ modulus_len - hLen - 1)) != PS_SUCCESS)
+ {
+ psTraceCrypto("MGF for seed failed in OAEP decode\n");
+ goto LBL_ERR;
+ }
/*
- xor against DB
-*/
- for (y = 0; y < (modulus_len - hLen - 1); y++) {
- DB[y] ^= mask[y];
- }
+ xor against DB
+ */
+ for (y = 0; y < (modulus_len - hLen - 1); y++)
+ {
+ DB[y] ^= mask[y];
+ }
/*
- compute lhash and store it in seed [reuse temps!]
+ compute lhash and store it in seed [reuse temps!]
- DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes
-*/
- x = modulus_len;
+ DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes
+ */
+ x = modulus_len;
- if (lparam != NULL) {
- if (hash_idx == PKCS1_SHA1_ID) {
- psSha1Init(&md.sha1);
- psSha1Update(&md.sha1, lparam, lparamlen);
- psSha1Final(&md.sha1, seed);
- }
-#ifdef USE_MD5
- else {
- psMd5Init(&md.md5);
- psMd5Update(&md.md5, lparam, lparamlen);
- psMd5Final(&md.md5, seed);
- }
-#endif /* USE_MD5 */
- } else {
- /* can't pass hash routine a NULL so use DB with zero length */
- if (hash_idx == PKCS1_SHA1_ID) {
- psSha1Init(&md.sha1);
- psSha1Update(&md.sha1, DB, 0);
- psSha1Final(&md.sha1, seed);
- }
-#ifdef USE_MD5
- else {
- psMd5Init(&md.md5);
- psMd5Update(&md.md5, DB, 0);
- psMd5Final(&md.md5, seed);
- }
-#endif /* USE_MD5 */
- }
+ if (lparam != NULL)
+ {
+ if (hash_idx == PKCS1_SHA1_ID)
+ {
+ psSha1Init(&md.sha1);
+ psSha1Update(&md.sha1, lparam, lparamlen);
+ psSha1Final(&md.sha1, seed);
+ }
+# ifdef USE_MD5
+ else
+ {
+ psMd5Init(&md.md5);
+ psMd5Update(&md.md5, lparam, lparamlen);
+ psMd5Final(&md.md5, seed);
+ }
+# endif /* USE_MD5 */
+ }
+ else
+ {
+ /* can't pass hash routine a NULL so use DB with zero length */
+ if (hash_idx == PKCS1_SHA1_ID)
+ {
+ psSha1Init(&md.sha1);
+ psSha1Update(&md.sha1, DB, 0);
+ psSha1Final(&md.sha1, seed);
+ }
+# ifdef USE_MD5
+ else
+ {
+ psMd5Init(&md.md5);
+ psMd5Update(&md.md5, DB, 0);
+ psMd5Final(&md.md5, seed);
+ }
+# endif /* USE_MD5 */
+ }
/*
- Compare the lhash'es
-*/
- if (memcmp(seed, DB, hLen) != 0) {
- psTraceCrypto("Seed/DB mismatch in OAEP decode\n");
- err = -1;
- goto LBL_ERR;
- }
+ Compare the lhash'es
+ */
+ if (memcmp(seed, DB, hLen) != 0)
+ {
+ psTraceCrypto("Seed/DB mismatch in OAEP decode\n");
+ err = -1;
+ goto LBL_ERR;
+ }
/*
- Now zeroes before a 0x01
-*/
- for (x = hLen; x < (modulus_len - hLen - 1) && DB[x] == 0x00; x++) {
- /* step... */
- }
+ Now zeroes before a 0x01
+ */
+ for (x = hLen; x < (modulus_len - hLen - 1) && DB[x] == 0x00; x++)
+ {
+ /* step... */
+ }
/*
- Error out if wasn't 0x01
-*/
- if (x == (modulus_len - hLen - 1) || DB[x] != 0x01) {
- psTraceCrypto("DB format error in OAEP decode\n");
- err = -1;
- goto LBL_ERR;
- }
+ Error out if wasn't 0x01
+ */
+ if (x == (modulus_len - hLen - 1) || DB[x] != 0x01)
+ {
+ psTraceCrypto("DB format error in OAEP decode\n");
+ err = -1;
+ goto LBL_ERR;
+ }
/*
- Rest is the message (and skip 0x01)
-*/
- if ((modulus_len - hLen - 1) - ++x > *outlen) {
- psTraceCrypto("Bad outlen in OAEP decode\n");
- err = -1;
- goto LBL_ERR;
- }
+ Rest is the message (and skip 0x01)
+ */
+ if ((modulus_len - hLen - 1) - ++x > *outlen)
+ {
+ psTraceCrypto("Bad outlen in OAEP decode\n");
+ err = -1;
+ goto LBL_ERR;
+ }
/*
- Copy message
-*/
- *outlen = (modulus_len - hLen - 1) - x;
- memcpy(out, DB + x, modulus_len - hLen - 1 - x);
- x += modulus_len - hLen - 1;
+ Copy message
+ */
+ *outlen = (modulus_len - hLen - 1) - x;
+ memcpy(out, DB + x, modulus_len - hLen - 1 - x);
+ x += modulus_len - hLen - 1;
- err = PS_SUCCESS;
+ err = PS_SUCCESS;
LBL_ERR:
- psFree(seed, pool);
- psFree(mask, pool);
- psFree(DB, pool);
+ psFree(seed, pool);
+ psFree(mask, pool);
+ psFree(DB, pool);
- return err;
+ return err;
}
#endif /* USE_PKCS1_OAEP */
/******************************************************************************/
@@ -2382,173 +2725,197 @@ LBL_ERR:
#ifdef USE_PKCS1_PSS
/******************************************************************************/
/*
- PKCS #1 v2.00 Signature Encoding
- @param msghash The hash to encode
- @param msghashlen The length of the hash (octets)
- @param saltlen The length of the salt desired (octets)
- @param hash_idx The index of the hash desired
- @param modulus_bitlen The bit length of the RSA modulus
- @param out [out] The destination of the encoding
- @param outlen [in/out] The max size and resulting size of the encoded data
- @return CRYPT_OK if successful
-*/
-int32 pkcs1PssEncode(psPool_t *pool, const unsigned char *msghash,
- uint32 msghashlen, unsigned char* tsalt, uint32 saltlen,
- int32 hash_idx, uint32 modulus_bitlen, unsigned char *out,
- uint16_t *outlen)
+ PKCS #1 v2.00 Signature Encoding
+ @param msghash The hash to encode
+ @param msghashlen The length of the hash (octets)
+ @param saltlen The length of the salt desired (octets)
+ @param hash_idx The index of the hash desired
+ @param modulus_bitlen The bit length of the RSA modulus
+ @param out [out] The destination of the encoding
+ @param outlen [in/out] The max size and resulting size of the encoded data
+ @return CRYPT_OK if successful
+ */
+int32 psPkcs1PssEncode(psPool_t *pool, const unsigned char *msghash,
+ uint32 msghashlen, unsigned char *tsalt, uint32 saltlen,
+ int32 hash_idx, uint32 modulus_bitlen, unsigned char *out,
+ psSize_t *outlen)
{
- unsigned char *DB, *mask, *salt, *hash;
- uint32 x, y, hLen, modulus_len;
- int32 err;
- psDigestContext_t md;
+ unsigned char *DB, *mask, *salt, *hash;
+ uint32 x, y, hLen, modulus_len;
+ int32 err;
+ psDigestContext_t md;
- if ((msghash == NULL) || (out == NULL) || (outlen == NULL)) {
- psTraceCrypto("Bad parameter to PSS encode\n");
- return PS_ARG_FAIL;
- }
+ if ((msghash == NULL) || (out == NULL) || (outlen == NULL))
+ {
+ psTraceCrypto("Bad parameter to PSS encode\n");
+ return PS_ARG_FAIL;
+ }
- if (hash_idx == PKCS1_SHA1_ID) {
- hLen = SHA1_HASH_SIZE;
- } else if (hash_idx == PKCS1_MD5_ID) {
-#ifdef USE_MD5
- hLen = MD5_HASH_SIZE;
-#else
- psTraceCrypto("MD5 not supported in this build.");
- psTraceCrypto(" Please enable USE_MD5\n");
- return PS_UNSUPPORTED_FAIL;
-#endif /* USE_MD5 */
-#ifdef USE_SHA256
- } else if (hash_idx == PKCS1_SHA256_ID) {
- hLen = SHA256_HASH_SIZE;
-#endif
- } else {
- psTraceStrCrypto("Bad hash index to PSS encode\n", NULL);
- return PS_ARG_FAIL;
- }
+ if (hash_idx == PKCS1_SHA1_ID)
+ {
+ hLen = SHA1_HASH_SIZE;
+ }
+ else if (hash_idx == PKCS1_MD5_ID)
+ {
+# ifdef USE_MD5
+ hLen = MD5_HASH_SIZE;
+# else
+ psTraceCrypto("MD5 not supported in this build.");
+ psTraceCrypto(" Please enable USE_MD5\n");
+ return PS_UNSUPPORTED_FAIL;
+# endif /* USE_MD5 */
+# ifdef USE_SHA256
+ }
+ else if (hash_idx == PKCS1_SHA256_ID)
+ {
+ hLen = SHA256_HASH_SIZE;
+# endif
+ }
+ else
+ {
+ psTraceStrCrypto("Bad hash index to PSS encode\n", NULL);
+ return PS_ARG_FAIL;
+ }
- modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
+ modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
- /* check sizes */
- if ((saltlen > modulus_len) || (modulus_len < hLen + saltlen + 2)) {
- psTraceCrypto("Bad saltlen or modulus len to PSS encode\n");
- return PS_ARG_FAIL;
- }
+ /* check sizes */
+ if ((saltlen > modulus_len) || (modulus_len < hLen + saltlen + 2))
+ {
+ psTraceCrypto("Bad saltlen or modulus len to PSS encode\n");
+ return PS_ARG_FAIL;
+ }
- /* allocate ram for DB/mask/salt/hash of size modulus_len */
- err = PS_MEM_FAIL;
- if ((DB = psMalloc(pool, modulus_len)) == NULL) {
- return err;
- }
- memset(DB, 0x0, modulus_len);
- if ((mask = psMalloc(pool, modulus_len)) == NULL) {
- goto LBL_DB;
- }
- memset(mask, 0x0, modulus_len);
- if ((salt = psMalloc(pool, modulus_len)) == NULL) {
- goto LBL_MASK;
- }
- memset(salt, 0x0, modulus_len);
- if ((hash = psMalloc(pool, modulus_len)) == NULL) {
- goto LBL_SALT;
- }
- memset(hash, 0x0, modulus_len);
+ /* allocate ram for DB/mask/salt/hash of size modulus_len */
+ err = PS_MEM_FAIL;
+ if ((DB = psMalloc(pool, modulus_len)) == NULL)
+ {
+ return err;
+ }
+ memset(DB, 0x0, modulus_len);
+ if ((mask = psMalloc(pool, modulus_len)) == NULL)
+ {
+ goto LBL_DB;
+ }
+ memset(mask, 0x0, modulus_len);
+ if ((salt = psMalloc(pool, modulus_len)) == NULL)
+ {
+ goto LBL_MASK;
+ }
+ memset(salt, 0x0, modulus_len);
+ if ((hash = psMalloc(pool, modulus_len)) == NULL)
+ {
+ goto LBL_SALT;
+ }
+ memset(hash, 0x0, modulus_len);
- /* generate random salt */
- if (saltlen > 0) {
- if (tsalt != NULL) {
- memcpy(salt, tsalt, saltlen);
- } else {
- if (matrixCryptoGetPrngData(salt, saltlen, NULL) != (int32)saltlen){
- err = PS_PLATFORM_FAIL;
- goto LBL_ERR;
- }
- }
- }
+ /* generate random salt */
+ if (saltlen > 0)
+ {
+ if (tsalt != NULL)
+ {
+ memcpy(salt, tsalt, saltlen);
+ }
+ else
+ {
+ if (psGetPrngLocked(salt, saltlen, NULL) != (int32) saltlen)
+ {
+ err = PS_PLATFORM_FAIL;
+ goto LBL_ERR;
+ }
+ }
+ }
- /* M = (eight) 0x00 || msghash || salt, hash = H(M) */
- if (hash_idx == PKCS1_SHA1_ID) {
- psSha1Init(&md.sha1);
- psSha1Update(&md.sha1, DB, 8); /* 8 0's */
- psSha1Update(&md.sha1, msghash, msghashlen);
- psSha1Update(&md.sha1, salt, saltlen);
- psSha1Final(&md.sha1, hash);
- }
-#ifdef USE_MD5
- if (hash_idx == PKCS1_MD5_ID) {
- psMd5Init(&md.md5);
- psMd5Update(&md.md5, DB, 8); /* 8 0's */
- psMd5Update(&md.md5, msghash, msghashlen);
- psMd5Update(&md.md5, salt, saltlen);
- psMd5Final(&md.md5, hash);
- }
-#endif /* USE_MD5 */
-#ifdef USE_SHA256
- if (hash_idx == PKCS1_SHA256_ID) {
- psSha256Init(&md.sha256);
- psSha256Update(&md.sha256, DB, 8); /* 8 0's */
- psSha256Update(&md.sha256, msghash, msghashlen);
- psSha256Update(&md.sha256, salt, saltlen);
- psSha256Final(&md.sha256, hash);
- }
-#endif
+ /* M = (eight) 0x00 || msghash || salt, hash = H(M) */
+ if (hash_idx == PKCS1_SHA1_ID)
+ {
+ psSha1Init(&md.sha1);
+ psSha1Update(&md.sha1, DB, 8); /* 8 0's */
+ psSha1Update(&md.sha1, msghash, msghashlen);
+ psSha1Update(&md.sha1, salt, saltlen);
+ psSha1Final(&md.sha1, hash);
+ }
+# ifdef USE_MD5
+ if (hash_idx == PKCS1_MD5_ID)
+ {
+ psMd5Init(&md.md5);
+ psMd5Update(&md.md5, DB, 8); /* 8 0's */
+ psMd5Update(&md.md5, msghash, msghashlen);
+ psMd5Update(&md.md5, salt, saltlen);
+ psMd5Final(&md.md5, hash);
+ }
+# endif /* USE_MD5 */
+# ifdef USE_SHA256
+ if (hash_idx == PKCS1_SHA256_ID)
+ {
+ psSha256Init(&md.sha256);
+ psSha256Update(&md.sha256, DB, 8); /* 8 0's */
+ psSha256Update(&md.sha256, msghash, msghashlen);
+ psSha256Update(&md.sha256, salt, saltlen);
+ psSha256Final(&md.sha256, hash);
+ }
+# endif
- /* generate DB = PS || 0x01 || salt
- PS == modulus_len - saltlen - hLen - 2 zero bytes */
- x = 0;
- memset(DB + x, 0, modulus_len - saltlen - hLen - 2);
- x += modulus_len - saltlen - hLen - 2;
- DB[x++] = 0x01;
- memcpy(DB + x, salt, saltlen);
- x += saltlen;
+ /* generate DB = PS || 0x01 || salt
+ PS == modulus_len - saltlen - hLen - 2 zero bytes */
+ x = 0;
+ memset(DB + x, 0, modulus_len - saltlen - hLen - 2);
+ x += modulus_len - saltlen - hLen - 2;
+ DB[x++] = 0x01;
+ memcpy(DB + x, salt, saltlen);
+ x += saltlen;
- /* generate mask of length modulus_len - hLen - 1 from hash */
- if ((err = pkcs_1_mgf1(pool, hash, hLen, hash_idx, mask,
- modulus_len - hLen - 1)) != PS_SUCCESS) {
- goto LBL_ERR;
- }
+ /* generate mask of length modulus_len - hLen - 1 from hash */
+ if ((err = pkcs_1_mgf1(pool, hash, hLen, hash_idx, mask,
+ modulus_len - hLen - 1)) != PS_SUCCESS)
+ {
+ goto LBL_ERR;
+ }
- /* xor against DB */
- for (y = 0; y < (modulus_len - hLen - 1); y++) {
- DB[y] ^= mask[y];
- }
+ /* xor against DB */
+ for (y = 0; y < (modulus_len - hLen - 1); y++)
+ {
+ DB[y] ^= mask[y];
+ }
- /* output is DB || hash || 0xBC */
- if (*outlen < modulus_len) {
- *outlen = modulus_len;
- err = PS_LIMIT_FAIL;
- goto LBL_ERR;
- }
+ /* output is DB || hash || 0xBC */
+ if (*outlen < modulus_len)
+ {
+ *outlen = modulus_len;
+ err = PS_LIMIT_FAIL;
+ goto LBL_ERR;
+ }
- /* DB len = modulus_len - hLen - 1 */
- y = 0;
- memcpy(out + y, DB, modulus_len - hLen - 1);
- y += modulus_len - hLen - 1;
+ /* DB len = modulus_len - hLen - 1 */
+ y = 0;
+ memcpy(out + y, DB, modulus_len - hLen - 1);
+ y += modulus_len - hLen - 1;
- /* hash */
- memcpy(out + y, hash, hLen);
- y += hLen;
+ /* hash */
+ memcpy(out + y, hash, hLen);
+ y += hLen;
- /* 0xBC */
- out[y] = 0xBC;
+ /* 0xBC */
+ out[y] = 0xBC;
- /* now clear the 8*modulus_len - modulus_bitlen most significant bits */
- out[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1));
+ /* now clear the 8*modulus_len - modulus_bitlen most significant bits */
+ out[0] &= 0xFF >> ((modulus_len << 3) - (modulus_bitlen - 1));
- /* store output size */
- *outlen = modulus_len;
- err = PS_SUCCESS;
+ /* store output size */
+ *outlen = modulus_len;
+ err = PS_SUCCESS;
LBL_ERR: psFree(hash, pool);
LBL_SALT: psFree(salt, pool);
LBL_MASK: psFree(mask, pool);
LBL_DB: psFree(DB, pool);
- return err;
+ return err;
}
/******************************************************************************/
/**
- PKCS #1 v2.00 PSS decode
+ PKCS #1 v2.00 PSS decode
@param msghash The hash to verify
@param msghashlen The length of the hash (octets)
@param sig The signature data (encoded data)
@@ -2558,200 +2925,230 @@ LBL_DB: psFree(DB, pool);
@param modulus_bitlen The bit length of the RSA modulus
@param res [out] The result of the comparison, 1==valid, 0==invalid
-*/
-int32 pkcs1PssDecode(psPool_t *pool, const unsigned char *msghash,
- uint32 msghashlen, const unsigned char *sig, uint32 siglen,
- uint32 saltlen, int32 hash_idx, uint32 modulus_bitlen, int32 *res)
+ */
+int32 psPkcs1PssDecode(psPool_t *pool, const unsigned char *msghash,
+ uint32 msghashlen, const unsigned char *sig, uint32 siglen,
+ uint32 saltlen, int32 hash_idx, uint32 modulus_bitlen, int32 *res)
{
- unsigned char *DB, *mask, *salt, *hash;
- uint32 x, y, hLen, modulus_len;
- int32 err;
- psDigestContext_t md;
+ unsigned char *DB, *mask, *salt, *hash;
+ uint32 x, y, hLen, modulus_len;
+ int32 err;
+ psDigestContext_t md;
- if ((msghash == NULL) || (res == NULL)) {
- psTraceCrypto("Bad parameters to pkcs1PssDecode\n");
- return PS_ARG_FAIL;
- }
+ if ((msghash == NULL) || (res == NULL))
+ {
+ psTraceCrypto("Bad parameters to psPkcs1PssDecode\n");
+ return PS_ARG_FAIL;
+ }
- /* default to invalid */
- *res = 0;
+ /* default to invalid */
+ *res = 0;
- if (hash_idx == PKCS1_SHA1_ID) {
- hLen = SHA1_HASH_SIZE;
- } else if (hash_idx == PKCS1_MD5_ID) {
-#ifdef USE_MD5
- hLen = MD5_HASH_SIZE;
-#else
- psTraceCrypto("MD5 not supported in this build.");
- psTraceCrypto(" Please enable USE_MD5\n");
- return PS_UNSUPPORTED_FAIL;
-#endif /* USE_MD5 */
-#ifdef USE_SHA256
- } else if (hash_idx == PKCS1_SHA256_ID) {
- hLen = SHA256_HASH_SIZE;
-#endif
-#ifdef USE_SHA384
- } else if (hash_idx == PKCS1_SHA384_ID) {
- hLen = SHA384_HASH_SIZE;
-#endif
-#ifdef USE_SHA512
- } else if (hash_idx == PKCS1_SHA512_ID) {
- hLen = SHA512_HASH_SIZE;
-#endif
- } else {
- psTraceStrCrypto("Bad hash index to PSS decode\n", NULL);
- return PS_ARG_FAIL;
- }
+ if (hash_idx == PKCS1_SHA1_ID)
+ {
+ hLen = SHA1_HASH_SIZE;
+ }
+ else if (hash_idx == PKCS1_MD5_ID)
+ {
+# ifdef USE_MD5
+ hLen = MD5_HASH_SIZE;
+# else
+ psTraceCrypto("MD5 not supported in this build.");
+ psTraceCrypto(" Please enable USE_MD5\n");
+ return PS_UNSUPPORTED_FAIL;
+# endif /* USE_MD5 */
+# ifdef USE_SHA256
+ }
+ else if (hash_idx == PKCS1_SHA256_ID)
+ {
+ hLen = SHA256_HASH_SIZE;
+# endif
+# ifdef USE_SHA384
+ }
+ else if (hash_idx == PKCS1_SHA384_ID)
+ {
+ hLen = SHA384_HASH_SIZE;
+# endif
+# ifdef USE_SHA512
+ }
+ else if (hash_idx == PKCS1_SHA512_ID)
+ {
+ hLen = SHA512_HASH_SIZE;
+# endif
+ }
+ else
+ {
+ psTraceStrCrypto("Bad hash index to PSS decode\n", NULL);
+ return PS_ARG_FAIL;
+ }
- modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
+ modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
- /* check sizes */
- if ((saltlen > modulus_len) ||
- (modulus_len < hLen + saltlen + 2) || (siglen != modulus_len)) {
- psTraceCrypto("Bad saltlen or modulus len to PSS decode\n");
- return PS_ARG_FAIL;
- }
+ /* check sizes */
+ if ((saltlen > modulus_len) ||
+ (modulus_len < hLen + saltlen + 2) || (siglen != modulus_len))
+ {
+ psTraceCrypto("Bad saltlen or modulus len to PSS decode\n");
+ return PS_ARG_FAIL;
+ }
- /* allocate ram for DB/mask/salt/hash of size modulus_len */
- err = PS_MEM_FAIL;
- if ((DB = psMalloc(pool, modulus_len)) == NULL) {
- return err;
- }
- memset(DB, 0x0, modulus_len);
- if ((mask = psMalloc(pool, modulus_len)) == NULL) {
- goto LBL_DB;
- }
- memset(mask, 0x0, modulus_len);
- if ((salt = psMalloc(pool, modulus_len)) == NULL) {
- goto LBL_MASK;
- }
- memset(salt, 0x0, modulus_len);
- if ((hash = psMalloc(pool, modulus_len)) == NULL) {
- goto LBL_SALT;
- }
- memset(hash, 0x0, modulus_len);
+ /* allocate ram for DB/mask/salt/hash of size modulus_len */
+ err = PS_MEM_FAIL;
+ if ((DB = psMalloc(pool, modulus_len)) == NULL)
+ {
+ return err;
+ }
+ memset(DB, 0x0, modulus_len);
+ if ((mask = psMalloc(pool, modulus_len)) == NULL)
+ {
+ goto LBL_DB;
+ }
+ memset(mask, 0x0, modulus_len);
+ if ((salt = psMalloc(pool, modulus_len)) == NULL)
+ {
+ goto LBL_MASK;
+ }
+ memset(salt, 0x0, modulus_len);
+ if ((hash = psMalloc(pool, modulus_len)) == NULL)
+ {
+ goto LBL_SALT;
+ }
+ memset(hash, 0x0, modulus_len);
- /* ensure the 0xBC byte */
- if (sig[siglen-1] != 0xBC) {
- err = PS_FAILURE;
- goto LBL_ERR;
- }
+ /* ensure the 0xBC byte */
+ if (sig[siglen - 1] != 0xBC)
+ {
+ err = PS_FAILURE;
+ goto LBL_ERR;
+ }
- /* copy out the DB */
- x = 0;
- memcpy(DB, sig + x, modulus_len - hLen - 1);
- x += modulus_len - hLen - 1;
+ /* copy out the DB */
+ x = 0;
+ memcpy(DB, sig + x, modulus_len - hLen - 1);
+ x += modulus_len - hLen - 1;
- /* copy out the hash */
- memcpy(hash, sig + x, hLen);
- x += hLen;
+ /* copy out the hash */
+ memcpy(hash, sig + x, hLen);
+ x += hLen;
- /* check the MSB */
- if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)))) != 0) {
- err = PS_FAILURE;
- goto LBL_ERR;
- }
+ /* check the MSB */
+ if ((sig[0] & ~(0xFF >> ((modulus_len << 3) - (modulus_bitlen - 1)))) != 0)
+ {
+ err = PS_FAILURE;
+ goto LBL_ERR;
+ }
- /* generate mask of length modulus_len - hLen - 1 from hash */
- if ((err = pkcs_1_mgf1(pool, hash, hLen, hash_idx, mask,
- modulus_len - hLen - 1)) != PS_SUCCESS) {
- goto LBL_ERR;
- }
+ /* generate mask of length modulus_len - hLen - 1 from hash */
+ if ((err = pkcs_1_mgf1(pool, hash, hLen, hash_idx, mask,
+ modulus_len - hLen - 1)) != PS_SUCCESS)
+ {
+ goto LBL_ERR;
+ }
- /* xor against DB */
- for (y = 0; y < (modulus_len - hLen - 1); y++) {
- DB[y] ^= mask[y];
- }
+ /* xor against DB */
+ for (y = 0; y < (modulus_len - hLen - 1); y++)
+ {
+ DB[y] ^= mask[y];
+ }
- /* now clear the first byte [make sure smaller than modulus] */
- DB[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1));
+ /* now clear the first byte [make sure smaller than modulus] */
+ DB[0] &= 0xFF >> ((modulus_len << 3) - (modulus_bitlen - 1));
- /* DB = PS || 0x01 || salt,
- PS == modulus_len - saltlen - hLen - 2 zero bytes */
+ /* DB = PS || 0x01 || salt,
+ PS == modulus_len - saltlen - hLen - 2 zero bytes */
- /* check for zeroes and 0x01 */
- for (x = 0; x < modulus_len - saltlen - hLen - 2; x++) {
- if (DB[x] != 0x00) {
- err = PS_FAILURE;
- goto LBL_ERR;
- }
- }
+ /* check for zeroes and 0x01 */
+ for (x = 0; x < modulus_len - saltlen - hLen - 2; x++)
+ {
+ if (DB[x] != 0x00)
+ {
+ err = PS_FAILURE;
+ goto LBL_ERR;
+ }
+ }
- /* check for the 0x01 */
- if (DB[x++] != 0x01) {
- err = PS_FAILURE;
- goto LBL_ERR;
- }
+ /* check for the 0x01 */
+ if (DB[x++] != 0x01)
+ {
+ err = PS_FAILURE;
+ goto LBL_ERR;
+ }
- /* M = (eight) 0x00 || msghash || salt, mask = H(M) */
- if (hash_idx == PKCS1_SHA1_ID) {
- psSha1Init(&md.sha1);
- memset(mask, 0x0, 8);
- psSha1Update(&md.sha1, mask, 8);
- psSha1Update(&md.sha1, msghash, msghashlen);
- psSha1Update(&md.sha1, DB+x, saltlen);
- psSha1Final(&md.sha1, mask);
- }
-#ifdef USE_MD5
- if (hash_idx == PKCS1_MD5_ID) {
- psMd5Init(&md.md5);
- memset(mask, 0x0, 8);
- psMd5Update(&md.md5, mask, 8);
- psMd5Update(&md.md5, msghash, msghashlen);
- psMd5Update(&md.md5, DB+x, saltlen);
- psMd5Final(&md.md5, mask);
- }
-#endif /* USE_MD5 */
+ /* M = (eight) 0x00 || msghash || salt, mask = H(M) */
+ if (hash_idx == PKCS1_SHA1_ID)
+ {
+ psSha1Init(&md.sha1);
+ memset(mask, 0x0, 8);
+ psSha1Update(&md.sha1, mask, 8);
+ psSha1Update(&md.sha1, msghash, msghashlen);
+ psSha1Update(&md.sha1, DB + x, saltlen);
+ psSha1Final(&md.sha1, mask);
+ }
+# ifdef USE_MD5
+ if (hash_idx == PKCS1_MD5_ID)
+ {
+ psMd5Init(&md.md5);
+ memset(mask, 0x0, 8);
+ psMd5Update(&md.md5, mask, 8);
+ psMd5Update(&md.md5, msghash, msghashlen);
+ psMd5Update(&md.md5, DB + x, saltlen);
+ psMd5Final(&md.md5, mask);
+ }
+# endif /* USE_MD5 */
-#ifdef USE_SHA256
- if (hash_idx == PKCS1_SHA256_ID) {
- psSha256Init(&md.sha256);
- memset(mask, 0x0, 8);
- psSha256Update(&md.sha256, mask, 8);
- psSha256Update(&md.sha256, msghash, msghashlen);
- psSha256Update(&md.sha256, DB+x, saltlen);
- psSha256Final(&md.sha256, mask);
- }
-#endif
-#ifdef USE_SHA384
- if (hash_idx == PKCS1_SHA384_ID) {
- psSha384Init(&md.sha384);
- memset(mask, 0x0, 8);
- psSha384Update(&md.sha384, mask, 8);
- psSha384Update(&md.sha384, msghash, msghashlen);
- psSha384Update(&md.sha384, DB+x, saltlen);
- psSha384Final(&md.sha384, mask);
- }
-#endif
-#ifdef USE_SHA512
- if (hash_idx == PKCS1_SHA512_ID) {
- psSha512Init(&md.sha512);
- memset(mask, 0x0, 8);
- psSha512Update(&md.sha512, mask, 8);
- psSha512Update(&md.sha512, msghash, msghashlen);
- psSha512Update(&md.sha512, DB+x, saltlen);
- psSha512Final(&md.sha512, mask);
- }
-#endif
+# ifdef USE_SHA256
+ if (hash_idx == PKCS1_SHA256_ID)
+ {
+ psSha256Init(&md.sha256);
+ memset(mask, 0x0, 8);
+ psSha256Update(&md.sha256, mask, 8);
+ psSha256Update(&md.sha256, msghash, msghashlen);
+ psSha256Update(&md.sha256, DB + x, saltlen);
+ psSha256Final(&md.sha256, mask);
+ }
+# endif
+# ifdef USE_SHA384
+ if (hash_idx == PKCS1_SHA384_ID)
+ {
+ psSha384Init(&md.sha384);
+ memset(mask, 0x0, 8);
+ psSha384Update(&md.sha384, mask, 8);
+ psSha384Update(&md.sha384, msghash, msghashlen);
+ psSha384Update(&md.sha384, DB + x, saltlen);
+ psSha384Final(&md.sha384, mask);
+ }
+# endif
+# ifdef USE_SHA512
+ if (hash_idx == PKCS1_SHA512_ID)
+ {
+ psSha512Init(&md.sha512);
+ memset(mask, 0x0, 8);
+ psSha512Update(&md.sha512, mask, 8);
+ psSha512Update(&md.sha512, msghash, msghashlen);
+ psSha512Update(&md.sha512, DB + x, saltlen);
+ psSha512Final(&md.sha512, mask);
+ }
+# endif
- /* mask == hash means valid signature */
- if (memcmp(mask, hash, hLen) == 0) {
- *res = 1;
- }
+ /* mask == hash means valid signature */
+ if (memcmp(mask, hash, hLen) == 0)
+ {
+ *res = 1;
+ }
- err = PS_SUCCESS;
+ err = PS_SUCCESS;
LBL_ERR:
- psFree(hash, pool);
+ psFree(hash, pool);
LBL_SALT:
- psFree(salt, pool);
+ psFree(salt, pool);
LBL_MASK:
- psFree(mask, pool);
+ psFree(mask, pool);
LBL_DB:
- psFree(DB, pool);
- memset_s(&md, sizeof(psDigestContext_t), 0x0, sizeof(psDigestContext_t));
+ psFree(DB, pool);
+ memset_s(&md, sizeof(psDigestContext_t), 0x0, sizeof(psDigestContext_t));
- return err;
+ return err;
}
#endif /* USE_PKCS1_PSS */
diff --git a/crypto/keyformat/x509.c b/crypto/keyformat/x509.c
index 33559b5..17f9ff0 100644
--- a/crypto/keyformat/x509.c
+++ b/crypto/keyformat/x509.c
@@ -1,2331 +1,3092 @@
/**
- * @file x509.c
- * @version $Format:%h%d$
+ * @file x509.c
+ * @version $Format:%h%d$
*
- * X.509 Parser.
+ * X.509 Parser.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
#ifdef USE_X509
/******************************************************************************/
-#ifdef POSIX
-#include
-#endif
+# ifdef POSIX
+# include
+# endif
/******************************************************************************/
-#define MAX_CERTS_PER_FILE 16
+# define MAX_CERTS_PER_FILE 16
/* Maximum time length accepted.
Allows RFC 5280 format time + nanosecond fractional time + non-Zulu time. */
-#define MAX_TIME_LEN 32
+# define MAX_TIME_LEN 32
-#ifdef USE_CERT_PARSE
+# ifdef USE_CERT_PARSE
/*
- Certificate extensions
-*/
-#define IMPLICIT_ISSUER_ID 1
-#define IMPLICIT_SUBJECT_ID 2
-#define EXPLICIT_EXTENSION 3
+ Certificate extensions
+ */
+# define IMPLICIT_ISSUER_ID 1
+# define IMPLICIT_SUBJECT_ID 2
+# define EXPLICIT_EXTENSION 3
/*
- Distinguished Name attributes
-*/
-#define ATTRIB_COMMON_NAME 3
-#define ATTRIB_SURNAME 4
-#define ATTRIB_SERIALNUMBER 5
-#define ATTRIB_COUNTRY_NAME 6
-#define ATTRIB_LOCALITY 7
-#define ATTRIB_STATE_PROVINCE 8
-#define ATTRIB_STREET_ADDRESS 9
-#define ATTRIB_ORGANIZATION 10
-#define ATTRIB_ORG_UNIT 11
-#define ATTRIB_TITLE 12
-#define ATTRIB_POSTAL_ADDRESS 16
-#define ATTRIB_TELEPHONE_NUMBER 20
-#define ATTRIB_NAME 41
-#define ATTRIB_GIVEN_NAME 42
-#define ATTRIB_INITIALS 43
-#define ATTRIB_GEN_QUALIFIER 44
-#define ATTRIB_DN_QUALIFIER 46
-#define ATTRIB_PSEUDONYM 65
+ Distinguished Name attributes
+ */
+# define ATTRIB_COMMON_NAME 3
+# define ATTRIB_SURNAME 4
+# define ATTRIB_SERIALNUMBER 5
+# define ATTRIB_COUNTRY_NAME 6
+# define ATTRIB_LOCALITY 7
+# define ATTRIB_STATE_PROVINCE 8
+# define ATTRIB_STREET_ADDRESS 9
+# define ATTRIB_ORGANIZATION 10
+# define ATTRIB_ORG_UNIT 11
+# define ATTRIB_TITLE 12
+# define ATTRIB_POSTAL_ADDRESS 16
+# define ATTRIB_TELEPHONE_NUMBER 20
+# define ATTRIB_NAME 41
+# define ATTRIB_GIVEN_NAME 42
+# define ATTRIB_INITIALS 43
+# define ATTRIB_GEN_QUALIFIER 44
+# define ATTRIB_DN_QUALIFIER 46
+# define ATTRIB_PSEUDONYM 65
-#define ATTRIB_DOMAIN_COMPONENT 25
-#define ATTRIB_UID 26
-#define ATTRIB_EMAIL 27
+# define ATTRIB_DOMAIN_COMPONENT 25
+# define ATTRIB_UID 26
+# define ATTRIB_EMAIL 27
/** Enumerate X.509 milestones for issuedBefore() api */
-typedef enum {
- RFC_6818, /* January 2013 X.509 Updates Below */
- RFC_5280, /* May 2008 X.509 Obsoletes Below */
- RFC_3280, /* April 2002 X.509 Obsoletes Below */
- RFC_2459, /* January 1999 X.509 First RFC */
- X509_V3, /* 1996 X.509v3 Pre-RFC */
- X509_V2, /* 1993 X.509v2 Pre-RFC */
- X509_V1, /* 1988 X.509v1 Pre-RFC */
+typedef enum
+{
+ RFC_6818, /* January 2013 X.509 Updates Below */
+ RFC_5280, /* May 2008 X.509 Obsoletes Below */
+ RFC_3280, /* April 2002 X.509 Obsoletes Below */
+ RFC_2459, /* January 1999 X.509 First RFC */
+ X509_V3, /* 1996 X.509v3 Pre-RFC */
+ X509_V2, /* 1993 X.509v2 Pre-RFC */
+ X509_V1, /* 1988 X.509v1 Pre-RFC */
} rfc_e;
-#define USE_OID_TRACE
-
-#ifdef USE_OID_TRACE
-#define OID_LIST(A, B) { { A, B }, #B, oid_##B }
-#else
-#define OID_LIST(A, B) { { A, B }, oid_##B }
-#endif
-static const struct {
- uint16_t oid[MAX_OID_LEN];
-#ifdef USE_OID_TRACE
- char name[32];
-#endif
- int id;
+# ifdef USE_CRYPTO_TRACE
+# define OID_LIST(A, B) { { A, B }, #B, oid_ ## B }
+# else
+# define OID_LIST(A, B) { { A, B }, oid_ ## B }
+# endif
+static const struct
+{
+ uint16_t oid[MAX_OID_LEN];
+# ifdef USE_CRYPTO_TRACE
+ char name[32];
+# endif
+ int id;
} oid_list[] = {
- /* X.509 certificate extensions */
- OID_LIST(id_ce, id_ce_authorityKeyIdentifier),
- OID_LIST(id_ce, id_ce_subjectKeyIdentifier),
- OID_LIST(id_ce, id_ce_keyUsage),
- OID_LIST(id_ce, id_ce_certificatePolicies),
- OID_LIST(id_ce, id_ce_policyMappings),
- OID_LIST(id_ce, id_ce_subjectAltName),
- OID_LIST(id_ce, id_ce_issuerAltName),
- OID_LIST(id_ce, id_ce_subjectDirectoryAttributes),
- OID_LIST(id_ce, id_ce_basicConstraints),
- OID_LIST(id_ce, id_ce_nameConstraints),
- OID_LIST(id_ce, id_ce_policyConstraints),
- OID_LIST(id_ce, id_ce_extKeyUsage),
- OID_LIST(id_ce, id_ce_cRLDistributionPoints),
- OID_LIST(id_ce, id_ce_cRLNumber),
- OID_LIST(id_ce, id_ce_issuingDistributionPoint),
- OID_LIST(id_ce, id_ce_inhibitAnyPolicy),
- OID_LIST(id_ce, id_ce_freshestCRL),
- OID_LIST(id_pe, id_pe_authorityInfoAccess),
- OID_LIST(id_pe, id_pe_subjectInfoAccess),
- /* Extended Key Usage */
- OID_LIST(id_ce_eku, id_ce_eku_anyExtendedKeyUsage),
- OID_LIST(id_kp, id_kp_serverAuth),
- OID_LIST(id_kp, id_kp_clientAuth),
- OID_LIST(id_kp, id_kp_codeSigning),
- OID_LIST(id_kp, id_kp_emailProtection),
- OID_LIST(id_kp, id_kp_timeStamping),
- OID_LIST(id_kp, id_kp_OCSPSigning),
- /* policyIdentifiers */
- OID_LIST(id_qt, id_qt_cps),
- OID_LIST(id_qt, id_qt_unotice),
- /* accessDescriptors */
- OID_LIST(id_ad, id_ad_caIssuers),
- OID_LIST(id_ad, id_ad_ocsp),
- /* List terminator */
- OID_LIST(0, 0),
+ /* X.509 certificate extensions */
+ OID_LIST(id_ce, id_ce_authorityKeyIdentifier),
+ OID_LIST(id_ce, id_ce_subjectKeyIdentifier),
+ OID_LIST(id_ce, id_ce_keyUsage),
+ OID_LIST(id_ce, id_ce_certificatePolicies),
+ OID_LIST(id_ce, id_ce_policyMappings),
+ OID_LIST(id_ce, id_ce_subjectAltName),
+ OID_LIST(id_ce, id_ce_issuerAltName),
+ OID_LIST(id_ce, id_ce_subjectDirectoryAttributes),
+ OID_LIST(id_ce, id_ce_basicConstraints),
+ OID_LIST(id_ce, id_ce_nameConstraints),
+ OID_LIST(id_ce, id_ce_policyConstraints),
+ OID_LIST(id_ce, id_ce_extKeyUsage),
+ OID_LIST(id_ce, id_ce_cRLDistributionPoints),
+ OID_LIST(id_ce, id_ce_cRLNumber),
+ OID_LIST(id_ce, id_ce_issuingDistributionPoint),
+ OID_LIST(id_ce, id_ce_inhibitAnyPolicy),
+ OID_LIST(id_ce, id_ce_freshestCRL),
+ OID_LIST(id_pe, id_pe_authorityInfoAccess),
+ OID_LIST(id_pe, id_pe_subjectInfoAccess),
+ /* Extended Key Usage */
+ OID_LIST(id_ce_eku, id_ce_eku_anyExtendedKeyUsage),
+ OID_LIST(id_kp, id_kp_serverAuth),
+ OID_LIST(id_kp, id_kp_clientAuth),
+ OID_LIST(id_kp, id_kp_codeSigning),
+ OID_LIST(id_kp, id_kp_emailProtection),
+ OID_LIST(id_kp, id_kp_timeStamping),
+ OID_LIST(id_kp, id_kp_OCSPSigning),
+ /* policyIdentifiers */
+ OID_LIST(id_qt, id_qt_cps),
+ OID_LIST(id_qt, id_qt_unotice),
+ /* accessDescriptors */
+ OID_LIST(id_ad, id_ad_caIssuers),
+ OID_LIST(id_ad, id_ad_ocsp),
+ /* List terminator */
+ OID_LIST(0, 0),
};
/*
- Hybrid ASN.1/X.509 cert parsing helpers
-*/
-static int32_t getExplicitVersion(const unsigned char **pp, uint16_t len,
- int32_t expVal, int32_t *val);
+ Hybrid ASN.1/X.509 cert parsing helpers
+ */
+static int32_t getExplicitVersion(const unsigned char **pp, psSize_t len,
+ int32_t expVal, int32_t *val);
static int32_t getTimeValidity(psPool_t *pool, const unsigned char **pp,
- uint16_t len,
- int32_t *notBeforeTimeType, int32_t *notAfterTimeType,
- char **notBefore, char **notAfter);
+ psSize_t len,
+ int32_t *notBeforeTimeType, int32_t *notAfterTimeType,
+ char **notBefore, char **notAfter);
static int32_t getImplicitBitString(psPool_t *pool, const unsigned char **pp,
- uint16_t len, int32_t impVal, unsigned char **bitString,
- uint16_t *bitLen);
+ psSize_t len, int32_t impVal, unsigned char **bitString,
+ psSize_t *bitLen);
static int32_t validateDateRange(psX509Cert_t *cert);
static int32_t issuedBefore(rfc_e rfc, const psX509Cert_t *cert);
-#ifdef USE_RSA
+# ifdef USE_RSA
static int32_t x509ConfirmSignature(const unsigned char *sigHash,
- const unsigned char *sigOut, uint16_t sigLen);
-#endif
+ const unsigned char *sigOut, psSize_t sigLen);
+# endif
-#endif /* USE_CERT_PARSE */
+# endif /* USE_CERT_PARSE */
/******************************************************************************/
-#ifdef MATRIX_USE_FILE_SYSTEM
+# ifdef MATRIX_USE_FILE_SYSTEM
/******************************************************************************/
static int32_t pemCertFileBufToX509(psPool_t *pool, const unsigned char *fileBuf,
- uint16_t fileBufLen, psList_t **x509certList);
+ psSize_t fileBufLen, psList_t **x509certList);
/******************************************************************************/
/*
- Open a PEM X.509 certificate file and parse it
+ Open a PEM X.509 certificate file and parse it
- Memory info:
- Caller must free outcert with psX509FreeCert on function success
- Caller does not have to free outcert on function failure
-*/
+ Memory info:
+ Caller must free outcert with psX509FreeCert on function success
+ Caller does not have to free outcert on function failure
+ */
int32 psX509ParseCertFile(psPool_t *pool, char *fileName,
- psX509Cert_t **outcert, int32 flags)
+ psX509Cert_t **outcert, int32 flags)
{
- int32 fileBufLen, err;
- unsigned char *fileBuf;
- psList_t *fileList, *currentFile, *x509list, *frontX509;
- psX509Cert_t *currentCert, *firstCert, *prevCert;
+ int32 fileBufLen, err;
+ unsigned char *fileBuf;
+ psList_t *fileList, *currentFile, *x509list, *frontX509;
+ psX509Cert_t *currentCert, *firstCert, *prevCert;
- *outcert = NULL;
+ *outcert = NULL;
/*
- First test to see if there are multiple files being passed in.
- Looking for a semi-colon delimiter
-*/
- if ((err = psParseList(pool, fileName, ';', &fileList)) < 0) {
- return err;
- }
- currentFile = fileList;
- firstCert = prevCert = NULL;
+ First test to see if there are multiple files being passed in.
+ Looking for a semi-colon delimiter
+ */
+ if ((err = psParseList(pool, fileName, ';', &fileList)) < 0)
+ {
+ return err;
+ }
+ currentFile = fileList;
+ firstCert = prevCert = NULL;
- /* Recurse each individual file */
- while (currentFile) {
- if ((err = psGetFileBuf(pool, (char*)currentFile->item, &fileBuf,
- &fileBufLen)) < PS_SUCCESS) {
- psFreeList(fileList, pool);
- if (firstCert) psX509FreeCert(firstCert);
- return err;
- }
+ /* Recurse each individual file */
+ while (currentFile)
+ {
+ if ((err = psGetFileBuf(pool, (char *) currentFile->item, &fileBuf,
+ &fileBufLen)) < PS_SUCCESS)
+ {
+ psFreeList(fileList, pool);
+ if (firstCert)
+ {
+ psX509FreeCert(firstCert);
+ }
+ return err;
+ }
- if ((err = pemCertFileBufToX509(pool, fileBuf, fileBufLen, &x509list))
- < PS_SUCCESS) {
- psFreeList(fileList, pool);
- psFree(fileBuf, pool);
- if (firstCert) psX509FreeCert(firstCert);
- return err;
- }
- psFree(fileBuf, pool);
+ if ((err = pemCertFileBufToX509(pool, fileBuf, fileBufLen, &x509list))
+ < PS_SUCCESS)
+ {
+ psFreeList(fileList, pool);
+ psFree(fileBuf, pool);
+ if (firstCert)
+ {
+ psX509FreeCert(firstCert);
+ }
+ return err;
+ }
+ psFree(fileBuf, pool);
- frontX509 = x509list;
+ frontX509 = x509list;
/*
- Recurse each individual cert buffer from within the file
-*/
- while (x509list != NULL) {
- if ((err = psX509ParseCert(pool, x509list->item, x509list->len,
- ¤tCert, flags)) < PS_SUCCESS) {
- psX509FreeCert(currentCert);
- psFreeList(fileList, pool);
- psFreeList(frontX509, pool);
- if (firstCert) psX509FreeCert(firstCert);
- return err;
- }
+ Recurse each individual cert buffer from within the file
+ */
+ while (x509list != NULL)
+ {
+ if ((err = psX509ParseCert(pool, x509list->item, x509list->len,
+ ¤tCert, flags)) < PS_SUCCESS)
+ {
+ psX509FreeCert(currentCert);
+ psFreeList(fileList, pool);
+ psFreeList(frontX509, pool);
+ if (firstCert)
+ {
+ psX509FreeCert(firstCert);
+ }
+ return err;
+ }
- x509list = x509list->next;
- if (firstCert == NULL) {
- firstCert = currentCert;
- } else {
- prevCert->next = currentCert;
- }
- prevCert = currentCert;
- currentCert = currentCert->next;
- }
- currentFile = currentFile->next;
- psFreeList(frontX509, pool);
- }
- psFreeList(fileList, pool);
+ x509list = x509list->next;
+ if (firstCert == NULL)
+ {
+ firstCert = currentCert;
+ }
+ else
+ {
+ prevCert->next = currentCert;
+ }
+ prevCert = currentCert;
+ currentCert = currentCert->next;
+ }
+ currentFile = currentFile->next;
+ psFreeList(frontX509, pool);
+ }
+ psFreeList(fileList, pool);
- *outcert = firstCert;
+ *outcert = firstCert;
- return PS_SUCCESS;
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
-*/
+ */
static int32_t pemCertFileBufToX509(psPool_t *pool, const unsigned char *fileBuf,
- uint16_t fileBufLen, psList_t **x509certList)
+ psSize_t fileBufLen, psList_t **x509certList)
{
- psList_t *front, *prev, *current;
- unsigned char *start, *end, *endTmp;
- const unsigned char *chFileBuf;
- unsigned char l;
+ psList_t *front, *prev, *current;
+ unsigned char *start, *end, *endTmp;
+ const unsigned char *chFileBuf;
+ unsigned char l;
- *x509certList = NULL;
- prev = NULL;
- if (fileBuf == NULL) {
- psTraceCrypto("Bad parameters to pemCertFileBufToX509\n");
- return PS_ARG_FAIL;
- }
- front = current = psMalloc(pool, sizeof(psList_t));
- if (current == NULL) {
- psError("Memory allocation error first pemCertFileBufToX509\n");
- return PS_MEM_FAIL;
- }
- l = strlen("CERTIFICATE-----");
- memset(current, 0x0, sizeof(psList_t));
- chFileBuf = fileBuf;
- while (fileBufLen > 0) {
- if (
-((start = (unsigned char *)strstr((char *)chFileBuf, "-----BEGIN")) != NULL) &&
-((start = (unsigned char *)strstr((char *)chFileBuf, "CERTIFICATE-----")) != NULL) &&
-((end = (unsigned char *)strstr((char *)start, "-----END")) != NULL) &&
-((endTmp = (unsigned char *)strstr((char *)end,"CERTIFICATE-----")) != NULL)
- ) {
- start += l;
- if (current == NULL) {
- current = psMalloc(pool, sizeof(psList_t));
- if (current == NULL) {
- psFreeList(front, pool);
- psError("Memory allocation error: pemCertFileBufToX509\n");
- return PS_MEM_FAIL;
- }
- memset(current, 0x0, sizeof(psList_t));
- prev->next = current;
- }
- current->len = (uint16_t)(end - start);
- end = endTmp + l;
- while (*end == '\x0d' || *end == '\x0a' || *end == '\x09'
- || *end == ' ') {
- end++;
- }
- } else {
- psFreeList(front, pool);
- psTraceCrypto("File buffer does not look to be X.509 PEM format\n");
- return PS_PARSE_FAIL;
- }
- current->item = psMalloc(pool, current->len);
- if (current->item == NULL) {
- psFreeList(front, pool);
- psError("Memory allocation error: pemCertFileBufToX509\n");
- return PS_MEM_FAIL;
- }
- memset(current->item, '\0', current->len);
+ *x509certList = NULL;
+ prev = NULL;
+ if (fileBuf == NULL)
+ {
+ psTraceCrypto("Bad parameters to pemCertFileBufToX509\n");
+ return PS_ARG_FAIL;
+ }
+ front = current = psMalloc(pool, sizeof(psList_t));
+ if (current == NULL)
+ {
+ psError("Memory allocation error first pemCertFileBufToX509\n");
+ return PS_MEM_FAIL;
+ }
+ l = strlen("CERTIFICATE-----");
+ memset(current, 0x0, sizeof(psList_t));
+ chFileBuf = fileBuf;
+ while (fileBufLen > 0)
+ {
+ if (
+ ((start = (unsigned char *) strstr((char *) chFileBuf, "-----BEGIN")) != NULL) &&
+ ((start = (unsigned char *) strstr((char *) chFileBuf, "CERTIFICATE-----")) != NULL) &&
+ ((end = (unsigned char *) strstr((char *) start, "-----END")) != NULL) &&
+ ((endTmp = (unsigned char *) strstr((char *) end, "CERTIFICATE-----")) != NULL)
+ )
+ {
+ start += l;
+ if (current == NULL)
+ {
+ current = psMalloc(pool, sizeof(psList_t));
+ if (current == NULL)
+ {
+ psFreeList(front, pool);
+ psError("Memory allocation error: pemCertFileBufToX509\n");
+ return PS_MEM_FAIL;
+ }
+ memset(current, 0x0, sizeof(psList_t));
+ prev->next = current;
+ }
+ current->len = (uint16_t) (end - start);
+ end = endTmp + l;
+ while (*end == '\x0d' || *end == '\x0a' || *end == '\x09'
+ || *end == ' ')
+ {
+ end++;
+ }
+ }
+ else
+ {
+ psFreeList(front, pool);
+ psTraceCrypto("File buffer does not look to be X.509 PEM format\n");
+ return PS_PARSE_FAIL;
+ }
+ current->item = psMalloc(pool, current->len);
+ if (current->item == NULL)
+ {
+ psFreeList(front, pool);
+ psError("Memory allocation error: pemCertFileBufToX509\n");
+ return PS_MEM_FAIL;
+ }
+ memset(current->item, '\0', current->len);
- fileBufLen -= (uint16_t)(end - fileBuf);
- fileBuf = end;
+ fileBufLen -= (uint16_t) (end - fileBuf);
+ fileBuf = end;
- if (psBase64decode(start, current->len, current->item, ¤t->len) != 0) {
- psFreeList(front, pool);
- psTraceCrypto("Unable to base64 decode certificate\n");
- return PS_PARSE_FAIL;
- }
- prev = current;
- current = current->next;
- chFileBuf = fileBuf;
- }
- *x509certList = front;
- return PS_SUCCESS;
+ if (psBase64decode(start, current->len, current->item, ¤t->len) != 0)
+ {
+ psFreeList(front, pool);
+ psTraceCrypto("Unable to base64 decode certificate\n");
+ return PS_PARSE_FAIL;
+ }
+ prev = current;
+ current = current->next;
+ chFileBuf = fileBuf;
+ }
+ *x509certList = front;
+ return PS_SUCCESS;
}
-#endif /* MATRIX_USE_FILE_SYSTEM */
+# endif /* MATRIX_USE_FILE_SYSTEM */
/******************************************************************************/
-#ifdef USE_PKCS1_PSS
+# ifdef USE_PKCS1_PSS
/*
- RSASSA-PSS-params ::= SEQUENCE {
- hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
- maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
- saltLength [2] INTEGER DEFAULT 20,
- trailerField [3] TrailerField DEFAULT trailerFieldBC
- }
- Note, each of these is sequential, but optional.
-*/
+ RSASSA-PSS-params ::= SEQUENCE {
+ hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
+ maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
+ saltLength [2] INTEGER DEFAULT 20,
+ trailerField [3] TrailerField DEFAULT 1
+ }
+ Note, each of these is sequential, but optional.
+ */
static int32 getRsaPssParams(const unsigned char **pp, int32 size,
- psX509Cert_t *cert, int32 secondPass)
+ psX509Cert_t *cert, int32 secondPass)
{
- const unsigned char *p, *end;
- int32 oi, second, asnint;
- uint16_t plen;
+ const unsigned char *p, *end;
+ int32 oi, second, asnint;
+ psSize_t plen;
- p = *pp;
- /* SEQUENCE has already been pulled off into size */
- end = p + size;
+ p = *pp;
+ /* SEQUENCE has already been pulled off into size */
+ end = p + size;
- /* The signature algorithm appears twice in an X.509 cert and must be
- identical. If secondPass is set we check for that */
- if ((uint32)(end - p) < 1) {
- return PS_PARSE_FAIL;
- }
- if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
- p++;
- if (getAsnLength(&p, (uint32)(end - p), &plen) < 0 ||
- (end - p) < plen) {
- psTraceCrypto("Error parsing rsapss hash alg\n");
- return PS_PARSE_FAIL;
- }
- /* hashAlgorithm is OID */
- if (getAsnAlgorithmIdentifier(&p, (uint32)(end - p), &oi, &plen) < 0) {
- psTraceCrypto("Error parsing rsapss hash alg 2\n");
- return PS_PARSE_FAIL;
- }
- if (secondPass) {
- if (oi != cert->pssHash) {
- psTraceCrypto("rsapss hash alg doesn't repeat\n");
- return PS_PARSE_FAIL;
- }
- /* Convert to PKCS1_ ID for pssDecode on second pass */
- if (oi == OID_SHA1_ALG) {
- second = PKCS1_SHA1_ID;
- } else if (oi == OID_SHA256_ALG) {
- second = PKCS1_SHA256_ID;
- } else if (oi == OID_MD5_ALG) {
- second = PKCS1_MD5_ID;
-#ifdef USE_SHA384
- } else if (oi == OID_SHA384_ALG) {
- second = PKCS1_SHA384_ID;
-#endif
-#ifdef USE_SHA512
- } else if (oi == OID_SHA512_ALG) {
- second = PKCS1_SHA512_ID;
-#endif
- } else {
- psTraceCrypto("Unsupported rsapss hash alg\n");
- return PS_UNSUPPORTED_FAIL;
- }
- cert->pssHash = second;
- } else {
- /* first time, save the OID for compare */
- cert->pssHash = oi;
- }
- }
- if ((uint32)(end - p) < 1) {
- return PS_PARSE_FAIL;
- }
- if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
- /* maskGenAlgorthm is OID */
- p++;
- if (getAsnLength(&p, (uint32)(end - p), &plen) < 0 ||
- (end - p) < plen) {
- psTraceCrypto("Error parsing mask gen alg\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnAlgorithmIdentifier(&p, (uint32)(end - p), &oi, &plen) < 0) {
- psTraceCrypto("Error parsing mask gen alg 2\n");
- return PS_PARSE_FAIL;
- }
- if (secondPass) {
- if (oi != cert->maskGen) {
- psTraceCrypto("rsapss mask gen alg doesn't repeat\n");
- return PS_PARSE_FAIL;
- }
- }
- cert->maskGen = oi;
- if (cert->maskGen != OID_ID_MGF1) {
- psTraceCrypto("Unsupported RSASSA-PSS maskGenAlgorithm\n");
- return PS_UNSUPPORTED_FAIL;
- }
- /* MaskGenAlgorithm ::= AlgorithmIdentifier {
- {PKCS1MGFAlgorithms}
- }
- PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
- { OID id-mgf1 PARAMETERS HashAlgorithm },
- ... -- Allows for future expansion --
- }
+ /* The signature algorithm appears twice in an X.509 cert and must be
+ identical. If secondPass is set we check for that */
- The default mask generation function is MGF1 with SHA-1:
+ if ((uint32) (end - p) < 1)
+ {
+ goto L_PSS_DONE_OPTIONAL_PARAMS;
+ }
+ if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
+ {
+ p++;
+ if (getAsnLength(&p, (uint32) (end - p), &plen) < 0 ||
+ (end - p) < plen)
+ {
+ psTraceCrypto("Error parsing rsapss hash alg len\n");
+ return PS_PARSE_FAIL;
+ }
+ /* hashAlgorithm is OID */
+ if (getAsnAlgorithmIdentifier(&p, (uint32) (end - p), &oi, &plen) < 0)
+ {
+ psTraceCrypto("Error parsing rsapss hash alg\n");
+ return PS_PARSE_FAIL;
+ }
+ if (secondPass)
+ {
+ if (oi != cert->pssHash)
+ {
+ psTraceCrypto("rsapss hash alg doesn't repeat\n");
+ return PS_PARSE_FAIL;
+ }
+ /* Convert to PKCS1_ ID for pssDecode on second pass */
+ if (oi == OID_SHA1_ALG)
+ {
+ second = PKCS1_SHA1_ID;
+ }
+ else if (oi == OID_SHA256_ALG)
+ {
+ second = PKCS1_SHA256_ID;
+ }
+ else if (oi == OID_MD5_ALG)
+ {
+ second = PKCS1_MD5_ID;
+# ifdef USE_SHA384
+ }
+ else if (oi == OID_SHA384_ALG)
+ {
+ second = PKCS1_SHA384_ID;
+# endif
+# ifdef USE_SHA512
+ }
+ else if (oi == OID_SHA512_ALG)
+ {
+ second = PKCS1_SHA512_ID;
+# endif
+ }
+ else
+ {
+ psTraceCrypto("Unsupported rsapss hash alg\n");
+ return PS_UNSUPPORTED_FAIL;
+ }
+ cert->pssHash = second;
+ }
+ else
+ {
+ /* first time, save the OID for compare */
+ cert->pssHash = oi;
+ }
+ }
+ if ((uint32) (end - p) < 1)
+ {
+ goto L_PSS_DONE_OPTIONAL_PARAMS;
+ }
+ if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
+ {
+ /* maskGenAlgorthm is OID */
+ p++;
+ if (getAsnLength(&p, (uint32) (end - p), &plen) < 0 ||
+ (end - p) < plen)
+ {
+ psTraceCrypto("Error parsing mask gen alg len\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnAlgorithmIdentifier(&p, (uint32) (end - p), &oi, &plen) < 0)
+ {
+ psTraceCrypto("Error parsing mask gen alg\n");
+ return PS_PARSE_FAIL;
+ }
+ if (secondPass)
+ {
+ if (oi != cert->maskGen)
+ {
+ psTraceCrypto("rsapss mask gen alg doesn't repeat\n");
+ return PS_PARSE_FAIL;
+ }
+ }
+ cert->maskGen = oi;
+ if (cert->maskGen != OID_ID_MGF1)
+ {
+ psTraceCrypto("Unsupported RSASSA-PSS maskGenAlgorithm\n");
+ return PS_UNSUPPORTED_FAIL;
+ }
+ /* MaskGenAlgorithm ::= AlgorithmIdentifier {
+ {PKCS1MGFAlgorithms}
+ }
+ PKCS1MGFAlgorithms ALGORITHM-IDENTIFIER ::= {
+ { OID id-mgf1 PARAMETERS HashAlgorithm },
+ ... -- Allows for future expansion --
+ }
- mgf1SHA1 MaskGenAlgorithm ::= {
- algorithm id-mgf1,
- parameters HashAlgorithm : sha1
- }
- */
- if (getAsnAlgorithmIdentifier(&p, (uint32)(end - p), &oi, &plen) < 0) {
- psTraceCrypto("Error parsing mask hash alg\n");
- return PS_PARSE_FAIL;
- }
- if (secondPass) {
- if (oi != cert->maskHash) {
- psTraceCrypto("rsapss mask hash alg doesn't repeat\n");
- return PS_PARSE_FAIL;
- }
- }
- cert->maskHash = oi;
- }
- if ((uint32)(end - p) < 1) {
- return PS_PARSE_FAIL;
- }
- if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) {
- /* saltLen */
- p++;
- if (getAsnLength(&p, (uint32)(end - p), &plen) < 0 ||
- (end - p) < plen) {
- psTraceCrypto("Error parsing salt len\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnInteger(&p, (uint32)(end - p), &asnint) < 0) {
- psTraceCrypto("Error parsing salt len 2\n");
- return PS_PARSE_FAIL;
- }
- if (secondPass) {
- if (asnint != cert->saltLen) {
- psTraceCrypto("Error: salt len doesn't repeat\n");
- return PS_PARSE_FAIL;
- }
- }
- cert->saltLen = plen;
- }
- if ((uint32)(end - p) < 1) {
- return PS_PARSE_FAIL;
- }
- if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3)) {
- /* It shall be 1 for this version of the document, which represents
- the trailer field with hexadecimal value 0xBC */
- p++;
- if (getAsnLength(&p, (uint32)(end - p), &plen) < 0 ||
- (end - p) < plen) {
- psTraceCrypto("Error parsing rsapss trailer\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnInteger(&p, (uint32)(end - p), &asnint) < 0 ||
- plen != 0xBC) {
- psTraceCrypto("Error parsing rsapss trailer 2\n");
- return PS_PARSE_FAIL;
- }
- }
+ The default mask generation function is MGF1 with SHA-1:
- if (p != end) {
- return PS_PARSE_FAIL;
- }
- *pp = (unsigned char*)p;
- return PS_SUCCESS;
+ mgf1SHA1 MaskGenAlgorithm ::= {
+ algorithm id-mgf1,
+ parameters HashAlgorithm : sha1
+ }
+ */
+ if (getAsnAlgorithmIdentifier(&p, (uint32) (end - p), &oi, &plen) < 0)
+ {
+ psTraceCrypto("Error parsing mask hash alg\n");
+ return PS_PARSE_FAIL;
+ }
+ if (secondPass)
+ {
+ if (oi != cert->maskHash)
+ {
+ psTraceCrypto("rsapss mask hash alg doesn't repeat\n");
+ return PS_PARSE_FAIL;
+ }
+ }
+ cert->maskHash = oi;
+ }
+ if ((uint32) (end - p) < 1)
+ {
+ goto L_PSS_DONE_OPTIONAL_PARAMS;
+ }
+ if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2))
+ {
+ /* saltLen */
+ p++;
+ if (getAsnLength(&p, (uint32) (end - p), &plen) < 0 ||
+ (end - p) < plen)
+ {
+ psTraceCrypto("Error parsing salt len length\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnInteger(&p, (uint32) (end - p), &asnint) < 0)
+ {
+ psTraceCrypto("Error parsing salt len\n");
+ return PS_PARSE_FAIL;
+ }
+ if (secondPass)
+ {
+ if (asnint != cert->saltLen)
+ {
+ psTraceCrypto("Error: salt len doesn't repeat\n");
+ return PS_PARSE_FAIL;
+ }
+ }
+ cert->saltLen = asnint;
+ }
+ if ((uint32) (end - p) < 1)
+ {
+ goto L_PSS_DONE_OPTIONAL_PARAMS;
+ }
+ if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 3))
+ {
+ /* It shall be 1 for this version of the document, which represents
+ the trailer field with hexadecimal value 0xBC */
+ p++;
+ if (getAsnLength(&p, (uint32) (end - p), &plen) < 0 ||
+ (end - p) < plen)
+ {
+ psTraceCrypto("Error parsing rsapss trailer len\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnInteger(&p, (uint32) (end - p), &asnint) < 0 ||
+ asnint != 0x01)
+ {
+ psTraceCrypto("Error parsing rsapss trailer\n");
+ return PS_PARSE_FAIL;
+ }
+ }
+ if (p != end)
+ {
+ psTraceCrypto("Unexpected PSS params\n");
+ return PS_PARSE_FAIL;
+ }
+L_PSS_DONE_OPTIONAL_PARAMS:
+ *pp = (unsigned char *) p;
+ return PS_SUCCESS;
}
-#endif /* USE_PKCS1_PSS */
+# endif /* USE_PKCS1_PSS */
/******************************************************************************/
/*
- Get the public key (SubjectPublicKeyInfo) in DER format from a psX509Cert_t.
+ Get the public key (SubjectPublicKeyInfo) in DER format from a psX509Cert_t.
- Precondition: the certificate must have been parsed with psX509ParseCert or
- psX509ParseCertFile with the CERT_STORE_UNPARSED_BUFFER flag set.
+ Precondition: the certificate must have been parsed with psX509ParseCert or
+ psX509ParseCertFile with the CERT_STORE_UNPARSED_BUFFER flag set.
*/
PSPUBLIC int32 psX509GetCertPublicKeyDer(psX509Cert_t *cert,
- unsigned char *der_out,
- uint16_t *der_out_len)
+ unsigned char *der_out,
+ psSize_t *der_out_len)
{
- if (!cert || !der_out || !der_out_len) {
- return PS_ARG_FAIL;
- }
- if (cert->publicKeyDerOffsetIntoUnparsedBin == 0
- || cert->publicKeyDerLen == 0) {
- psTraceCrypto("No DER format public key stored in this cert. " \
- "CERT_STORE_DN_BUFFER flag was not used when parsing?");
- return PS_ARG_FAIL;
- }
+ if (!cert || !der_out || !der_out_len)
+ {
+ return PS_ARG_FAIL;
+ }
+ if (cert->publicKeyDerOffsetIntoUnparsedBin == 0
+ || cert->publicKeyDerLen == 0)
+ {
+ psTraceCrypto("No DER format public key stored in this cert. " \
+ "CERT_STORE_DN_BUFFER flag was not used when parsing?");
+ return PS_ARG_FAIL;
+ }
- if (*der_out_len < cert->publicKeyDerLen) {
- psTraceCrypto("Output buffer is too small");
- *der_out_len = cert->publicKeyDerLen;
- return PS_OUTPUT_LENGTH;
- }
+ if (*der_out_len < cert->publicKeyDerLen)
+ {
+ psTraceCrypto("Output buffer is too small");
+ *der_out_len = cert->publicKeyDerLen;
+ return PS_OUTPUT_LENGTH;
+ }
- memcpy(der_out,
- cert->unparsedBin + cert->publicKeyDerOffsetIntoUnparsedBin,
- cert->publicKeyDerLen);
+ memcpy(der_out,
+ cert->unparsedBin + cert->publicKeyDerOffsetIntoUnparsedBin,
+ cert->publicKeyDerLen);
- *der_out_len = cert->publicKeyDerLen;
+ *der_out_len = cert->publicKeyDerLen;
- return PS_SUCCESS;
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- Parse an X509 v3 ASN.1 certificate stream
- http://tools.ietf.org/html/rfc3280
+ Parse an X509 v3 ASN.1 certificate stream
+ http://tools.ietf.org/html/rfc3280
- flags
- CERT_STORE_UNPARSED_BUFFER
- CERT_STORE_DN_BUFFER
+ flags
+ CERT_STORE_UNPARSED_BUFFER
+ CERT_STORE_DN_BUFFER
- Memory info:
- Caller must always free outcert with psX509FreeCert. Even on failure
-*/
+ Memory info:
+ Caller must always free outcert with psX509FreeCert. Even on failure
+ */
int32 psX509ParseCert(psPool_t *pool, const unsigned char *pp, uint32 size,
- psX509Cert_t **outcert, int32 flags)
+ psX509Cert_t **outcert, int32 flags)
{
- psX509Cert_t *cert;
- const unsigned char *p, *end, *far_end, *certStart;
- uint16_t len;
- uint32_t oneCertLen;
- int32_t parsing, rc;
- const unsigned char *certEnd;
- uint16_t plen;
-#ifdef USE_CERT_PARSE
- const unsigned char *tbsCertStart;
- unsigned char sha1KeyHash[SHA1_HASH_SIZE];
- psDigestContext_t hashCtx;
- uint16_t certLen;
- const unsigned char *p_subject_pubkey_info;
- size_t subject_pubkey_info_header_len;
-#endif /* USE_CERT_PARSE */
+ psX509Cert_t *cert;
+ const unsigned char *p, *end, *far_end, *certStart;
+ psSize_t len;
+ uint32_t oneCertLen;
+ int32_t parsing, rc;
+ const unsigned char *certEnd;
+ psSize_t plen;
+
+# ifdef USE_CERT_PARSE
+ const unsigned char *tbsCertStart;
+ unsigned char sha1KeyHash[SHA1_HASH_SIZE];
+ psDigestContext_t hashCtx;
+ psSize_t certLen;
+ const unsigned char *p_subject_pubkey_info;
+ size_t subject_pubkey_info_header_len;
+# endif /* USE_CERT_PARSE */
/*
- Allocate the cert structure right away. User MUST always call
- psX509FreeCert regardless of whether this function succeeds.
- memset is important because the test for NULL is what is used
- to determine what to free
-*/
- *outcert = cert = psMalloc(pool, sizeof(psX509Cert_t));
- if (cert == NULL) {
- psError("Memory allocation failure in psX509ParseCert\n");
- return PS_MEM_FAIL;
- }
- memset(cert, 0x0, sizeof(psX509Cert_t));
- cert->pool = pool;
-#ifdef USE_CERT_PARSE
- cert->extensions.bc.cA = CA_UNDEFINED;
-#endif /* USE_CERT_PARSE */
+ Allocate the cert structure right away. User MUST always call
+ psX509FreeCert regardless of whether this function succeeds.
+ memset is important because the test for NULL is what is used
+ to determine what to free
+ */
+ *outcert = cert = psMalloc(pool, sizeof(psX509Cert_t));
+ if (cert == NULL)
+ {
+ psError("Memory allocation failure in psX509ParseCert\n");
+ return PS_MEM_FAIL;
+ }
+ memset(cert, 0x0, sizeof(psX509Cert_t));
+ cert->pool = pool;
+ cert->parseStatus = PS_X509_PARSE_FAIL; /* Default to fail status */
+# ifdef USE_CERT_PARSE
+ cert->extensions.bc.cA = CA_UNDEFINED;
+# endif /* USE_CERT_PARSE */
- p = pp;
- far_end = p + size;
+# ifdef ALWAYS_KEEP_CERT_DER
+ flags |= CERT_STORE_UNPARSED_BUFFER;
+# endif /* ALWAYS_KEEP_CERT_DER */
+
+ p = pp;
+ far_end = p + size;
/*
- Certificate ::= SEQUENCE {
- tbsCertificate TBSCertificate,
- signatureAlgorithm AlgorithmIdentifier,
- signatureValue BIT STRING }
-*/
- parsing = 1;
- while (parsing) {
- certStart = p;
- if ((rc = getAsnSequence32(&p, (uint32_t)(far_end - p), &oneCertLen, 0))
- < 0){
- psTraceCrypto("Initial cert parse error\n");
- return rc;
- }
- /* The whole list of certs could be > 64K bytes, but we still
- restrict individual certs to 64KB */
- if (oneCertLen > 0xFFFF) {
- psAssert(oneCertLen <= 0xFFFF);
- return PS_FAILURE;
- }
- end = p + oneCertLen;
+ Certificate ::= SEQUENCE {
+ tbsCertificate TBSCertificate,
+ signatureAlgorithm AlgorithmIdentifier,
+ signatureValue BIT STRING }
+ */
+ parsing = 1;
+ while (parsing)
+ {
+ certStart = p;
+ if ((rc = getAsnSequence32(&p, (uint32_t) (far_end - p), &oneCertLen, 0))
+ < 0)
+ {
+ psTraceCrypto("Initial cert parse error\n");
+ return rc;
+ }
+ /* The whole list of certs could be > 64K bytes, but we still
+ restrict individual certs to 64KB */
+ if (oneCertLen > 0xFFFF)
+ {
+ psAssert(oneCertLen <= 0xFFFF);
+ return PS_FAILURE;
+ }
+ end = p + oneCertLen;
/*
- If the user has specified to keep the ASN.1 buffer in the X.509
- structure, now is the time to account for it
-*/
- if (flags & CERT_STORE_UNPARSED_BUFFER) {
- cert->binLen = oneCertLen + (int32)(p - certStart);
- cert->unparsedBin = psMalloc(pool, cert->binLen);
- if (cert->unparsedBin == NULL) {
- psError("Memory allocation error in psX509ParseCert\n");
- return PS_MEM_FAIL;
- }
- memcpy(cert->unparsedBin, certStart, cert->binLen);
- }
+ If the user has specified to keep the ASN.1 buffer in the X.509
+ structure, now is the time to account for it
+ */
+ if (flags & CERT_STORE_UNPARSED_BUFFER)
+ {
+ cert->binLen = oneCertLen + (int32) (p - certStart);
+ cert->unparsedBin = psMalloc(pool, cert->binLen);
+ if (cert->unparsedBin == NULL)
+ {
+ psError("Memory allocation error in psX509ParseCert\n");
+ return PS_MEM_FAIL;
+ }
+ memcpy(cert->unparsedBin, certStart, cert->binLen);
+ }
-#ifdef ENABLE_CA_CERT_HASH
- /* We use the cert_sha1_hash type for the Trusted CA Indication so
- run a SHA1 has over the entire Certificate DER encoding. */
- psSha1PreInit(&hashCtx.sha1);
- psSha1Init(&hashCtx.sha1);
- psSha1Update(&hashCtx.sha1, certStart,
- oneCertLen + (int32)(p - certStart));
- psSha1Final(&hashCtx.sha1, cert->sha1CertHash);
-#endif
+# ifdef ENABLE_CA_CERT_HASH
+ /* We use the cert_sha1_hash type for the Trusted CA Indication so
+ run a SHA1 has over the entire Certificate DER encoding. */
+ psSha1PreInit(&hashCtx.sha1);
+ psSha1Init(&hashCtx.sha1);
+ psSha1Update(&hashCtx.sha1, certStart,
+ oneCertLen + (int32) (p - certStart));
+ psSha1Final(&hashCtx.sha1, cert->sha1CertHash);
+# endif
-#ifdef USE_CERT_PARSE
- tbsCertStart = p;
-#endif /* USE_CERT_PARSE */
+# ifdef USE_CERT_PARSE
+ tbsCertStart = p;
+# endif /* USE_CERT_PARSE */
/*
- TBSCertificate ::= SEQUENCE {
- version [0] EXPLICIT Version DEFAULT v1,
- serialNumber CertificateSerialNumber,
- signature AlgorithmIdentifier,
- issuer Name,
- validity Validity,
- subject Name,
- subjectPublicKeyInfo SubjectPublicKeyInfo,
- issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
- -- If present, version shall be v2 or v3
- subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
- -- If present, version shall be v2 or v3
- extensions [3] EXPLICIT Extensions OPTIONAL
- -- If present, version shall be v3 }
-*/
- if ((rc = getAsnSequence(&p, (uint32)(end - p), &len)) < 0) {
- psTraceCrypto("ASN sequence parse error\n");
- return rc;
- }
- certEnd = p + len;
-#ifdef USE_CERT_PARSE
+ TBSCertificate ::= SEQUENCE {
+ version [0] EXPLICIT Version DEFAULT v1,
+ serialNumber CertificateSerialNumber,
+ signature AlgorithmIdentifier,
+ issuer Name,
+ validity Validity,
+ subject Name,
+ subjectPublicKeyInfo SubjectPublicKeyInfo,
+ issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
+ -- If present, version shall be v2 or v3
+ subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
+ -- If present, version shall be v2 or v3
+ extensions [3] EXPLICIT Extensions OPTIONAL
+ -- If present, version shall be v3 }
+ */
+ if ((rc = getAsnSequence(&p, (uint32) (end - p), &len)) < 0)
+ {
+ psTraceCrypto("ASN sequence parse error\n");
+ return rc;
+ }
+ certEnd = p + len;
+# ifdef USE_CERT_PARSE
/*
- Start parsing TBSCertificate contents.
-*/
- certLen = certEnd - tbsCertStart;
+ Start parsing TBSCertificate contents.
+ */
+ certLen = certEnd - tbsCertStart;
/*
- Version ::= INTEGER { v1(0), v2(1), v3(2) }
-*/
- if ((rc = getExplicitVersion(&p, (uint32)(end - p), 0, &cert->version))
- < 0) {
- psTraceCrypto("ASN version parse error\n");
- return rc;
- }
- if (cert->version != 2) {
-#ifndef ALLOW_VERSION_1_ROOT_CERT_PARSE
- psTraceIntCrypto("ERROR: non-v3 certificate version %d insecure\n",
- cert->version);
- return PS_PARSE_FAIL;
-#else
- if (cert->version != 0 && cert->version != 1) {
- psTraceIntCrypto("ERROR: unsupported certificate version: %d\n",
- cert->version);
- }
- /* Allow locally stored, trusted version 1 and version 2 certificates
- to be parsed. The SSL layer code will still reject v1 and v2
- certificates that arrive over-the-wire. */
-#endif /* ALLOW_VERSION_1_ROOT_CERT_PARSE */
- }
+ Version ::= INTEGER { v1(0), v2(1), v3(2) }
+ */
+ if ((rc = getExplicitVersion(&p, (uint32) (end - p), 0, &cert->version))
+ < 0)
+ {
+ psTraceCrypto("ASN version parse error\n");
+ return rc;
+ }
+ switch (cert->version)
+ {
+ case 0:
+ case 1:
+# ifndef ALLOW_VERSION_1_ROOT_CERT_PARSE
+ psTraceCrypto("ERROR: v1 and v2 certificate versions insecure\n");
+ cert->parseStatus = PS_X509_UNSUPPORTED_VERSION;
+ return PS_PARSE_FAIL;
+# else
+ /* Allow locally stored, trusted version 1 and version 2 certificates
+ to be parsed. The SSL layer code will still reject non v3
+ certificates that arrive over-the-wire. */
+ /* Version 1 certificates do not have basic constraints to
+ specify a CA flag or path length. Here, the CA flag is implied
+ since v1 certs can only be loaded as root. We explicitly set
+ the pathLengthConstraint to allow up to 2 intermediate certs.
+ This can be adjusted to allow more or less intermediate certs. */
+ cert->extensions.bc.pathLenConstraint = 2;
+ break;
+# endif /* ALLOW_VERSION_1_ROOT_CERT_PARSE */
+ case 2:
+ /* Typical case of v3 cert */
+ break;
+ default:
+ psTraceIntCrypto("ERROR: unknown certificate version: %d\n",
+ cert->version);
+ cert->parseStatus = PS_X509_UNSUPPORTED_VERSION;
+ return PS_PARSE_FAIL;
+ }
/*
- CertificateSerialNumber ::= INTEGER
- There is a special return code for a missing serial number that
- will get written to the parse warning flag
-*/
- if ((rc = getSerialNum(pool, &p, (uint32)(end - p), &cert->serialNumber,
- &cert->serialNumberLen)) < 0) {
- psTraceCrypto("ASN serial number parse error\n");
- return rc;
- }
+ CertificateSerialNumber ::= INTEGER
+ There is a special return code for a missing serial number that
+ will get written to the parse warning flag
+ */
+ if ((rc = getSerialNum(pool, &p, (uint32) (end - p), &cert->serialNumber,
+ &cert->serialNumberLen)) < 0)
+ {
+ psTraceCrypto("ASN serial number parse error\n");
+ return rc;
+ }
/*
- AlgorithmIdentifier ::= SEQUENCE {
- algorithm OBJECT IDENTIFIER,
- parameters ANY DEFINED BY algorithm OPTIONAL }
-*/
- if ((rc = getAsnAlgorithmIdentifier(&p, (uint32)(end - p),
- &cert->certAlgorithm, &plen)) < 0) {
- psTraceCrypto("Couldn't parse algorithm identifier for certAlgorithm\n");
- return rc;
- }
- if (plen != 0) {
-#ifdef USE_PKCS1_PSS
- if (cert->certAlgorithm == OID_RSASSA_PSS) {
- /* RSASSA-PSS-params ::= SEQUENCE {
- hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
- maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
- saltLength [2] INTEGER DEFAULT 20,
- trailerField [3] TrailerField DEFAULT trailerFieldBC
- }
- */
- if ((rc = getAsnSequence(&p, (uint32)(end - p), &len)) < 0) {
- psTraceCrypto("ASN sequence parse error\n");
- return rc;
- }
- /* Always set the defaults before parsing */
- cert->pssHash = PKCS1_SHA1_ID;
- cert->saltLen = SHA1_HASH_SIZE;
- /* Something other than defaults to parse here? */
- if (len > 0) {
- if ((rc = getRsaPssParams(&p, len, cert, 0)) < 0) {
- return rc;
- }
- }
- } else {
- psTraceCrypto("Unsupported X.509 certAlgorithm\n");
- return PS_UNSUPPORTED_FAIL;
- }
-#else
- psTraceCrypto("Unsupported X.509 certAlgorithm\n");
- return PS_UNSUPPORTED_FAIL;
-#endif
- }
+ AlgorithmIdentifier ::= SEQUENCE {
+ algorithm OBJECT IDENTIFIER,
+ parameters ANY DEFINED BY algorithm OPTIONAL }
+ */
+ if ((rc = getAsnAlgorithmIdentifier(&p, (uint32) (end - p),
+ &cert->certAlgorithm, &plen)) < 0)
+ {
+ psTraceCrypto("Couldn't parse algorithm identifier for certAlgorithm\n");
+ cert->parseStatus = PS_X509_ALG_ID;
+ return rc;
+ }
+ if (plen != 0)
+ {
+# ifdef USE_PKCS1_PSS
+ if (cert->certAlgorithm == OID_RSASSA_PSS)
+ {
+ /* RSASSA-PSS-params ::= SEQUENCE {
+ hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
+ maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
+ saltLength [2] INTEGER DEFAULT 20,
+ trailerField [3] TrailerField DEFAULT trailerFieldBC
+ }
+ */
+ if ((rc = getAsnSequence(&p, (uint32) (end - p), &len)) < 0)
+ {
+ psTraceCrypto("ASN sequence parse error\n");
+ return rc;
+ }
+ /* Always set the defaults before parsing */
+ cert->pssHash = PKCS1_SHA1_ID;
+ cert->maskGen = OID_ID_MGF1;
+ cert->saltLen = SHA1_HASH_SIZE;
+ /* Something other than defaults to parse here? */
+ if (len > 0)
+ {
+ if ((rc = getRsaPssParams(&p, len, cert, 0)) < 0)
+ {
+ return rc;
+ }
+ }
+ }
+ else
+ {
+ psTraceCrypto("Unsupported X.509 certAlgorithm\n");
+ return PS_UNSUPPORTED_FAIL;
+ }
+# else
+ psTraceCrypto("Unsupported X.509 certAlgorithm\n");
+ return PS_UNSUPPORTED_FAIL;
+# endif
+ }
/*
- Name ::= CHOICE {
- RDNSequence }
+ Name ::= CHOICE {
+ RDNSequence }
- RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+ RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
- RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
+ RelativeDistinguishedName ::= SET OF AttributeTypeAndValue
- AttributeTypeAndValue ::= SEQUENCE {
- type AttributeType,
- value AttributeValue }
+ AttributeTypeAndValue ::= SEQUENCE {
+ type AttributeType,
+ value AttributeValue }
- AttributeType ::= OBJECT IDENTIFIER
+ AttributeType ::= OBJECT IDENTIFIER
- AttributeValue ::= ANY DEFINED BY AttributeType
-*/
- if ((rc = psX509GetDNAttributes(pool, &p, (uint32)(end - p),
- &cert->issuer, flags)) < 0) {
- psTraceCrypto("Couldn't parse issuer DN attributes\n");
- return rc;
- }
+ AttributeValue ::= ANY DEFINED BY AttributeType
+ */
+ if ((rc = psX509GetDNAttributes(pool, &p, (uint32) (end - p),
+ &cert->issuer, flags)) < 0)
+ {
+ psTraceCrypto("Couldn't parse issuer DN attributes\n");
+ cert->parseStatus = PS_X509_ISSUER_DN;
+ return rc;
+ }
/*
- Validity ::= SEQUENCE {
- notBefore Time,
- notAfter Time }
-*/
- if ((rc = getTimeValidity(pool, &p, (uint32)(end - p),
- &cert->notBeforeTimeType, &cert->notAfterTimeType,
- &cert->notBefore, &cert->notAfter)) < 0) {
- psTraceCrypto("Couldn't parse validity\n");
- return rc;
- }
+ Validity ::= SEQUENCE {
+ notBefore Time,
+ notAfter Time }
+ */
+ if ((rc = getTimeValidity(pool, &p, (uint32) (end - p),
+ &cert->notBeforeTimeType, &cert->notAfterTimeType,
+ &cert->notBefore, &cert->notAfter)) < 0)
+ {
+ psTraceCrypto("Couldn't parse validity\n");
+ return rc;
+ }
- /* SECURITY - platforms without a date function will always succeed */
- if ((rc = validateDateRange(cert)) < 0) {
- psTraceCrypto("Validity date check failed\n");
- return rc;
- }
+ /* SECURITY - platforms without a date function will always succeed */
+ if ((rc = validateDateRange(cert)) < 0)
+ {
+ psTraceCrypto("Validity date check failed\n");
+ cert->parseStatus = PS_X509_DATE;
+ return rc;
+ }
/*
- Subject DN
-*/
- if ((rc = psX509GetDNAttributes(pool, &p, (uint32)(end - p),
- &cert->subject, flags)) < 0) {
- psTraceCrypto("Couldn't parse subject DN attributes\n");
- return rc;
- }
+ Subject DN
+ */
+ cert->subjectKeyDerOffsetIntoUnparsedBin = (uint16_t) (p - certStart);
+ if ((rc = psX509GetDNAttributes(pool, &p, (uint32) (end - p),
+ &cert->subject, flags)) < 0)
+ {
+ psTraceCrypto("Couldn't parse subject DN attributes\n");
+ cert->parseStatus = PS_X509_SUBJECT_DN;
+ return rc;
+ }
/*
- SubjectPublicKeyInfo ::= SEQUENCE {
- algorithm AlgorithmIdentifier,
- subjectPublicKey BIT STRING }
-*/
- p_subject_pubkey_info = p;
+ SubjectPublicKeyInfo ::= SEQUENCE {
+ algorithm AlgorithmIdentifier,
+ subjectPublicKey BIT STRING }
+ */
+ p_subject_pubkey_info = p;
- cert->publicKeyDerOffsetIntoUnparsedBin = (uint16_t)(p - certStart);
+ cert->publicKeyDerOffsetIntoUnparsedBin = (uint16_t) (p - certStart);
- if ((rc = getAsnSequence(&p, (uint32)(end - p), &len)) < 0) {
- psTraceCrypto("Couldn't get ASN sequence for pubKeyAlgorithm\n");
- return rc;
- }
- subject_pubkey_info_header_len = (p - p_subject_pubkey_info);
- cert->publicKeyDerLen = len + subject_pubkey_info_header_len;
+ if ((rc = getAsnSequence(&p, (uint32) (end - p), &len)) < 0)
+ {
+ psTraceCrypto("Couldn't get ASN sequence for pubKeyAlgorithm\n");
+ return rc;
+ }
+ subject_pubkey_info_header_len = (p - p_subject_pubkey_info);
+ cert->publicKeyDerLen = len + subject_pubkey_info_header_len;
- if ((rc = getAsnAlgorithmIdentifier(&p, (uint32)(end - p),
- &cert->pubKeyAlgorithm, &plen)) < 0) {
- psTraceCrypto("Couldn't parse algorithm id for pubKeyAlgorithm\n");
- return rc;
- }
+ if ((rc = getAsnAlgorithmIdentifier(&p, (uint32) (end - p),
+ &cert->pubKeyAlgorithm, &plen)) < 0)
+ {
+ psTraceCrypto("Couldn't parse algorithm id for pubKeyAlgorithm\n");
+ return rc;
+ }
- /* Populate with correct type based on pubKeyAlgorithm OID */
- switch (cert->pubKeyAlgorithm) {
-#ifdef USE_ECC
- case OID_ECDSA_KEY_ALG:
- if (plen == 0 || plen > (int32)(end - p)) {
- psTraceCrypto("Bad params on EC OID\n");
- return PS_PARSE_FAIL;
- }
- psInitPubKey(pool, &cert->publicKey, PS_ECC);
- if (getEcPubKey(pool, &p, (uint16_t)(end - p),
- &cert->publicKey.key.ecc, sha1KeyHash) < 0) {
- return PS_PARSE_FAIL;
- }
- /* keysize will be the size of the public ecc key (2 * privateLen) */
- cert->publicKey.keysize = psEccSize(&cert->publicKey.key.ecc);
- if (cert->publicKey.keysize < (MIN_ECC_BITS / 8)) {
- psTraceIntCrypto("ECC key size < %d\n", MIN_ECC_BITS);
- psClearPubKey(&cert->publicKey);
- return PS_PARSE_FAIL;
- }
- break;
-#endif
-#ifdef USE_RSA
- case OID_RSA_KEY_ALG:
- psAssert(plen == 0); /* No parameters on RSA pub key OID */
- psInitPubKey(pool, &cert->publicKey, PS_RSA);
- if ((rc = psRsaParseAsnPubKey(pool, &p, (uint16_t)(end - p),
- &cert->publicKey.key.rsa, sha1KeyHash)) < 0) {
- psTraceCrypto("Couldn't get RSA pub key from cert\n");
- return rc;
- }
- cert->publicKey.keysize = psRsaSize(&cert->publicKey.key.rsa);
+ /* Populate with correct type based on pubKeyAlgorithm OID */
+ switch (cert->pubKeyAlgorithm)
+ {
+# ifdef USE_ECC
+ case OID_ECDSA_KEY_ALG:
+ if (plen == 0 || plen > (int32) (end - p))
+ {
+ psTraceCrypto("Bad params on EC OID\n");
+ return PS_PARSE_FAIL;
+ }
+ psInitPubKey(pool, &cert->publicKey, PS_ECC);
+ if ((rc = getEcPubKey(pool, &p, (uint16_t) (end - p),
+ &cert->publicKey.key.ecc, sha1KeyHash)) < 0)
+ {
+ if (rc == PS_UNSUPPORTED_FAIL)
+ {
+ cert->parseStatus = PS_X509_UNSUPPORTED_ECC_CURVE;
+ }
+ return PS_PARSE_FAIL;
+ }
+ /* keysize will be the size of the public ecc key (2 * privateLen) */
+ cert->publicKey.keysize = psEccSize(&cert->publicKey.key.ecc);
+ if (cert->publicKey.keysize < (MIN_ECC_BITS / 8))
+ {
+ psTraceIntCrypto("ECC key size < %d\n", MIN_ECC_BITS);
+ psClearPubKey(&cert->publicKey);
+ cert->parseStatus = PS_X509_WEAK_KEY;
+ return PS_PARSE_FAIL;
+ }
+ break;
+# endif
+# ifdef USE_RSA
+ case OID_RSA_KEY_ALG:
+ psAssert(plen == 0); /* No parameters on RSA pub key OID */
+ psInitPubKey(pool, &cert->publicKey, PS_RSA);
+ if ((rc = psRsaParseAsnPubKey(pool, &p, (uint16_t) (end - p),
+ &cert->publicKey.key.rsa, sha1KeyHash)) < 0)
+ {
+ psTraceCrypto("Couldn't get RSA pub key from cert\n");
+ cert->parseStatus = PS_X509_MISSING_RSA;
+ return rc;
+ }
+ cert->publicKey.keysize = psRsaSize(&cert->publicKey.key.rsa);
- if (cert->publicKey.keysize < (MIN_RSA_BITS / 8)) {
- psTraceIntCrypto("RSA key size < %d\n", MIN_RSA_BITS);
- psClearPubKey(&cert->publicKey);
- return PS_PARSE_FAIL;
- }
+ if (cert->publicKey.keysize < (MIN_RSA_BITS / 8))
+ {
+ psTraceIntCrypto("RSA key size < %d\n", MIN_RSA_BITS);
+ psClearPubKey(&cert->publicKey);
+ cert->parseStatus = PS_X509_WEAK_KEY;
+ return PS_PARSE_FAIL;
+ }
- break;
-#endif
- default:
- psTraceIntCrypto("Unsupported public key algorithm in cert parse: %d\n",
- cert->pubKeyAlgorithm);
- return PS_UNSUPPORTED_FAIL;
- }
+ break;
+# endif
+ default:
+ /* Note 645:RSA, 515:DSA, 518:ECDSA, 32969:GOST */
+ psTraceIntCrypto(
+ "Unsupported public key algorithm in cert parse: %d\n",
+ cert->pubKeyAlgorithm);
+ cert->parseStatus = PS_X509_UNSUPPORTED_KEY_ALG;
+ return PS_UNSUPPORTED_FAIL;
+ }
-#ifdef USE_OCSP
- /* A sha1 hash of the public key is useful for OCSP */
- memcpy(cert->sha1KeyHash, sha1KeyHash, SHA1_HASH_SIZE);
-#endif
+# ifdef USE_OCSP
+ /* A sha1 hash of the public key is useful for OCSP */
+ memcpy(cert->sha1KeyHash, sha1KeyHash, SHA1_HASH_SIZE);
+# endif
- /* As the next three values are optional, we can do a specific test here */
- if (*p != (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
- if (getImplicitBitString(pool, &p, (uint32)(end - p),
- IMPLICIT_ISSUER_ID, &cert->uniqueIssuerId,
- &cert->uniqueIssuerIdLen) < 0 ||
- getImplicitBitString(pool, &p, (uint32)(end - p),
- IMPLICIT_SUBJECT_ID, &cert->uniqueSubjectId,
- &cert->uniqueSubjectIdLen) < 0 ||
- getExplicitExtensions(pool, &p, (uint32)(end - p),
- EXPLICIT_EXTENSION, &cert->extensions, 0) < 0) {
- psTraceCrypto("There was an error parsing a certificate\n");
- psTraceCrypto("extension. This is likely caused by an\n");
- psTraceCrypto("extension format that is not currently\n");
- psTraceCrypto("recognized. Please email Inside support\n");
- psTraceCrypto("to add support for the extension.\n\n");
- return PS_PARSE_FAIL;
- }
- }
+ /* As the next three values are optional, we can do a specific test here */
+ if (*p != (ASN_SEQUENCE | ASN_CONSTRUCTED))
+ {
+ if (getImplicitBitString(pool, &p, (uint32) (end - p),
+ IMPLICIT_ISSUER_ID, &cert->uniqueIssuerId,
+ &cert->uniqueIssuerIdLen) < 0 ||
+ getImplicitBitString(pool, &p, (uint32) (end - p),
+ IMPLICIT_SUBJECT_ID, &cert->uniqueSubjectId,
+ &cert->uniqueSubjectIdLen) < 0 ||
+ getExplicitExtensions(pool, &p, (uint32) (end - p),
+ EXPLICIT_EXTENSION, &cert->extensions, 0) < 0)
+ {
+ psTraceCrypto("There was an error parsing a certificate\n"
+ "extension. This is likely caused by an\n"
+ "extension format that is not currently\n"
+ "recognized. Please email support\n"
+ "to add support for the extension.\n");
+ cert->parseStatus = PS_X509_UNSUPPORTED_EXT;
+ return PS_PARSE_FAIL;
+ }
+ }
- /* This is the end of the cert. Do a check here to be certain */
- if (certEnd != p) {
- psTraceCrypto("Error. Expecting end of cert\n");
- return PS_LIMIT_FAIL;
- }
+ /* This is the end of the cert. Do a check here to be certain */
+ if (certEnd != p)
+ {
+ psTraceCrypto("Error. Expecting end of cert\n");
+ cert->parseStatus = PS_X509_EOF;
+ return PS_LIMIT_FAIL;
+ }
- /* Reject any cert without a distinguishedName or subjectAltName */
- if (cert->subject.commonName == NULL &&
- cert->subject.country == NULL &&
- cert->subject.state == NULL &&
- cert->subject.organization == NULL &&
- cert->subject.orgUnit == NULL &&
- cert->subject.domainComponent == NULL &&
- cert->extensions.san == NULL) {
- psTraceCrypto("Error. Cert has no name information\n");
- return PS_PARSE_FAIL;
- }
-#else /* No TBSCertificate parsing. */
- p = certEnd;
-#endif /* USE_CERT_PARSE (end of TBSCertificate parsing) */
+ /* Reject any cert without a distinguishedName or subjectAltName */
+ if (cert->subject.commonName == NULL &&
+ cert->subject.country == NULL &&
+ cert->subject.state == NULL &&
+ cert->subject.organization == NULL &&
+ cert->subject.orgUnit == NULL &&
+ cert->subject.domainComponent == NULL &&
+ cert->extensions.san == NULL)
+ {
+ psTraceCrypto("Error. Cert has no name information\n");
+ cert->parseStatus = PS_X509_MISSING_NAME;
+ return PS_PARSE_FAIL;
+ }
+# else /* No TBSCertificate parsing. */
+ p = certEnd;
+# endif /* USE_CERT_PARSE (end of TBSCertificate parsing) */
- /* Certificate signature info */
- if ((rc = getAsnAlgorithmIdentifier(&p, (uint32)(end - p),
- &cert->sigAlgorithm, &plen)) < 0) {
- psTraceCrypto("Couldn't get algorithm identifier for sigAlgorithm\n");
- return rc;
- }
+ /* Certificate signature info */
+ if ((rc = getAsnAlgorithmIdentifier(&p, (uint32) (end - p),
+ &cert->sigAlgorithm, &plen)) < 0)
+ {
+ psTraceCrypto("Couldn't get algorithm identifier for sigAlgorithm\n");
+ return rc;
+ }
- if (plen != 0) {
-#ifdef USE_PKCS1_PSS
- if (cert->sigAlgorithm == OID_RSASSA_PSS) {
- /* RSASSA-PSS-params ::= SEQUENCE {
- hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
- maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
- saltLength [2] INTEGER DEFAULT 20,
- trailerField [3] TrailerField DEFAULT trailerFieldBC
- }
- */
- if ((rc = getAsnSequence(&p, (uint32)(end - p), &len)) < 0) {
- psTraceCrypto("ASN sequence parse error\n");
- return rc;
- }
- /* Something other than defaults to parse here? */
- if (len > 0) {
- if ((rc = getRsaPssParams(&p, len, cert, 1)) < 0) {
- return rc;
- }
- }
- } else {
- psTraceCrypto("Unsupported X.509 sigAlgorithm\n");
- return PS_UNSUPPORTED_FAIL;
- }
-#else
- psTraceCrypto("Unsupported X.509 sigAlgorithm\n");
- return PS_UNSUPPORTED_FAIL;
-#endif /* USE_PKCS1_PSS */
- }
-#ifdef USE_CERT_PARSE
+ if (plen != 0)
+ {
+# ifdef USE_PKCS1_PSS
+ if (cert->sigAlgorithm == OID_RSASSA_PSS)
+ {
+ /* RSASSA-PSS-params ::= SEQUENCE {
+ hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
+ maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
+ saltLength [2] INTEGER DEFAULT 20,
+ trailerField [3] TrailerField DEFAULT trailerFieldBC
+ }
+ */
+ if ((rc = getAsnSequence(&p, (uint32) (end - p), &len)) < 0)
+ {
+ psTraceCrypto("ASN sequence parse error\n");
+ return rc;
+ }
+ /* Something other than defaults to parse here? */
+ if (len > 0)
+ {
+ if ((rc = getRsaPssParams(&p, len, cert, 1)) < 0)
+ {
+ return rc;
+ }
+ }
+ }
+ else
+ {
+ psTraceCrypto("Unsupported X.509 sigAlgorithm\n");
+ return PS_UNSUPPORTED_FAIL;
+ }
+# else
+ psTraceCrypto("Unsupported X.509 sigAlgorithm\n");
+ return PS_UNSUPPORTED_FAIL;
+# endif /* USE_PKCS1_PSS */
+ }
+# ifdef USE_CERT_PARSE
/*
- Signature algorithm must match that specified in TBS cert
-*/
- if (cert->certAlgorithm != cert->sigAlgorithm) {
- psTraceCrypto("Parse error: mismatched signature type\n");
- return PS_CERT_AUTH_FAIL;
- }
+ https://tools.ietf.org/html/rfc5280#section-4.1.1.2
+ This field MUST contain the same algorithm identifier as the
+ signature field in the sequence tbsCertificate (Section 4.1.2.3).
+ */
+ if (cert->certAlgorithm != cert->sigAlgorithm)
+ {
+ psTraceIntCrypto("Parse error: mismatched sig alg (tbs = %d ",
+ cert->certAlgorithm);
+ psTraceIntCrypto("sig = %d)\n", cert->sigAlgorithm);
+ cert->parseStatus = PS_X509_SIG_MISMATCH;
+ return PS_CERT_AUTH_FAIL;
+ }
+/*
+ Compute the hash of the cert here for CA validation
+ */
+ switch (cert->certAlgorithm)
+ {
+# ifdef ENABLE_MD5_SIGNED_CERTS
+# ifdef USE_MD2
+ case OID_MD2_RSA_SIG:
+ psMd2Init(&hashCtx.md2);
+ psMd2Update(&hashCtx.md2, tbsCertStart, certLen);
+ psMd2Final(&hashCtx.md2, cert->sigHash);
+ break;
+# endif /* USE_MD2 */
+ case OID_MD5_RSA_SIG:
+ psMd5Init(&hashCtx.md5);
+ psMd5Update(&hashCtx.md5, tbsCertStart, certLen);
+ psMd5Final(&hashCtx.md5, cert->sigHash);
+ break;
+# endif
+# ifdef ENABLE_SHA1_SIGNED_CERTS
+ case OID_SHA1_RSA_SIG:
+ case OID_SHA1_RSA_SIG2:
+# ifdef USE_ECC
+ case OID_SHA1_ECDSA_SIG:
+# endif
+ psSha1PreInit(&hashCtx.sha1);
+ psSha1Init(&hashCtx.sha1);
+ psSha1Update(&hashCtx.sha1, tbsCertStart, certLen);
+ psSha1Final(&hashCtx.sha1, cert->sigHash);
+ break;
+# endif
+# ifdef USE_SHA256
+ case OID_SHA256_RSA_SIG:
+# ifdef USE_ECC
+ case OID_SHA256_ECDSA_SIG:
+# endif
+ psSha256PreInit(&hashCtx.sha256);
+ psSha256Init(&hashCtx.sha256);
+ psSha256Update(&hashCtx.sha256, tbsCertStart, certLen);
+ psSha256Final(&hashCtx.sha256, cert->sigHash);
+ break;
+# endif
+# ifdef USE_SHA384
+ case OID_SHA384_RSA_SIG:
+# ifdef USE_ECC
+ case OID_SHA384_ECDSA_SIG:
+# endif
+ psSha384PreInit(&hashCtx.sha384);
+ psSha384Init(&hashCtx.sha384);
+ psSha384Update(&hashCtx.sha384, tbsCertStart, certLen);
+ psSha384Final(&hashCtx.sha384, cert->sigHash);
+ break;
+# endif
+# ifdef USE_SHA512
+ case OID_SHA512_RSA_SIG:
+# ifdef USE_ECC
+ case OID_SHA512_ECDSA_SIG:
+# endif
+ psSha512PreInit(&hashCtx.sha512);
+ psSha512Init(&hashCtx.sha512);
+ psSha512Update(&hashCtx.sha512, tbsCertStart, certLen);
+ psSha512Final(&hashCtx.sha512, cert->sigHash);
+ break;
+# endif
+# ifdef USE_PKCS1_PSS
+ case OID_RSASSA_PSS:
+ switch (cert->pssHash)
+ {
+# ifdef ENABLE_MD5_SIGNED_CERTS
+ case PKCS1_MD5_ID:
+ psMd5Init(&hashCtx.md5);
+ psMd5Update(&hashCtx.md5, tbsCertStart, certLen);
+ psMd5Final(&hashCtx.md5, cert->sigHash);
+ break;
+# endif
+# ifdef ENABLE_SHA1_SIGNED_CERTS
+ case PKCS1_SHA1_ID:
+ psSha1PreInit(&hashCtx.sha1);
+ psSha1Init(&hashCtx.sha1);
+ psSha1Update(&hashCtx.sha1, tbsCertStart, certLen);
+ psSha1Final(&hashCtx.sha1, cert->sigHash);
+ break;
+# endif
+# ifdef USE_SHA256
+ case PKCS1_SHA256_ID:
+ psSha256PreInit(&hashCtx.sha256);
+ psSha256Init(&hashCtx.sha256);
+ psSha256Update(&hashCtx.sha256, tbsCertStart, certLen);
+ psSha256Final(&hashCtx.sha256, cert->sigHash);
+ break;
+# endif
+# ifdef USE_SHA384
+ case PKCS1_SHA384_ID:
+ psSha384PreInit(&hashCtx.sha384);
+ psSha384Init(&hashCtx.sha384);
+ psSha384Update(&hashCtx.sha384, tbsCertStart, certLen);
+ psSha384Final(&hashCtx.sha384, cert->sigHash);
+ break;
+# endif
+# ifdef USE_SHA512
+ case PKCS1_SHA512_ID:
+ psSha512PreInit(&hashCtx.sha512);
+ psSha512Init(&hashCtx.sha512);
+ psSha512Update(&hashCtx.sha512, tbsCertStart, certLen);
+ psSha512Final(&hashCtx.sha512, cert->sigHash);
+ break;
+# endif
+ default:
+ psTraceIntCrypto("Unsupported pssHash algorithm: %d\n",
+ cert->pssHash);
+ cert->parseStatus = PS_X509_UNSUPPORTED_SIG_ALG;
+ return PS_UNSUPPORTED_FAIL;
+
+ } /* switch pssHash */
+ break;
+# endif /* USE_PKCS1_PSS */
+
+ default:
+ /* Note 1670:MD2 */
+ psTraceIntCrypto("Unsupported cert algorithm: %d\n",
+ cert->certAlgorithm);
+ cert->parseStatus = PS_X509_UNSUPPORTED_SIG_ALG;
+ return PS_UNSUPPORTED_FAIL;
+
+ } /* switch certAlgorithm */
+
+ /* 6 empty bytes is plenty enough to know if sigHash didn't calculate */
+ if (memcmp(cert->sigHash, "\0\0\0\0\0\0", 6) == 0)
+ {
+ psTraceIntCrypto("No library signature alg support for cert: %d\n",
+ cert->certAlgorithm);
+ return PS_UNSUPPORTED_FAIL;
+ }
+# endif /* USE_CERT_PARSE */
+
+ if ((rc = psX509GetSignature(pool, &p, (uint32) (end - p),
+ &cert->signature, &cert->signatureLen)) < 0)
+ {
+ psTraceCrypto("Couldn't parse signature\n");
+ cert->parseStatus = PS_X509_SIGNATURE;
+ return rc;
+ }
+
+# ifndef USE_CERT_PARSE
+ /* Some APIs need certAlgorithm.*/
+ cert->certAlgorithm = cert->sigAlgorithm;
+# endif /* !USE_CERT_PARSE */
/*
- Compute the hash of the cert here for CA validation
-*/
- switch (cert->certAlgorithm) {
-#ifdef ENABLE_MD5_SIGNED_CERTS
-#ifdef USE_MD2
- case OID_MD2_RSA_SIG:
- psMd2Init(&hashCtx.md2);
- psMd2Update(&hashCtx.md2, tbsCertStart, certLen);
- psMd2Final(&hashCtx.md2, cert->sigHash);
- break;
-#endif /* USE_MD2 */
- case OID_MD5_RSA_SIG:
- psMd5Init(&hashCtx.md5);
- psMd5Update(&hashCtx.md5, tbsCertStart, certLen);
- psMd5Final(&hashCtx.md5, cert->sigHash);
- break;
-#endif
-#ifdef ENABLE_SHA1_SIGNED_CERTS
- case OID_SHA1_RSA_SIG:
-#ifdef USE_ECC
- case OID_SHA1_ECDSA_SIG:
-#endif
- psSha1PreInit(&hashCtx.sha1);
- psSha1Init(&hashCtx.sha1);
- psSha1Update(&hashCtx.sha1, tbsCertStart, certLen);
- psSha1Final(&hashCtx.sha1, cert->sigHash);
- break;
-#endif
-#ifdef USE_SHA256
- case OID_SHA256_RSA_SIG:
-#ifdef USE_ECC
- case OID_SHA256_ECDSA_SIG:
-#endif
- psSha256PreInit(&hashCtx.sha256);
- psSha256Init(&hashCtx.sha256);
- psSha256Update(&hashCtx.sha256, tbsCertStart, certLen);
- psSha256Final(&hashCtx.sha256, cert->sigHash);
- break;
-#endif
-#ifdef USE_SHA384
- case OID_SHA384_RSA_SIG:
-#ifdef USE_ECC
- case OID_SHA384_ECDSA_SIG:
-#endif
- psSha384PreInit(&hashCtx.sha384);
- psSha384Init(&hashCtx.sha384);
- psSha384Update(&hashCtx.sha384, tbsCertStart, certLen);
- psSha384Final(&hashCtx.sha384, cert->sigHash);
- break;
-#endif
-#ifdef USE_SHA512
- case OID_SHA512_RSA_SIG:
-#ifdef USE_ECC
- case OID_SHA512_ECDSA_SIG:
-#endif
- psSha512PreInit(&hashCtx.sha512);
- psSha512Init(&hashCtx.sha512);
- psSha512Update(&hashCtx.sha512, tbsCertStart, certLen);
- psSha512Final(&hashCtx.sha512, cert->sigHash);
- break;
-#endif
-#ifdef USE_PKCS1_PSS
- case OID_RSASSA_PSS:
- switch (cert->pssHash) {
-#ifdef ENABLE_MD5_SIGNED_CERTS
- case PKCS1_MD5_ID:
- psMd5Init(&hashCtx.md5);
- psMd5Update(&hashCtx.md5, tbsCertStart, certLen);
- psMd5Final(&hashCtx.md5, cert->sigHash);
- break;
-#endif
-#ifdef ENABLE_SHA1_SIGNED_CERTS
- case PKCS1_SHA1_ID:
- psSha1PreInit(&hashCtx.sha1);
- psSha1Init(&hashCtx.sha1);
- psSha1Update(&hashCtx.sha1, tbsCertStart, certLen);
- psSha1Final(&hashCtx.sha1, cert->sigHash);
- break;
-#endif
-#ifdef USE_SHA256
- case PKCS1_SHA256_ID:
- psSha256PreInit(&hashCtx.sha256);
- psSha256Init(&hashCtx.sha256);
- psSha256Update(&hashCtx.sha256, tbsCertStart, certLen);
- psSha256Final(&hashCtx.sha256, cert->sigHash);
- break;
-#endif
-#ifdef USE_SHA384
- case PKCS1_SHA384_ID:
- psSha384PreInit(&hashCtx.sha384);
- psSha384Init(&hashCtx.sha384);
- psSha384Update(&hashCtx.sha384, tbsCertStart, certLen);
- psSha384Final(&hashCtx.sha384, cert->sigHash);
- break;
-#endif
-#ifdef USE_SHA512
- case PKCS1_SHA512_ID:
- psSha512PreInit(&hashCtx.sha512);
- psSha512Init(&hashCtx.sha512);
- psSha512Update(&hashCtx.sha512, tbsCertStart, certLen);
- psSha512Final(&hashCtx.sha512, cert->sigHash);
- break;
-#endif
- default:
- return PS_UNSUPPORTED_FAIL;
-
- } /* switch pssHash */
- break;
-#endif /* USE_PKCS1_PSS */
-
- default:
- psTraceCrypto("Unsupported cert algorithm\n");
- return PS_UNSUPPORTED_FAIL;
-
- } /* switch certAlgorithm */
-
- /* 6 empty bytes is plenty enough to know if sigHash didn't calculate */
- if (memcmp(cert->sigHash, "\0\0\0\0\0\0", 6) == 0) {
- psTraceIntCrypto("No library signature alg support for cert: %d\n",
- cert->certAlgorithm);
- return PS_UNSUPPORTED_FAIL;
- }
-#endif /* USE_CERT_PARSE */
-
- if ((rc = psX509GetSignature(pool, &p, (uint32)(end - p),
- &cert->signature, &cert->signatureLen)) < 0) {
- psTraceCrypto("Couldn't parse signature\n");
- return rc;
- }
-
-#ifndef USE_CERT_PARSE
- /* Some APIs need certAlgorithm.*/
- cert->certAlgorithm = cert->sigAlgorithm;
-#endif /* !USE_CERT_PARSE */
-
-/*
- The ability to parse additional chained certs is a PKI product
- feature addition. Chaining in MatrixSSL is handled internally.
-*/
- if ((p != far_end) && (p < (far_end + 1))) {
- if (*p == 0x0 && *(p + 1) == 0x0) {
- parsing = 0; /* An indefinite length stream was passed in */
- /* caller will have to deal with skipping these because they
- would have read off the TL of this ASN.1 stream */
- } else {
- cert->next = psMalloc(pool, sizeof(psX509Cert_t));
- if (cert->next == NULL) {
- psError("Memory allocation error in psX509ParseCert\n");
- return PS_MEM_FAIL;
- }
- cert = cert->next;
- memset(cert, 0x0, sizeof(psX509Cert_t));
- cert->pool = pool;
- }
- } else {
- parsing = 0;
- }
- }
-
- return (int32)(p - pp);
+ The ability to parse additional chained certs is a PKI product
+ feature addition. Chaining in MatrixSSL is handled internally.
+ */
+ if ((p != far_end) && (p < (far_end + 1)))
+ {
+ if (*p == 0x0 && *(p + 1) == 0x0)
+ {
+ parsing = 0; /* An indefinite length stream was passed in */
+ /* caller will have to deal with skipping these because they
+ would have read off the TL of this ASN.1 stream */
+ }
+ else
+ {
+ cert->next = psMalloc(pool, sizeof(psX509Cert_t));
+ if (cert->next == NULL)
+ {
+ psError("Memory allocation error in psX509ParseCert\n");
+ return PS_MEM_FAIL;
+ }
+ cert = cert->next;
+ memset(cert, 0x0, sizeof(psX509Cert_t));
+ cert->pool = pool;
+ }
+ }
+ else
+ {
+ parsing = 0;
+ }
+ }
+ cert->parseStatus = PS_X509_PARSE_SUCCESS;
+ return (int32) (p - pp);
}
-#ifdef USE_CERT_PARSE
+# ifdef USE_CERT_PARSE
static void freeOrgUnitList(x509OrgUnit_t *orgUnit, psPool_t *allocPool)
{
- x509OrgUnit_t *ou;
- while (orgUnit != NULL) {
- ou = orgUnit;
- orgUnit = ou->next;
- psFree(ou->name, allocPool);
- psFree(ou, allocPool);
- }
+ x509OrgUnit_t *ou;
+
+ while (orgUnit != NULL)
+ {
+ ou = orgUnit;
+ orgUnit = ou->next;
+ psFree(ou->name, allocPool);
+ psFree(ou, allocPool);
+ }
}
static void freeDomainComponentList(x509DomainComponent_t *domainComponent,
- psPool_t *allocPool)
+ psPool_t *allocPool)
{
- x509DomainComponent_t *dc;
- while (domainComponent != NULL) {
- dc = domainComponent;
- domainComponent = dc->next;
- psFree(dc->name, allocPool);
- psFree(dc, allocPool);
- }
+ x509DomainComponent_t *dc;
+
+ while (domainComponent != NULL)
+ {
+ dc = domainComponent;
+ domainComponent = dc->next;
+ psFree(dc->name, allocPool);
+ psFree(dc, allocPool);
+ }
}
void x509FreeExtensions(x509v3extensions_t *extensions)
{
- x509GeneralName_t *active, *inc;
-#if defined(USE_FULL_CERT_PARSE) || defined(USE_CERT_GEN)
- x509PolicyQualifierInfo_t *qual_info, *qual_info_inc;
- x509PolicyInformation_t *pol_info, *pol_info_inc;
- x509policyMappings_t *pol_map, *pol_map_inc;
- x509authorityInfoAccess_t *authInfo, *authInfoInc;
-#endif /* USE_FULL_CERT_PARSE || USE_CERT_GEN */
+ x509GeneralName_t *active, *inc;
- if (extensions == NULL) {
- return;
- }
- if (extensions->san) {
- active = extensions->san;
- while (active != NULL) {
- inc = active->next;
- psFree(active->data, extensions->pool);
- psFree(active, extensions->pool);
- active = inc;
- }
- }
-#if defined(USE_FULL_CERT_PARSE) || defined(USE_CERT_GEN)
- if (extensions->issuerAltName) {
- active = extensions->issuerAltName;
- while (active != NULL) {
- inc = active->next;
- psFree(active->data, extensions->pool);
- psFree(active, extensions->pool);
- active = inc;
- }
- }
+# if defined(USE_FULL_CERT_PARSE) || defined(USE_CERT_GEN)
+ x509PolicyQualifierInfo_t *qual_info, *qual_info_inc;
+ x509PolicyInformation_t *pol_info, *pol_info_inc;
+ x509policyMappings_t *pol_map, *pol_map_inc;
+ x509authorityInfoAccess_t *authInfo, *authInfoInc;
+# endif /* USE_FULL_CERT_PARSE || USE_CERT_GEN */
- if (extensions->authorityInfoAccess) {
- authInfo = extensions->authorityInfoAccess;
- while (authInfo != NULL) {
- authInfoInc = authInfo->next;
- psFree(authInfo->ocsp, extensions->pool);
- psFree(authInfo->caIssuers, extensions->pool);
- psFree(authInfo, extensions->pool);
- authInfo = authInfoInc;
- }
- }
-#endif /* USE_FULL_CERT_PARSE || USE_CERT_GEN */
+ if (extensions == NULL)
+ {
+ return;
+ }
+ if (extensions->san)
+ {
+ active = extensions->san;
+ while (active != NULL)
+ {
+ inc = active->next;
+ psFree(active->data, extensions->pool);
+ psFree(active, extensions->pool);
+ active = inc;
+ }
+ }
+# if defined(USE_FULL_CERT_PARSE) || defined(USE_CERT_GEN)
+ if (extensions->issuerAltName)
+ {
+ active = extensions->issuerAltName;
+ while (active != NULL)
+ {
+ inc = active->next;
+ psFree(active->data, extensions->pool);
+ psFree(active, extensions->pool);
+ active = inc;
+ }
+ }
-#ifdef USE_CRL
- if (extensions->crlNum) {
- psFree(extensions->crlNum, extensions->pool);
- }
- if (extensions->crlDist) {
- active = extensions->crlDist;
- while (active != NULL) {
- inc = active->next;
- psFree(active->data, extensions->pool);
- psFree(active, extensions->pool);
- active = inc;
- }
- }
-#endif /* CRL */
+ if (extensions->authorityInfoAccess)
+ {
+ authInfo = extensions->authorityInfoAccess;
+ while (authInfo != NULL)
+ {
+ authInfoInc = authInfo->next;
+ psFree(authInfo->ocsp, extensions->pool);
+ psFree(authInfo->caIssuers, extensions->pool);
+ psFree(authInfo, extensions->pool);
+ authInfo = authInfoInc;
+ }
+ }
+# endif /* USE_FULL_CERT_PARSE || USE_CERT_GEN */
-#ifdef USE_FULL_CERT_PARSE
- if (extensions->nameConstraints.excluded) {
- active = extensions->nameConstraints.excluded;
- while (active != NULL) {
- inc = active->next;
- psFree(active->data, extensions->pool);
- psFree(active, extensions->pool);
- active = inc;
- }
- }
- if (extensions->nameConstraints.permitted) {
- active = extensions->nameConstraints.permitted;
- while (active != NULL) {
- inc = active->next;
- psFree(active->data, extensions->pool);
- psFree(active, extensions->pool);
- active = inc;
- }
- }
-#endif /* USE_FULL_CERT_PARSE */
- if (extensions->sk.id) psFree(extensions->sk.id, extensions->pool);
- if (extensions->ak.keyId) psFree(extensions->ak.keyId, extensions->pool);
- if (extensions->ak.serialNum) psFree(extensions->ak.serialNum,
- extensions->pool);
- psX509FreeDNStruct(&extensions->ak.attribs, extensions->pool);
+# ifdef USE_CRL
+ if (extensions->crlNum)
+ {
+ psFree(extensions->crlNum, extensions->pool);
+ }
+ if (extensions->crlDist)
+ {
+ active = extensions->crlDist;
+ while (active != NULL)
+ {
+ inc = active->next;
+ psFree(active->data, extensions->pool);
+ psFree(active, extensions->pool);
+ active = inc;
+ }
+ }
+# endif /* CRL */
-#if defined(USE_FULL_CERT_PARSE) || defined(USE_CERT_GEN)
- pol_info = extensions->certificatePolicy.policy;
- while (pol_info != NULL) {
- /* Free PolicyInformation member variables. */
- pol_info_inc = pol_info->next;
- psFree(pol_info->policyOid, extensions->pool);
- qual_info = pol_info->qualifiers;
- while (qual_info != NULL) {
- /* Free QualifierInfo member variables. */
- qual_info_inc = qual_info->next;
- psFree(qual_info->cps, extensions->pool);
- psFree(qual_info->unoticeOrganization, extensions->pool);
- psFree(qual_info->unoticeExplicitText, extensions->pool);
- psFree(qual_info, extensions->pool);
- qual_info = qual_info_inc;
- }
- psFree(pol_info, extensions->pool);
- pol_info = pol_info_inc;
- }
+# ifdef USE_FULL_CERT_PARSE
+ if (extensions->nameConstraints.excluded)
+ {
+ active = extensions->nameConstraints.excluded;
+ while (active != NULL)
+ {
+ inc = active->next;
+ psFree(active->data, extensions->pool);
+ psFree(active, extensions->pool);
+ active = inc;
+ }
+ }
+ if (extensions->nameConstraints.permitted)
+ {
+ active = extensions->nameConstraints.permitted;
+ while (active != NULL)
+ {
+ inc = active->next;
+ psFree(active->data, extensions->pool);
+ psFree(active, extensions->pool);
+ active = inc;
+ }
+ }
+# endif /* USE_FULL_CERT_PARSE */
+ if (extensions->sk.id)
+ {
+ psFree(extensions->sk.id, extensions->pool);
+ }
+ if (extensions->ak.keyId)
+ {
+ psFree(extensions->ak.keyId, extensions->pool);
+ }
+ if (extensions->ak.serialNum)
+ {
+ psFree(extensions->ak.serialNum,
+ extensions->pool);
+ }
+ psX509FreeDNStruct(&extensions->ak.attribs, extensions->pool);
- pol_map = extensions->policyMappings;
- while (pol_map != NULL) {
- pol_map_inc = pol_map->next;
- psFree(pol_map->issuerDomainPolicy, extensions->pool);
- psFree(pol_map->subjectDomainPolicy, extensions->pool);
- psFree(pol_map, extensions->pool);
- pol_map = pol_map_inc;
- }
-#endif /* USE_FULL_CERT_PARSE || USE_CERT_GEN */
+# if defined(USE_FULL_CERT_PARSE) || defined(USE_CERT_GEN)
+ pol_info = extensions->certificatePolicy.policy;
+ while (pol_info != NULL)
+ {
+ /* Free PolicyInformation member variables. */
+ pol_info_inc = pol_info->next;
+ psFree(pol_info->policyOid, extensions->pool);
+ qual_info = pol_info->qualifiers;
+ while (qual_info != NULL)
+ {
+ /* Free QualifierInfo member variables. */
+ qual_info_inc = qual_info->next;
+ psFree(qual_info->cps, extensions->pool);
+ psFree(qual_info->unoticeOrganization, extensions->pool);
+ psFree(qual_info->unoticeExplicitText, extensions->pool);
+ psFree(qual_info, extensions->pool);
+ qual_info = qual_info_inc;
+ }
+ psFree(pol_info, extensions->pool);
+ pol_info = pol_info_inc;
+ }
+
+ pol_map = extensions->policyMappings;
+ while (pol_map != NULL)
+ {
+ pol_map_inc = pol_map->next;
+ psFree(pol_map->issuerDomainPolicy, extensions->pool);
+ psFree(pol_map->subjectDomainPolicy, extensions->pool);
+ psFree(pol_map, extensions->pool);
+ pol_map = pol_map_inc;
+ }
+
+ if (extensions->netscapeComment)
+ {
+ if (extensions->netscapeComment->comment)
+ {
+ psFree(extensions->netscapeComment->comment, pool);
+ }
+ psFree(extensions->netscapeComment, pool);
+ }
+# endif /* USE_FULL_CERT_PARSE || USE_CERT_GEN */
+}
+
+int32_t psX509GetNumOrganizationalUnits(const x509DNattributes_t *DN)
+{
+ x509OrgUnit_t *ou;
+ int32_t res = 0;
+
+ if (DN == NULL)
+ {
+ return PS_ARG_FAIL;
+ }
+
+ if (DN->orgUnit == NULL)
+ {
+ return 0;
+ }
+
+ res = 1;
+ ou = DN->orgUnit;
+ while (ou->next != NULL)
+ {
+ ou = ou->next;
+ res++;
+ }
+
+ return res;
+}
+
+x509OrgUnit_t *psX509GetOrganizationalUnit(const x509DNattributes_t *DN,
+ int32_t index)
+{
+ x509OrgUnit_t *ou;
+ int32_t i;
+
+ if (DN == NULL || DN->orgUnit == NULL || index < 0)
+ {
+ return NULL;
+ }
+
+ /*
+ Note: the OU list is in reverse order. The last item
+ (i.e the item with largest index) is at the list head.
+ */
+
+ i = psX509GetNumOrganizationalUnits(DN) - 1; /* Largest index. */
+ if (i < 0)
+ {
+ return NULL;
+ }
+
+ ou = DN->orgUnit;
+ if (i == index)
+ {
+ return ou;
+ }
+
+ while (ou->next != NULL)
+ {
+ ou = ou->next;
+ i--;
+ if (i < 0)
+ {
+ return NULL;
+ }
+ if (i == index)
+ {
+ return ou;
+ }
+ }
+
+ return NULL;
}
int32_t psX509GetNumDomainComponents(const x509DNattributes_t *DN)
{
- x509DomainComponent_t *dc;
- int32_t res = 0;
+ x509DomainComponent_t *dc;
+ int32_t res = 0;
- if (DN == NULL)
- return PS_ARG_FAIL;
+ if (DN == NULL)
+ {
+ return PS_ARG_FAIL;
+ }
- if (DN->domainComponent == NULL)
- return 0;
+ if (DN->domainComponent == NULL)
+ {
+ return 0;
+ }
- res = 1;
- dc = DN->domainComponent;
- while(dc->next != NULL) {
- dc = dc->next;
- res++;
- }
+ res = 1;
+ dc = DN->domainComponent;
+ while (dc->next != NULL)
+ {
+ dc = dc->next;
+ res++;
+ }
- return res;
+ return res;
}
-x509DomainComponent_t* psX509GetDomainComponent(const x509DNattributes_t *DN,
- int32_t index)
+x509DomainComponent_t *psX509GetDomainComponent(const x509DNattributes_t *DN,
+ int32_t index)
{
- x509DomainComponent_t *dc;
- int32_t i;
+ x509DomainComponent_t *dc;
+ int32_t i;
- if (DN == NULL || DN->domainComponent == NULL || index < 0)
- return NULL;
+ if (DN == NULL || DN->domainComponent == NULL || index < 0)
+ {
+ return NULL;
+ }
- /*
- Note: the DC list is in reverse order. The last item
- (i.e the item with largest index) is at the list head.
- */
+ /*
+ Note: the DC list is in reverse order. The last item
+ (i.e the item with largest index) is at the list head.
+ */
- i = psX509GetNumDomainComponents(DN) - 1; /* Largest index. */
- if (i < 0)
- return NULL;
+ i = psX509GetNumDomainComponents(DN) - 1; /* Largest index. */
+ if (i < 0)
+ {
+ return NULL;
+ }
- dc = DN->domainComponent;
- if (i == index)
- return dc;
+ dc = DN->domainComponent;
+ if (i == index)
+ {
+ return dc;
+ }
- while(dc->next != NULL) {
- dc = dc->next;
- i--;
- if (i < 0)
- return NULL;
- if (i == index)
- return dc;
- }
+ while (dc->next != NULL)
+ {
+ dc = dc->next;
+ i--;
+ if (i < 0)
+ {
+ return NULL;
+ }
+ if (i == index)
+ {
+ return dc;
+ }
+ }
- return NULL;
+ return NULL;
}
int32_t psX509GetConcatenatedDomainComponent(const x509DNattributes_t *DN,
- char **out_str,
- size_t *out_str_len)
+ char **out_str,
+ size_t *out_str_len)
{
- x509DomainComponent_t *dc;
- int32_t i = 0;
- uint16_t total_len = 0;
- int32_t num_dcs = 0;
- int32_t pos = 0;
+ x509DomainComponent_t *dc;
+ int32_t i = 0;
+ psSize_t total_len = 0;
+ int32_t num_dcs = 0;
+ int32_t pos = 0;
- if (DN == NULL || out_str == NULL)
- return PS_ARG_FAIL;
+ if (DN == NULL || out_str == NULL)
+ {
+ return PS_ARG_FAIL;
+ }
- num_dcs = psX509GetNumDomainComponents(DN);
- if (num_dcs == 0) {
- *out_str = NULL;
- *out_str_len = 0;
- return PS_SUCCESS;
- }
+ num_dcs = psX509GetNumDomainComponents(DN);
+ if (num_dcs == 0)
+ {
+ *out_str = NULL;
+ *out_str_len = 0;
+ return PS_SUCCESS;
+ }
- for (i = 0; i < num_dcs; i++) {
- dc = psX509GetDomainComponent(DN, i);
- if (dc == NULL)
- return PS_FAILURE;
- total_len += dc->len - DN_NUM_TERMINATING_NULLS;
- /* We will add a dot between the components. */
- if (i != (num_dcs - 1))
- total_len += 1;
- }
+ for (i = 0; i < num_dcs; i++)
+ {
+ dc = psX509GetDomainComponent(DN, i);
+ if (dc == NULL)
+ {
+ return PS_FAILURE;
+ }
+ total_len += dc->len - DN_NUM_TERMINATING_NULLS;
+ /* We will add a dot between the components. */
+ if (i != (num_dcs - 1))
+ {
+ total_len += 1;
+ }
+ }
- total_len += DN_NUM_TERMINATING_NULLS;
+ total_len += DN_NUM_TERMINATING_NULLS;
- *out_str = psMalloc(NULL, total_len);
- if (*out_str == NULL)
- return PS_MEM_FAIL;
- memset(*out_str, 0, total_len);
+ *out_str = psMalloc(NULL, total_len);
+ if (*out_str == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ memset(*out_str, 0, total_len);
- /* The top-level DC is usually listed first. So we start from the
- other end. */
- pos = 0;
- for (i = num_dcs - 1; i >= 0; i--) {
- dc = psX509GetDomainComponent(DN, i);
- if (dc == NULL) {
- psFree(*out_str, NULL);
- *out_str = NULL;
- return PS_FAILURE;
- }
- memcpy(*out_str + pos, dc->name,
- dc->len - DN_NUM_TERMINATING_NULLS);
- pos += dc->len - DN_NUM_TERMINATING_NULLS;
- if (i != 0) {
- (*out_str)[pos] = '.';
- pos++;
- }
- }
+ /* The top-level DC is usually listed first. So we start from the
+ other end. */
+ pos = 0;
+ for (i = num_dcs - 1; i >= 0; i--)
+ {
+ dc = psX509GetDomainComponent(DN, i);
+ if (dc == NULL)
+ {
+ psFree(*out_str, NULL);
+ *out_str = NULL;
+ return PS_FAILURE;
+ }
+ memcpy(*out_str + pos, dc->name,
+ dc->len - DN_NUM_TERMINATING_NULLS);
+ pos += dc->len - DN_NUM_TERMINATING_NULLS;
+ if (i != 0)
+ {
+ (*out_str)[pos] = '.';
+ pos++;
+ }
+ }
- if (pos != total_len - DN_NUM_TERMINATING_NULLS) {
- psFree(*out_str, NULL);
- *out_str = NULL;
- return PS_FAILURE;
- }
+ if (pos != total_len - DN_NUM_TERMINATING_NULLS)
+ {
+ psFree(*out_str, NULL);
+ *out_str = NULL;
+ return PS_FAILURE;
+ }
- *out_str_len = (size_t)total_len;
+ *out_str_len = (size_t) total_len;
- return PS_SUCCESS;
+ return PS_SUCCESS;
}
-#endif /* USE_CERT_PARSE */
+# endif /* USE_CERT_PARSE */
+# ifdef USE_FULL_CERT_PARSE
+/** Long, ugly function that concatenates all the DN components
+ to produce OpenSSL-style output.
+
+ This function aims to produce output identical
+ to X509_NAME_oneline(), which seems to be function used by
+ the openssl x509 utility to print out DNs.
+
+ The amount of code is rather large, so compile this only
+ when USE_FULL_CERT_PARSE is defined.
+
+ On success, the caller is responsible for freeing the
+ returned string.
+*/
+static int32_t concatenate_dn(psPool_t *pool,
+ const x509DNattributes_t *dn,
+ char **out_str,
+ size_t *out_str_len)
+{
+ size_t total_len = 0;
+ char *str, *p;
+ const char *country_prefix = "C=";
+ const char *state_prefix = "ST=";
+ const char *organization_prefix = "O=";
+ const char *organizationalUnit_prefix = "OU=";
+ const char *dnQualifier_prefix = "/dnQualifier=";
+ const char *commonName_prefix = "CN=";
+ const char *serialNumber_prefix = "/serialNumber=";
+ const char *domainComponent_prefix = "DC=";
+
+# ifdef USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
+ const char *locality_prefix = "L=";
+ const char *title_prefix = "/title=";
+ const char *surname_prefix = "SN=";
+ const char *givenName_prefix = "GN=";
+ const char *initials_prefix = "/initials=";
+ const char *pseudonym_prefix = "/pseudonym=";
+ const char *generationQualifier_prefix = "/generationQualifier=";
+# endif /* USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
+# ifdef USE_EXTRA_DN_ATTRIBUTES
+ const char *streetAddress_prefix = "/street=";
+ const char *postalAddress_prefix = "/postalAddress=";
+ const char *telephoneNumber_prefix = "/telephoneNumber=";
+ const char *uid_prefix = "/UID=";
+ const char *name_prefix = "/name=";
+ const char *email_prefix = "/emailAddress=";
+# endif /* USE_EXTRA_DN_ATTRIBUTES */
+ int num_dcs;
+ int first_len = 1;
+ int first_field = 1;
+ x509OrgUnit_t *orgUnit;
+ int num_ous;
+
+ psAssert(dn != NULL && out_str != NULL);
+
+# define INC_LEN(X) \
+ if (dn->X ## Len > 0) { \
+ if (!first_len && X ## _prefix[0] != '/') { \
+ total_len += 2; \
+ } \
+ first_len = 0; \
+ total_len += strlen(X ## _prefix) + \
+ dn->X ## Len - \
+ DN_NUM_TERMINATING_NULLS; \
+ }
+
+ INC_LEN(country);
+ INC_LEN(state);
+ INC_LEN(organization);
+ num_ous = psX509GetNumOrganizationalUnits(dn);
+ if (num_ous > 0)
+ {
+ int i;
+ for (i = 0; i < num_ous; i++)
+ {
+ orgUnit = psX509GetOrganizationalUnit(dn, i);
+ if (orgUnit == NULL)
+ {
+ return PS_FAILURE;
+ }
+ if (first_len)
+ {
+ first_len = 0;
+ }
+ else
+ {
+ total_len += 2;
+ }
+ total_len += strlen(organizationalUnit_prefix);
+ total_len += orgUnit->len - DN_NUM_TERMINATING_NULLS;
+ }
+ }
+ INC_LEN(dnQualifier);
+ INC_LEN(commonName);
+ INC_LEN(serialNumber);
+
+# ifdef USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
+ INC_LEN(locality);
+ INC_LEN(title);
+ INC_LEN(surname);
+ INC_LEN(givenName);
+ INC_LEN(initials);
+ INC_LEN(pseudonym);
+ INC_LEN(generationQualifier);
+# endif /* USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
+
+# ifdef USE_EXTRA_DN_ATTRIBUTES
+ INC_LEN(streetAddress);
+ INC_LEN(postalAddress);
+ INC_LEN(telephoneNumber);
+ INC_LEN(uid);
+ INC_LEN(name);
+ INC_LEN(email);
+# endif /* USE_EXTRA_DN_ATTRIBUTES */
+ num_dcs = psX509GetNumDomainComponents(dn);
+ if (num_dcs > 0)
+ {
+ int i;
+ x509DomainComponent_t *dc;
+
+ for (i = 0; i < num_dcs; i++)
+ {
+ total_len += strlen(domainComponent_prefix);
+ if (first_len)
+ {
+ first_len = 0;
+ }
+ else
+ {
+ total_len += 2;
+ }
+ dc = psX509GetDomainComponent(dn, i);
+ if (dc == NULL)
+ {
+ return PS_FAILURE;
+ }
+ total_len += dc->len - DN_NUM_TERMINATING_NULLS;
+ }
+ }
+
+ /*
+ Sanity check.*/
+ if (total_len > 100000)
+ {
+ return PS_ARG_FAIL;
+ }
+
+ str = psMalloc(pool, total_len + 1);
+ if (str == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ memset(str, 0, total_len + 1);
+
+ p = str;
+
+ /*
+ We are going to imitate the OpenSSL output format.
+ For common fields such as country (C) or state (ST), there is
+ a 1-2 letter ID and the printout is e.g. "ST=[value]".
+ For other fields, the prefix is "/field_name=[value]".
+ Note that there is comma and a space ", " before fields with
+ a 1-2 letter ID, but not before the "/field_name=" fields.
+ Example:
+
+ C=US, ST=Test State or Province, L=Test Locality, O=Organization Name,
+ OU=First Organizational Unit Name, OU=Second Organizational Unit
+ Name, OU=Third Organizational Unit Name, CN=Common Name
+ /name=GivenName Surname, GN=Givenname, SN=Surname, DC=com,
+ DC=insidesecure,
+ DC=test/emailAddress=test@email.address/serialNumber=012bf123aa
+ /street=MyStreetAddress99/title=Dr./postalAddress=12345
+ /telephoneNumber=1111-2222-3333/pseudonym=myPseudonym
+ /generationQualifier=III/initials=G.S.
+ /dnQualifier=123456789/UID=root
+ */
+
+# define PRINT_FIELD(field) \
+ if (dn->field ## Len > 0) { \
+ if (first_field) { \
+ first_field = 0; \
+ } else { \
+ if (field ## _prefix[0] != '/') { \
+ *p++ = ','; \
+ *p++ = ' '; \
+ } \
+ } \
+ memcpy(p, field ## _prefix, strlen(field ## _prefix)); \
+ p += strlen(field ## _prefix); \
+ memcpy(p, dn->field, \
+ dn->field ## Len - DN_NUM_TERMINATING_NULLS); \
+ p += dn->field ## Len - DN_NUM_TERMINATING_NULLS; \
+ }
+
+ /*
+ The ifdefs are a bit messy, because we wish to use the same
+ print order as OpenSSL. MatrixSSL divides the fields
+ into ifdef-wrapped groups differently.
+ */
+ PRINT_FIELD(country);
+ PRINT_FIELD(state);
+# ifdef USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
+ PRINT_FIELD(locality);
+# endif /* USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
+ PRINT_FIELD(organization);
+ num_ous = psX509GetNumOrganizationalUnits(dn);
+ if (num_ous > 0)
+ {
+ int i;
+ for (i = 0; i < num_ous; i++)
+ {
+ orgUnit = psX509GetOrganizationalUnit(dn, i);
+ if (orgUnit == NULL)
+ {
+ psFree(str, pool);
+ return PS_FAILURE;
+ }
+ if (first_field)
+ {
+ first_field = 0;
+ }
+ else
+ {
+ *p++ = ',';
+ } *p++ = ' ';
+ memcpy(p, organizationalUnit_prefix,
+ strlen(organizationalUnit_prefix));
+ p += strlen(organizationalUnit_prefix);
+ memcpy(p, orgUnit->name, orgUnit->len - DN_NUM_TERMINATING_NULLS);
+ p += orgUnit->len - DN_NUM_TERMINATING_NULLS;
+ }
+ }
+ PRINT_FIELD(commonName);
+# ifdef USE_EXTRA_DN_ATTRIBUTES
+ PRINT_FIELD(name);
+# endif /* USE_EXTRA_DN_ATTRIBUTES */
+# ifdef USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
+ PRINT_FIELD(givenName);
+ PRINT_FIELD(surname);
+# endif /* USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
+# ifdef USE_EXTRA_DN_ATTRIBUTES
+ /**/
+ num_dcs = psX509GetNumDomainComponents(dn);
+ if (num_dcs > 0)
+ {
+ int i;
+ x509DomainComponent_t *dc;
+
+ for (i = 0; i < num_dcs; i++)
+ {
+ if (first_field)
+ {
+ first_field = 0;
+ }
+ else
+ {
+ *p++ = ',';
+ } *p++ = ' ';
+ memcpy(p, domainComponent_prefix,
+ strlen(domainComponent_prefix));
+ p += strlen(domainComponent_prefix);
+ dc = psX509GetDomainComponent(dn, i);
+ if (dc == NULL)
+ {
+ psFree(str, pool);
+ return PS_FAILURE;
+ }
+ memcpy(p, dc->name, dc->len - DN_NUM_TERMINATING_NULLS);
+ p += dc->len - DN_NUM_TERMINATING_NULLS;
+ }
+ }
+ PRINT_FIELD(email);
+# endif /* USE_EXTRA_DN_ATTRIBUTES */
+ PRINT_FIELD(serialNumber);
+# ifdef USE_EXTRA_DN_ATTRIBUTES
+ PRINT_FIELD(streetAddress);
+# endif /* USE_EXTRA_DN_ATTRIBUTES */
+# ifdef USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
+ PRINT_FIELD(title);
+# endif /* USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
+# ifdef USE_EXTRA_DN_ATTRIBUTES
+ PRINT_FIELD(postalAddress);
+ PRINT_FIELD(telephoneNumber);
+# endif /* USE_EXTRA_DN_ATTRIBUTES */
+# ifdef USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
+ PRINT_FIELD(pseudonym);
+ PRINT_FIELD(generationQualifier);
+ PRINT_FIELD(initials);
+# endif /* USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
+ PRINT_FIELD(dnQualifier);
+# ifdef USE_EXTRA_DN_ATTRIBUTES
+ PRINT_FIELD(uid);
+# endif /* USE_EXTRA_DN_ATTRIBUTES */
+
+ psAssert(total_len == (p - str));
+
+ *p++ = '\0';
+ *out_str = str;
+ *out_str_len = total_len;
+
+ return PS_SUCCESS;
+}
+
+int32_t psX509GetOnelineDN(const x509DNattributes_t *DN,
+ char **out_str,
+ size_t *out_str_len)
+{
+ return concatenate_dn(NULL, DN, out_str, out_str_len);
+}
+
+# endif /* USE_FULL_CERT_PARSE */
/******************************************************************************/
/*
- User must call after all calls to psX509ParseCert
- (we violate the coding standard a bit here for clarity)
-*/
+ User must call after all calls to psX509ParseCert
+ (we violate the coding standard a bit here for clarity)
+ */
void psX509FreeCert(psX509Cert_t *cert)
{
- psX509Cert_t *curr, *next;
- psPool_t *pool;
+ psX509Cert_t *curr, *next;
+ psPool_t *pool;
- curr = cert;
- while (curr) {
- pool = curr->pool;
- if (curr->unparsedBin) psFree(curr->unparsedBin, pool);
-#ifdef USE_CERT_PARSE
- psX509FreeDNStruct(&curr->issuer, pool);
- psX509FreeDNStruct(&curr->subject, pool);
- if (curr->serialNumber) psFree(curr->serialNumber, pool);
- if (curr->notBefore) psFree(curr->notBefore, pool);
- if (curr->notAfter) psFree(curr->notAfter, pool);
- if (curr->signature) psFree(curr->signature, pool);
- if (curr->uniqueIssuerId) psFree(curr->uniqueIssuerId, pool);
- if (curr->uniqueSubjectId) psFree(curr->uniqueSubjectId, pool);
+ curr = cert;
+ while (curr)
+ {
+ pool = curr->pool;
+ if (curr->unparsedBin)
+ {
+ psFree(curr->unparsedBin, pool);
+ }
+# ifdef USE_CERT_PARSE
+ psX509FreeDNStruct(&curr->issuer, pool);
+ psX509FreeDNStruct(&curr->subject, pool);
+ if (curr->serialNumber)
+ {
+ psFree(curr->serialNumber, pool);
+ }
+ if (curr->notBefore)
+ {
+ psFree(curr->notBefore, pool);
+ }
+ if (curr->notAfter)
+ {
+ psFree(curr->notAfter, pool);
+ }
+ if (curr->signature)
+ {
+ psFree(curr->signature, pool);
+ }
+ if (curr->uniqueIssuerId)
+ {
+ psFree(curr->uniqueIssuerId, pool);
+ }
+ if (curr->uniqueSubjectId)
+ {
+ psFree(curr->uniqueSubjectId, pool);
+ }
- if (curr->publicKey.type != PS_NOKEY) {
- switch (curr->pubKeyAlgorithm) {
-#ifdef USE_RSA
- case OID_RSA_KEY_ALG:
- psRsaClearKey(&curr->publicKey.key.rsa);
- break;
-#endif
+ if (curr->publicKey.type != PS_NOKEY)
+ {
+ switch (curr->pubKeyAlgorithm)
+ {
+# ifdef USE_RSA
+ case OID_RSA_KEY_ALG:
+ psRsaClearKey(&curr->publicKey.key.rsa);
+ break;
+# endif
-#ifdef USE_ECC
- case OID_ECDSA_KEY_ALG:
- psEccClearKey(&curr->publicKey.key.ecc);
- break;
-#endif
- default:
- psAssert(0);
- break;
- }
- curr->publicKey.type = PS_NOKEY;
- }
+# ifdef USE_ECC
+ case OID_ECDSA_KEY_ALG:
+ psEccClearKey(&curr->publicKey.key.ecc);
+ break;
+# endif
- x509FreeExtensions(&curr->extensions);
-#endif /* USE_CERT_PARSE */
- next = curr->next;
- psFree(curr, pool);
- curr = next;
- }
+ default:
+ psAssert(0);
+ break;
+ }
+ curr->publicKey.type = PS_NOKEY;
+ }
+
+ x509FreeExtensions(&curr->extensions);
+# endif /* USE_CERT_PARSE */
+ next = curr->next;
+ psFree(curr, pool);
+ curr = next;
+ }
}
/******************************************************************************/
/*
- Currently just returning the raw BIT STRING and size in bytes
-*/
-#define MIN_HASH_SIZE 16
-int32_t psX509GetSignature(psPool_t *pool, const unsigned char **pp, uint16_t len,
- unsigned char **sig, uint16_t *sigLen)
+ Currently just returning the raw BIT STRING and size in bytes
+ */
+# define MIN_HASH_SIZE 16
+int32_t psX509GetSignature(psPool_t *pool, const unsigned char **pp, psSize_t len,
+ unsigned char **sig, psSize_t *sigLen)
{
- const unsigned char *p = *pp, *end;
- uint16_t llen;
+ const unsigned char *p = *pp, *end;
+ psSize_t llen;
- end = p + len;
- if (len < 1 || (*(p++) != ASN_BIT_STRING) ||
- getAsnLength(&p, len - 1, &llen) < 0 ||
- (uint32)(end - p) < llen ||
- llen < (1 + MIN_HASH_SIZE)) {
+ end = p + len;
+ if (len < 1 || (*(p++) != ASN_BIT_STRING) ||
+ getAsnLength(&p, len - 1, &llen) < 0 ||
+ (uint32) (end - p) < llen ||
+ llen < (1 + MIN_HASH_SIZE))
+ {
- psTraceCrypto("Initial parse error in getSignature\n");
- return PS_PARSE_FAIL;
- }
- /* We assume this ignore_bits byte is always 0. */
- psAssert(*p == 0);
- p++;
- /* Length was including the ignore_bits byte, subtract it */
- *sigLen = llen - 1;
- *sig = psMalloc(pool, *sigLen);
- if (*sig == NULL) {
- psError("Memory allocation error in getSignature\n");
- return PS_MEM_FAIL;
- }
- memcpy(*sig, p, *sigLen);
- *pp = p + *sigLen;
- return PS_SUCCESS;
+ psTraceCrypto("Initial parse error in getSignature\n");
+ return PS_PARSE_FAIL;
+ }
+ /* We assume this ignore_bits byte is always 0. */
+ psAssert(*p == 0);
+ p++;
+ /* Length was including the ignore_bits byte, subtract it */
+ *sigLen = llen - 1;
+ *sig = psMalloc(pool, *sigLen);
+ if (*sig == NULL)
+ {
+ psError("Memory allocation error in getSignature\n");
+ return PS_MEM_FAIL;
+ }
+ memcpy(*sig, p, *sigLen);
+ *pp = p + *sigLen;
+ return PS_SUCCESS;
}
-#ifdef USE_CERT_PARSE
+# ifdef USE_CERT_PARSE
/******************************************************************************/
/*
- Validate the expected name against a subset of the GeneralName rules
- for DNS, Email and IP types.
- We assume the expected name is not maliciously entered. If it is, it may
- match an invalid GeneralName in a remote cert chain.
- Returns 0 on valid format, PS_FAILURE on invalid format of GeneralName
-*/
+ Validate the expected name against a subset of the GeneralName rules
+ for DNS, Email and IP types.
+ We assume the expected name is not maliciously entered. If it is, it may
+ match an invalid GeneralName in a remote cert chain.
+ Returns 0 on valid format, PS_FAILURE on invalid format of GeneralName
+ */
int32_t psX509ValidateGeneralName(const char *n)
{
- const char *c;
- int atfound; /* Ampersand found */
- int notip; /* Not an ip address */
+ const char *c;
+ int atfound; /* Ampersand found */
+ int notip; /* Not an ip address */
- if (n == NULL) return 0;
+ if (n == NULL)
+ {
+ return 0;
+ }
- /* Must be at least one character */
- if (*n == '\0') return PS_FAILURE;
+ /* Must be at least one character */
+ if (*n == '\0')
+ {
+ return PS_FAILURE;
+ }
- atfound = notip = 0;
- for (c = n; *c != '\0'; c++ ) {
+ atfound = notip = 0;
+ for (c = n; *c != '\0'; c++ )
+ {
- /* Negative tests first in the loop */
- /* Can't have any combination of . and - and @ together */
- if (c != n) {
- if (*c == '.' && *(c-1) == '.') return PS_FAILURE;
- if (*c == '.' && *(c-1) == '-') return PS_FAILURE;
- if (*c == '.' && *(c-1) == '@') return PS_FAILURE;
- if (*c == '-' && *(c-1) == '.') return PS_FAILURE;
- if (*c == '-' && *(c-1) == '-') return PS_FAILURE;
- if (*c == '-' && *(c-1) == '@') return PS_FAILURE;
- if (*c == '@' && *(c-1) == '.') return PS_FAILURE;
- if (*c == '@' && *(c-1) == '-') return PS_FAILURE;
- if (*c == '@' && *(c-1) == '@') return PS_FAILURE;
- }
+ /* Negative tests first in the loop */
+ /* Can't have any combination of . and - and @ together */
+ if (c != n)
+ {
+ if (*c == '.' && *(c - 1) == '.')
+ {
+ return PS_FAILURE;
+ }
+ if (*c == '.' && *(c - 1) == '-')
+ {
+ return PS_FAILURE;
+ }
+ if (*c == '.' && *(c - 1) == '@')
+ {
+ return PS_FAILURE;
+ }
+ if (*c == '-' && *(c - 1) == '.')
+ {
+ return PS_FAILURE;
+ }
+ if (*c == '-' && *(c - 1) == '-')
+ {
+ return PS_FAILURE;
+ }
+ if (*c == '-' && *(c - 1) == '@')
+ {
+ return PS_FAILURE;
+ }
+ if (*c == '@' && *(c - 1) == '.')
+ {
+ return PS_FAILURE;
+ }
+ if (*c == '@' && *(c - 1) == '-')
+ {
+ return PS_FAILURE;
+ }
+ if (*c == '@' && *(c - 1) == '@')
+ {
+ return PS_FAILURE;
+ }
+ }
- /* Note whether we have hit a non numeric name */
- if (*c != '.' && (*c < '0' || *c > '9')) notip++;
+ /* Note whether we have hit a non numeric name */
+ if (*c != '.' && (*c < '0' || *c > '9'))
+ {
+ notip++;
+ }
- /* Now positive tests */
- /* Cannot start or end with . or -, but can contain them */
- if (c != n && *(c + 1) != '\0' && (*c == '.' || *c == '-')) continue;
- /* Can contain at most one @ , and not at the start or end */
- if (*c == '@') {
- atfound++;
- if (c != n && *(c + 1) != '\0' && atfound == 1) {
- continue;
- }
- }
- /* Numbers allowed generally */
- if (*c >= '0' && *c <= '9') continue;
- /* Upper and lowercase characters allowed */
- if (*c >= 'A' && *c <= 'Z') continue;
- if (*c >= 'a' && *c <= 'z') continue;
+ /* Now positive tests */
+ /* Cannot start or end with . or -, but can contain them */
+ if (c != n && *(c + 1) != '\0' && (*c == '.' || *c == '-'))
+ {
+ continue;
+ }
+ /* Can contain at most one @ , and not at the start or end */
+ if (*c == '@')
+ {
+ atfound++;
+ if (c != n && *(c + 1) != '\0' && atfound == 1)
+ {
+ continue;
+ }
+ }
+ /* Numbers allowed generally */
+ if (*c >= '0' && *c <= '9')
+ {
+ continue;
+ }
+ /* Upper and lowercase characters allowed */
+ if (*c >= 'A' && *c <= 'Z')
+ {
+ continue;
+ }
+ if (*c >= 'a' && *c <= 'z')
+ {
+ continue;
+ }
- /* Everything else is a failure */
- return PS_FAILURE;
- }
- /* RFC 1034 states if it's not an IP, it can't start with a number,
- However, RFC 1123 updates this and does allow a number as the
- first character of a DNS name.
- See the X.509 RFC: http://tools.ietf.org/html/rfc5280#section-4.2.1.6 */
- if (atfound && (*n >= '0' && *n <= '9')) return PS_FAILURE;
+ /* Everything else is a failure */
+ return PS_FAILURE;
+ }
+ /* RFC 1034 states if it's not an IP, it can't start with a number,
+ However, RFC 1123 updates this and does allow a number as the
+ first character of a DNS name.
+ See the X.509 RFC: http://tools.ietf.org/html/rfc5280#section-4.2.1.6 */
+ if (atfound && (*n >= '0' && *n <= '9'))
+ {
+ return PS_FAILURE;
+ }
- /* We could at this point store whether it is a DNS, Email or IP */
+ /* We could at this point store whether it is a DNS, Email or IP */
- return 0;
+ return 0;
}
/******************************************************************************/
/*
- Parses a sequence of GeneralName types*/
+ Parses a sequence of GeneralName types*/
static int32_t parseGeneralNames(psPool_t *pool, const unsigned char **buf,
- uint16_t len, const unsigned char *extEnd,
- x509GeneralName_t **name, int16_t limit)
+ psSize_t len, const unsigned char *extEnd,
+ x509GeneralName_t **name, int16_t limit)
{
- uint16_t otherNameLen;
- const unsigned char *p, *c, *save, *end;
- x509GeneralName_t *activeName, *firstName, *prevName;
+ psSize_t otherNameLen;
+ const unsigned char *p, *c, *save, *end;
+ x509GeneralName_t *activeName, *firstName, *prevName;
- if (*name == NULL) {
- firstName = NULL;
- } else {
- firstName = *name;
- }
- p = *buf;
- end = p + len;
+ if (*name == NULL)
+ {
+ firstName = NULL;
+ }
+ else
+ {
+ firstName = *name;
+ }
+ p = *buf;
+ end = p + len;
- while (len > 0) {
- if (firstName == NULL) {
- activeName = firstName = psMalloc(pool, sizeof(x509GeneralName_t));
- if (activeName == NULL) {
- return PS_MEM_FAIL;
- }
- memset(firstName, 0x0, sizeof(x509GeneralName_t));
- firstName->pool = pool;
- *name = firstName;
- } else {
+ while (len > 0)
+ {
+ if (firstName == NULL)
+ {
+ activeName = firstName = psMalloc(pool, sizeof(x509GeneralName_t));
+ if (activeName == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ memset(firstName, 0x0, sizeof(x509GeneralName_t));
+ firstName->pool = pool;
+ *name = firstName;
+ }
+ else
+ {
/*
- Find the end
-*/
- prevName = firstName;
- activeName = firstName->next;
- while (activeName != NULL) {
- prevName = activeName;
- activeName = activeName->next;
- }
- prevName->next = psMalloc(pool, sizeof(x509GeneralName_t));
- if (prevName->next == NULL) {
- return PS_MEM_FAIL;
- }
- activeName = prevName->next;
- memset(activeName, 0x0, sizeof(x509GeneralName_t));
- activeName->pool = pool;
- }
- activeName->id = *p & 0xF;
- p++; len--;
- switch (activeName->id) {
- case GN_OTHER:
- strncpy((char *)activeName->name, "other",
- sizeof(activeName->name) - 1);
- /* OtherName ::= SEQUENCE {
- type-id OBJECT IDENTIFIER,
- value [0] EXPLICIT ANY DEFINED BY type-id }
- */
- save = p;
- if (getAsnLength(&p, (uint32)(extEnd - p), &otherNameLen) < 0 ||
- otherNameLen < 1 ||
- (uint32)(extEnd - p) < otherNameLen) {
- psTraceCrypto("ASN parse error SAN otherName\n");
- return PS_PARSE_FAIL;
- }
- if (*(p++) != ASN_OID
- || getAsnLength(&p, (int32)(extEnd - p), &activeName->oidLen) < 0
- || (uint32)(extEnd - p) < activeName->oidLen
- || activeName->oidLen > sizeof(activeName->oid)) {
+ Find the end
+ */
+ prevName = firstName;
+ activeName = firstName->next;
+ while (activeName != NULL)
+ {
+ prevName = activeName;
+ activeName = activeName->next;
+ }
+ prevName->next = psMalloc(pool, sizeof(x509GeneralName_t));
+ if (prevName->next == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ activeName = prevName->next;
+ memset(activeName, 0x0, sizeof(x509GeneralName_t));
+ activeName->pool = pool;
+ }
+ activeName->id = *p & 0xF;
+ p++; len--;
+ switch (activeName->id)
+ {
+ case GN_OTHER:
+ strncpy((char *) activeName->name, "other",
+ sizeof(activeName->name) - 1);
+ /* OtherName ::= SEQUENCE {
+ type-id OBJECT IDENTIFIER,
+ value [0] EXPLICIT ANY DEFINED BY type-id }
+ */
+ save = p;
+ if (getAsnLength(&p, (uint32) (extEnd - p), &otherNameLen) < 0 ||
+ otherNameLen < 1 ||
+ (uint32) (extEnd - p) < otherNameLen)
+ {
+ psTraceCrypto("ASN parse error SAN otherName\n");
+ return PS_PARSE_FAIL;
+ }
+ if (*(p++) != ASN_OID
+ || getAsnLength(&p, (int32) (extEnd - p), &activeName->oidLen) < 0
+ || (uint32) (extEnd - p) < activeName->oidLen
+ || activeName->oidLen > sizeof(activeName->oid))
+ {
- psTraceCrypto("ASN parse error SAN otherName oid\n");
- return -1;
- }
- /* Note activeName->oidLen could be zero here */
- memcpy(activeName->oid, p, activeName->oidLen);
- p += activeName->oidLen;
- /* value looks like
- 0xA0, , , ,
- We're supporting only string-type TYPE so just skipping it
- */
- if ((uint32)(extEnd - p) < 1 || *p != 0xA0) {
- psTraceCrypto("ASN parse error SAN otherName\n");
- return PS_PARSE_FAIL;
- }
- p++; /* Jump over A0 */
- if (getAsnLength(&p, (uint32)(extEnd - p), &otherNameLen) < 0 ||
- otherNameLen < 1 ||
- (uint32)(extEnd - p) < otherNameLen) {
- psTraceCrypto("ASN parse error SAN otherName value\n");
- return PS_PARSE_FAIL;
- }
- if ((uint32)(extEnd - p) < 1) {
- psTraceCrypto("ASN parse error SAN otherName len\n");
- return PS_PARSE_FAIL;
- }
- /* TODO - validate *p == STRING type? */
- p++; /* Jump over TYPE */
- len -= (p - save);
- break;
- case GN_EMAIL:
- strncpy((char *)activeName->name, "email",
- sizeof(activeName->name) - 1);
- break;
- case GN_DNS:
- strncpy((char *)activeName->name, "DNS",
- sizeof(activeName->name) - 1);
- break;
- case GN_X400:
- strncpy((char *)activeName->name, "x400Address",
- sizeof(activeName->name) - 1);
- break;
- case GN_DIR:
- strncpy((char *)activeName->name, "directoryName",
- sizeof(activeName->name) - 1);
- break;
- case GN_EDI:
- strncpy((char *)activeName->name, "ediPartyName",
- sizeof(activeName->name) - 1);
- break;
- case GN_URI:
- strncpy((char *)activeName->name, "URI",
- sizeof(activeName->name) - 1);
- break;
- case GN_IP:
- strncpy((char *)activeName->name, "iPAddress",
- sizeof(activeName->name) - 1);
- break;
- case GN_REGID:
- strncpy((char *)activeName->name, "registeredID",
- sizeof(activeName->name) - 1);
- break;
- default:
- strncpy((char *)activeName->name, "unknown",
- sizeof(activeName->name) - 1);
- break;
- }
+ psTraceCrypto("ASN parse error SAN otherName oid\n");
+ return -1;
+ }
+ /* Note activeName->oidLen could be zero here */
+ memcpy(activeName->oid, p, activeName->oidLen);
+ p += activeName->oidLen;
+ /* value looks like
+ 0xA0, , , ,
+ We're supporting only string-type TYPE so just skipping it
+ */
+ if ((uint32) (extEnd - p) < 1 || *p != 0xA0)
+ {
+ psTraceCrypto("ASN parse error SAN otherName\n");
+ return PS_PARSE_FAIL;
+ }
+ p++; /* Jump over A0 */
+ if (getAsnLength(&p, (uint32) (extEnd - p), &otherNameLen) < 0 ||
+ otherNameLen < 1 ||
+ (uint32) (extEnd - p) < otherNameLen)
+ {
+ psTraceCrypto("ASN parse error SAN otherName value\n");
+ return PS_PARSE_FAIL;
+ }
+ if ((uint32) (extEnd - p) < 1)
+ {
+ psTraceCrypto("ASN parse error SAN otherName len\n");
+ return PS_PARSE_FAIL;
+ }
+ /* TODO - validate *p == STRING type? */
+ p++; /* Jump over TYPE */
+ len -= (p - save);
+ break;
+ case GN_EMAIL:
+ strncpy((char *) activeName->name, "email",
+ sizeof(activeName->name) - 1);
+ break;
+ case GN_DNS:
+ strncpy((char *) activeName->name, "DNS",
+ sizeof(activeName->name) - 1);
+ break;
+ case GN_X400:
+ strncpy((char *) activeName->name, "x400Address",
+ sizeof(activeName->name) - 1);
+ break;
+ case GN_DIR:
+ strncpy((char *) activeName->name, "directoryName",
+ sizeof(activeName->name) - 1);
+ break;
+ case GN_EDI:
+ strncpy((char *) activeName->name, "ediPartyName",
+ sizeof(activeName->name) - 1);
+ break;
+ case GN_URI:
+ strncpy((char *) activeName->name, "URI",
+ sizeof(activeName->name) - 1);
+ break;
+ case GN_IP:
+ strncpy((char *) activeName->name, "iPAddress",
+ sizeof(activeName->name) - 1);
+ break;
+ case GN_REGID:
+ strncpy((char *) activeName->name, "registeredID",
+ sizeof(activeName->name) - 1);
+ break;
+ default:
+ strncpy((char *) activeName->name, "unknown",
+ sizeof(activeName->name) - 1);
+ break;
+ }
- save = p;
- if (getAsnLength(&p, (uint32)(extEnd - p), &activeName->dataLen) < 0 ||
- activeName->dataLen < 1 ||
- (uint32)(extEnd - p) < activeName->dataLen) {
- psTraceCrypto("ASN len error in parseGeneralNames\n");
- return PS_PARSE_FAIL;
- }
- len -= (p - save);
- if (len < activeName->dataLen) {
- psTraceCrypto("ASN len error in parseGeneralNames\n");
- return PS_PARSE_FAIL;
- }
+ save = p;
+ if (getAsnLength(&p, (uint32) (extEnd - p), &activeName->dataLen) < 0 ||
+ activeName->dataLen < 1 ||
+ (uint32) (extEnd - p) < activeName->dataLen)
+ {
+ psTraceCrypto("ASN len error in parseGeneralNames\n");
+ return PS_PARSE_FAIL;
+ }
+ len -= (p - save);
+ if (len < activeName->dataLen)
+ {
+ psTraceCrypto("ASN len error in parseGeneralNames\n");
+ return PS_PARSE_FAIL;
+ }
- /* Currently we validate that the IA5String fields are printable
- At a minimum, this prevents attacks with null terminators or
- invisible characters in the certificate.
- Additional validation of name format is done indirectly
- via byte comparison to the expected name in ValidateGeneralName
- or directly by the user in the certificate callback */
- switch (activeName->id) {
- case GN_EMAIL:
- case GN_DNS:
- case GN_URI:
- save = p + activeName->dataLen;
- for (c = p; c < save; c++) {
- if (*c < ' ' || *c > '~') {
- psTraceCrypto("ASN invalid GeneralName character\n");
- return PS_PARSE_FAIL;
- }
- }
- break;
- case GN_IP:
- if (activeName->dataLen < 4) {
- psTraceCrypto("Unknown GN_IP format\n");
- return PS_PARSE_FAIL;
- }
- break;
- default:
- break;
- }
+ /* Currently we validate that the IA5String fields are printable
+ At a minimum, this prevents attacks with null terminators or
+ invisible characters in the certificate.
+ Additional validation of name format is done indirectly
+ via byte comparison to the expected name in ValidateGeneralName
+ or directly by the user in the certificate callback */
+ switch (activeName->id)
+ {
+ case GN_EMAIL:
+ case GN_DNS:
+ case GN_URI:
+ save = p + activeName->dataLen;
+ for (c = p; c < save; c++)
+ {
+ if (*c < ' ' || *c > '~')
+ {
+ psTraceCrypto("ASN invalid GeneralName character\n");
+ return PS_PARSE_FAIL;
+ }
+ }
+ break;
+ case GN_IP:
+ if (activeName->dataLen < 4)
+ {
+ psTraceCrypto("Unknown GN_IP format\n");
+ return PS_PARSE_FAIL;
+ }
+ break;
+ default:
+ break;
+ }
- activeName->data = psMalloc(pool, activeName->dataLen + 1);
- if (activeName->data == NULL) {
- psError("Memory allocation error: activeName->data\n");
- return PS_MEM_FAIL;
- }
- /* This guarantees data is null terminated, even for non IA5Strings */
- memset(activeName->data, 0x0, activeName->dataLen + 1);
- memcpy(activeName->data, p, activeName->dataLen);
+ activeName->data = psMalloc(pool, activeName->dataLen + 1);
+ if (activeName->data == NULL)
+ {
+ psError("Memory allocation error: activeName->data\n");
+ return PS_MEM_FAIL;
+ }
+ /* This guarantees data is null terminated, even for non IA5Strings */
+ memset(activeName->data, 0x0, activeName->dataLen + 1);
+ memcpy(activeName->data, p, activeName->dataLen);
- p = p + activeName->dataLen;
- len -= activeName->dataLen;
-
- if (limit > 0) {
- if (--limit == 0) {
- *buf = end;
- return PS_SUCCESS;
- }
- }
- }
- *buf = p;
- return PS_SUCCESS;
-}
+ p = p + activeName->dataLen;
+ len -= activeName->dataLen;
-/******************************************************************************/
-/**
- Parse ASN.1 DER encoded OBJECT bytes into an OID array.
- @param[in] der Pointer to start of OBJECT encoding.
- @param[in] derlen Number of bytes pointed to by 'der'.
- @param[out] oid Caller allocated array to receive OID, of
- at least MAX_OID_LEN elements.
- @return Number of OID elements written to 'oid', 0 on error.
-*/
-static uint8_t psParseOid(const unsigned char *der, uint16_t derlen,
- uint32_t oid[MAX_OID_LEN])
-{
- const unsigned char *end;
- uint8_t n, sanity;
-
- if (derlen < 1) {
- return 0;
- }
- end = der + derlen;
- /* First two OID elements are single octet, base 40 for some reason */
- oid[0] = *der / 40;
- oid[1] = *der % 40;
- der++;
- /* Zero the remainder of OID and leave n == 2 */
- for (n = MAX_OID_LEN - 1; n > 2; n--) {
- oid[n] = 0;
- }
- while (der < end && n < MAX_OID_LEN) {
- /* If the high bit is 0, it's short form variable length quantity */
- if (!(*der & 0x80)) {
- oid[n++] = *der++;
- } else {
- sanity = 0;
- /* Long form. High bit means another (lower) 7 bits following */
- do {
- oid[n] |= (*der & 0x7F);
- /* A clear high bit ends the byte sequence */
- if (!(*der & 0x80)) {
- break;
- }
- /* Allow a maximum of 4 x 7 bit shifts (28 bits) */
- if (++sanity > 4) {
- return 0;
- }
- /* Make room for the next 7 bits */
- oid[n] <<= 7;
- der++;
- } while (der < end);
- der++;
- n++;
- }
- }
- if (n < MAX_OID_LEN) {
- return n;
- }
- return 0;
+ if (limit > 0)
+ {
+ if (--limit == 0)
+ {
+ *buf = end;
+ return PS_SUCCESS;
+ }
+ }
+ }
+ *buf = p;
+ return PS_SUCCESS;
}
/**
- Look up an OID in our known oid table.
- @param[in] oid Array of OID segments to look up in table.
- @param[in] oidlen Number of segments in 'oid'
- @return A valid OID enum on success, 0 on failure.
-*/
+ Look up an OID in our known oid table.
+ @param[in] oid Array of OID segments to look up in table.
+ @param[in] oidlen Number of segments in 'oid'
+ @return A valid OID enum on success, 0 on failure.
+ */
static oid_e psFindOid(const uint32_t oid[MAX_OID_LEN], uint8_t oidlen)
{
- int i, j;
+ int i, j;
- psAssert(oidlen <= MAX_OID_LEN);
- for (j = 0; oid_list[j].id != 0; j++) {
- for (i = 0; i < oidlen; i++) {
- if ((uint16_t)(oid[i] & 0xFFFF) != oid_list[j].oid[i]) {
- break;
- }
- if ((i + 1) == oidlen) {
- return oid_list[j].id;
- }
- }
- }
- return 0;
+ psAssert(oidlen <= MAX_OID_LEN);
+ for (j = 0; oid_list[j].id != 0; j++)
+ {
+ for (i = 0; i < oidlen; i++)
+ {
+ if ((uint16_t) (oid[i] & 0xFFFF) != oid_list[j].oid[i])
+ {
+ break;
+ }
+ if ((i + 1) == oidlen)
+ {
+ return oid_list[j].id;
+ }
+ }
+ }
+ return 0;
}
-#ifdef USE_OID_TRACE
+# ifdef USE_CRYPTO_TRACE
/**
- Print an OID in dot notation, with it's symbolic name, if found.
- @param[in] oid Array of OID segments print.
- @param[in] oidlen Number of segments in 'oid'
- @return void
-*/
+ Print an OID in dot notation, with it's symbolic name, if found.
+ @param[in] oid Array of OID segments print.
+ @param[in] oidlen Number of segments in 'oid'
+ @return void
+ */
static void psTraceOid(uint32_t oid[MAX_OID_LEN], uint8_t oidlen)
{
- int i, j, found;
+ int i, j, found;
- for (i = 0; i < oidlen; i++) {
- if ((i + 1) < oidlen) {
- psTraceIntCrypto("%u.", oid[i]);
- } else {
- psTraceIntCrypto("%u", oid[i]);
- }
- }
- found = 0;
- for (j = 0; oid_list[j].oid[0] != 0 && !found; j++) {
- for (i = 0; i < oidlen; i++) {
- if ((uint8_t)(oid[i] & 0xFF) != oid_list[j].oid[i]) {
- break;
- }
- if ((i + 1) == oidlen) {
- psTraceStrCrypto(" (%s)", oid_list[j].name);
- found++;
- }
- }
- }
- psTraceCrypto("\n");
+ for (i = 0; i < oidlen; i++)
+ {
+ if ((i + 1) < oidlen)
+ {
+ psTraceIntCrypto("%u.", oid[i]);
+ }
+ else
+ {
+ psTraceIntCrypto("%u", oid[i]);
+ }
+ }
+ found = 0;
+ for (j = 0; oid_list[j].oid[0] != 0 && !found; j++)
+ {
+ for (i = 0; i < oidlen; i++)
+ {
+ if ((uint8_t) (oid[i] & 0xFF) != oid_list[j].oid[i])
+ {
+ break;
+ }
+ if ((i + 1) == oidlen)
+ {
+ psTraceStrCrypto(" (%s)", oid_list[j].name);
+ found++;
+ }
+ }
+ }
+ psTraceCrypto("\n");
}
-#else
-#define psTraceOid(A, B) psTraceCrypto("\n");
-#endif
+# else
+# define psTraceOid(A, B)
+# endif
/******************************************************************************/
/*
- X509v3 extensions
-*/
+ X509v3 extensions
+ */
-#ifdef USE_FULL_CERT_PARSE
+# ifdef USE_FULL_CERT_PARSE
static
int32_t parsePolicyQualifierInfo(psPool_t *pool,
- const unsigned char *p,
- const unsigned char *extEnd,
- uint16_t fullExtLen,
- x509PolicyQualifierInfo_t *qualInfo,
- uint16_t *qual_info_len)
+ const unsigned char *p,
+ const unsigned char *extEnd,
+ psSize_t fullExtLen,
+ x509PolicyQualifierInfo_t *qualInfo,
+ psSize_t *qual_info_len)
{
- uint32_t oid[MAX_OID_LEN] = {0};
- uint8_t oidlen;
- oid_e noid;
- uint16_t len;
- const unsigned char *qualifierStart, *qualifierEnd;
- const unsigned char *noticeNumbersEnd;
- int i;
- int32_t noticeNumber;
+ uint32_t oid[MAX_OID_LEN] = { 0 };
+ uint8_t oidlen;
+ oid_e noid;
+ psSize_t len;
+ const unsigned char *qualifierStart, *qualifierEnd;
+ const unsigned char *noticeNumbersEnd;
+ int i;
+ int32_t noticeNumber;
- qualifierStart = p;
+ qualifierStart = p;
- /* Parse a PolicyQualifierInfo. */
- if (getAsnSequence(&p, (uint32)(extEnd - p), &len) < 0) {
- psTraceCrypto("Error parsing certificatePolicies extension\n");
- return PS_PARSE_FAIL;
- }
- *qual_info_len = len + (p - qualifierStart);
- qualifierEnd = qualifierStart + *qual_info_len;
+ /* Parse a PolicyQualifierInfo. */
+ if (getAsnSequence(&p, (uint32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("Error parsing certificatePolicies extension\n");
+ return PS_PARSE_FAIL;
+ }
+ *qual_info_len = len + (p - qualifierStart);
+ qualifierEnd = qualifierStart + *qual_info_len;
- /* Parse policyQualifierId. */
- if (len < 1 || *p++ != ASN_OID) {
- psTraceCrypto("Malformed policy qualifier header\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnLength(&p, fullExtLen, &len) < 0 ||
- fullExtLen < len) {
- psTraceCrypto("Malformed extension length\n");
- return PS_PARSE_FAIL;
- }
- if ((oidlen = psParseOid(p, len, oid)) < 1) {
- psTraceCrypto("Malformed extension OID\n");
- return PS_PARSE_FAIL;
- }
- /* PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )*/
- noid = psFindOid(oid, oidlen);
- p += len;
- if (noid == oid_id_qt_cps) {
- if (*p++ != ASN_IA5STRING) {
- psTraceCrypto("Malformed extension OID\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnLength(&p, fullExtLen, &len) < 0 ||
- fullExtLen < len) {
- psTraceCrypto("Malformed extension length\n");
- return PS_PARSE_FAIL;
- }
- qualInfo->cps = psMalloc(pool, len+1);
- qualInfo->cpsLen = len;
- memcpy(qualInfo->cps,
- p, len);
- qualInfo->cps[len] = 0; /* Store as C string. */
- p += len;
- } else if(noid == oid_id_qt_unotice) {
+ /* Parse policyQualifierId. */
+ if (len < 1 || *p++ != ASN_OID)
+ {
+ psTraceCrypto("Malformed policy qualifier header\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnLength(&p, fullExtLen, &len) < 0 ||
+ fullExtLen < len)
+ {
+ psTraceCrypto("Malformed extension length\n");
+ return PS_PARSE_FAIL;
+ }
+ if ((oidlen = asnParseOid(p, len, oid)) < 1)
+ {
+ psTraceCrypto("Malformed extension OID\n");
+ return PS_PARSE_FAIL;
+ }
+ /* PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )*/
+ noid = psFindOid(oid, oidlen);
+ p += len;
+ if (noid == oid_id_qt_cps)
+ {
+ if (*p++ != ASN_IA5STRING)
+ {
+ psTraceCrypto("Malformed extension OID\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnLength(&p, fullExtLen, &len) < 0 ||
+ fullExtLen < len)
+ {
+ psTraceCrypto("Malformed extension length\n");
+ return PS_PARSE_FAIL;
+ }
+ qualInfo->cps = psMalloc(pool, len + 1);
+ qualInfo->cpsLen = len;
+ memcpy(qualInfo->cps,
+ p, len);
+ qualInfo->cps[len] = 0; /* Store as C string. */
+ p += len;
+ }
+ else if (noid == oid_id_qt_unotice)
+ {
- /* UserNotice ::= SEQUENCE {
- noticeRef NoticeReference OPTIONAL,
- explicitText DisplayText OPTIONAL } */
- if (getAsnSequence(&p, (uint32)(extEnd - p), &len) < 0) {
- psTraceCrypto("Error parsing certificatePolicies extension\n");
- return PS_PARSE_FAIL;
- }
- if (len == 0 || p >= qualifierEnd) {
- /* No optional noticeRef or explicitText.
- Nothing left to parse. */
- return PS_SUCCESS;
- }
- if (*p == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
- /* NoticeReference ::= SEQUENCE {
- organization DisplayText,
- noticeNumbers SEQUENCE OF INTEGER } */
- if (getAsnSequence(&p, (uint32)(extEnd - p), &len) < 0) {
- psTraceCrypto("Error parsing certificatePolicies extension\n");
- return PS_PARSE_FAIL;
- }
- /* Parse explicitText. */
- if (*p != ASN_UTF8STRING &&
- *p != ASN_VISIBLE_STRING &&
- *p != ASN_BMPSTRING &&
- *p != ASN_IA5STRING) {
- psTraceCrypto("Error parsing certificatePolicies extension." \
- "Only UTF8String, IA5String, BMPString and " \
- "VisibleString are supported in NoticeReferences.\n");
- return PS_PARSE_FAIL;
- }
- qualInfo->unoticeOrganizationEncoding = *p;
- p++;
- /* Parse organization. */
- if (getAsnLength(&p, fullExtLen, &len) < 0 ||
- fullExtLen < len) {
- psTraceCrypto("Malformed extension length\n");
- return PS_PARSE_FAIL;
- }
- qualInfo->unoticeOrganization = psMalloc(pool, len+1);
- if (qualInfo->unoticeOrganization == NULL)
- return PS_MEM_FAIL;
- qualInfo->unoticeOrganizationLen = len;
- memcpy(qualInfo->unoticeOrganization, p, len);
- qualInfo->unoticeOrganization[len] = 0; /* Store as C string. */
- p += len;
- /* Parse noticeNumbers. */
- if (getAsnSequence(&p, (uint32)(extEnd - p), &len) < 0) {
- psTraceCrypto("Error parsing certificatePolicies extension\n");
- return PS_PARSE_FAIL;
- }
- noticeNumbersEnd = p+len;
- i = 0;
- while (p != noticeNumbersEnd) {
- if (i == MAX_UNOTICE_NUMBERS) {
- psTraceCrypto("Too many UserNoticeNumbers.\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnInteger(&p, len, ¬iceNumber) < 0) {
- psTraceCrypto("Malformed extension length\n");
- return PS_PARSE_FAIL;
- }
- qualInfo->unoticeNumbers[i] = noticeNumber;
- i++;
- }
- qualInfo->unoticeNumbersLen = i;
- }
- if (p >= qualifierEnd) {
- /* The UserNotice contained noticeRef, but not explicitText. */
- return PS_SUCCESS;
- }
- /* Parse explicitText. */
- if (*p != ASN_UTF8STRING &&
- *p != ASN_VISIBLE_STRING &&
- *p != ASN_BMPSTRING &&
- *p != ASN_IA5STRING) {
- psTraceCrypto("Error parsing certificatePolicies extension." \
- "Only UTF8String, IA5String, BMPString and " \
- "VisibleString are supported in explicitText.\n");
- return PS_PARSE_FAIL;
- }
- qualInfo->unoticeExplicitTextEncoding = *p;
- p++;
- if (getAsnLength(&p, fullExtLen, &len) < 0 ||
- fullExtLen < len) {
- psTraceCrypto("Malformed extension length\n");
- return PS_PARSE_FAIL;
- }
- qualInfo->unoticeExplicitText = psMalloc(pool, len+1);
- if (qualInfo->unoticeExplicitText == NULL)
- return PS_MEM_FAIL;
- qualInfo->unoticeExplicitTextLen = len;
- memcpy(qualInfo->unoticeExplicitText, p, len);
- qualInfo->unoticeExplicitText[len] = 0; /* Store as C string. */
- p += len;
- } else {
- psTraceCrypto("Unsupported policyQualifierId\n");
- return PS_PARSE_FAIL;
- }
+ /* UserNotice ::= SEQUENCE {
+ noticeRef NoticeReference OPTIONAL,
+ explicitText DisplayText OPTIONAL } */
+ if (getAsnSequence(&p, (uint32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("Error parsing certificatePolicies extension\n");
+ return PS_PARSE_FAIL;
+ }
+ if (len == 0 || p >= qualifierEnd)
+ {
+ /* No optional noticeRef or explicitText.
+ Nothing left to parse. */
+ return PS_SUCCESS;
+ }
+ if (*p == (ASN_SEQUENCE | ASN_CONSTRUCTED))
+ {
+ /* NoticeReference ::= SEQUENCE {
+ organization DisplayText,
+ noticeNumbers SEQUENCE OF INTEGER } */
+ if (getAsnSequence(&p, (uint32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("Error parsing certificatePolicies extension\n");
+ return PS_PARSE_FAIL;
+ }
+ /* Parse explicitText. */
+ if (*p != ASN_UTF8STRING &&
+ *p != ASN_VISIBLE_STRING &&
+ *p != ASN_BMPSTRING &&
+ *p != ASN_IA5STRING)
+ {
+ psTraceCrypto("Error parsing certificatePolicies extension."
+ "Only UTF8String, IA5String, BMPString and "
+ "VisibleString are supported in NoticeReferences.\n");
+ return PS_PARSE_FAIL;
+ }
+ qualInfo->unoticeOrganizationEncoding = *p;
+ p++;
+ /* Parse organization. */
+ if (getAsnLength(&p, fullExtLen, &len) < 0 ||
+ fullExtLen < len)
+ {
+ psTraceCrypto("Malformed extension length\n");
+ return PS_PARSE_FAIL;
+ }
+ qualInfo->unoticeOrganization = psMalloc(pool, len + 1);
+ if (qualInfo->unoticeOrganization == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ qualInfo->unoticeOrganizationLen = len;
+ memcpy(qualInfo->unoticeOrganization, p, len);
+ qualInfo->unoticeOrganization[len] = 0; /* Store as C string. */
+ p += len;
+ /* Parse noticeNumbers. */
+ if (getAsnSequence(&p, (uint32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("Error parsing certificatePolicies extension\n");
+ return PS_PARSE_FAIL;
+ }
+ noticeNumbersEnd = p + len;
+ i = 0;
+ while (p != noticeNumbersEnd)
+ {
+ if (i == MAX_UNOTICE_NUMBERS)
+ {
+ psTraceCrypto("Too many UserNoticeNumbers.\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnInteger(&p, len, ¬iceNumber) < 0)
+ {
+ psTraceCrypto("Malformed extension length\n");
+ return PS_PARSE_FAIL;
+ }
+ qualInfo->unoticeNumbers[i] = noticeNumber;
+ i++;
+ }
+ qualInfo->unoticeNumbersLen = i;
+ }
+ if (p >= qualifierEnd)
+ {
+ /* The UserNotice contained noticeRef, but not explicitText. */
+ return PS_SUCCESS;
+ }
+ /* Parse explicitText. */
+ if (*p != ASN_UTF8STRING &&
+ *p != ASN_VISIBLE_STRING &&
+ *p != ASN_BMPSTRING &&
+ *p != ASN_IA5STRING)
+ {
+ psTraceCrypto("Error parsing certificatePolicies extension."
+ "Only UTF8String, IA5String, BMPString and "
+ "VisibleString are supported in explicitText.\n");
+ return PS_PARSE_FAIL;
+ }
+ qualInfo->unoticeExplicitTextEncoding = *p;
+ p++;
+ if (getAsnLength(&p, fullExtLen, &len) < 0 ||
+ fullExtLen < len)
+ {
+ psTraceCrypto("Malformed extension length\n");
+ return PS_PARSE_FAIL;
+ }
+ qualInfo->unoticeExplicitText = psMalloc(pool, len + 1);
+ if (qualInfo->unoticeExplicitText == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ qualInfo->unoticeExplicitTextLen = len;
+ memcpy(qualInfo->unoticeExplicitText, p, len);
+ qualInfo->unoticeExplicitText[len] = 0; /* Store as C string. */
+ p += len;
+ }
+ else
+ {
+ psTraceCrypto("Unsupported policyQualifierId\n");
+ return PS_PARSE_FAIL;
+ }
- return PS_SUCCESS;
+ return PS_SUCCESS;
}
static
int32_t parsePolicyInformation(psPool_t *pool,
- const unsigned char *p,
- const unsigned char *extEnd,
- uint16_t fullExtLen,
- x509PolicyInformation_t *polInfo,
- uint16_t *pol_info_len)
+ const unsigned char *p,
+ const unsigned char *extEnd,
+ psSize_t fullExtLen,
+ x509PolicyInformation_t *polInfo,
+ psSize_t *pol_info_len)
{
- uint32_t oid[MAX_OID_LEN] = {0};
- uint8_t oidlen;
- uint16_t len;
- const unsigned char *qualifierEnd;
- const unsigned char *polInfoStart, *polInfoEnd;
- x509PolicyQualifierInfo_t *qualInfo;
- uint16_t qualInfoLen;
- int i;
+ uint32_t oid[MAX_OID_LEN] = { 0 };
+ uint8_t oidlen;
+ psSize_t len;
+ const unsigned char *qualifierEnd;
+ const unsigned char *polInfoStart, *polInfoEnd;
+ x509PolicyQualifierInfo_t *qualInfo;
+ psSize_t qualInfoLen;
+ int i;
- polInfoStart = p;
+ polInfoStart = p;
- /*
- PolicyInformation ::= SEQUENCE {
- policyIdentifier CertPolicyId,
- policyQualifiers SEQUENCE SIZE (1..MAX) OF
- PolicyQualifierInfo OPTIONAL }
- */
+ /*
+ PolicyInformation ::= SEQUENCE {
+ policyIdentifier CertPolicyId,
+ policyQualifiers SEQUENCE SIZE (1..MAX) OF
+ PolicyQualifierInfo OPTIONAL }
+ */
- if (getAsnSequence(&p, (uint32)(extEnd - p), &len) < 0) {
- psTraceCrypto("Error parsing certificatePolicies extension\n");
- return PS_PARSE_FAIL;
- }
- *pol_info_len = len + (p-polInfoStart);
- polInfoEnd = polInfoStart + *pol_info_len;
+ if (getAsnSequence(&p, (uint32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("Error parsing certificatePolicies extension\n");
+ return PS_PARSE_FAIL;
+ }
+ *pol_info_len = len + (p - polInfoStart);
+ polInfoEnd = polInfoStart + *pol_info_len;
- /* Parse CertPolicyId. */
- if (*p++ != ASN_OID) {
- psTraceCrypto("Malformed extension header\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnLength(&p, fullExtLen, &len) < 0 ||
- fullExtLen < len) {
- psTraceCrypto("Malformed extension length\n");
- return PS_PARSE_FAIL;
- }
- if ((oidlen = psParseOid(p, len, oid)) < 1) {
- psTraceCrypto("Malformed extension OID\n");
- return PS_PARSE_FAIL;
- }
- p += len;
- if (oidlen == 0 || oidlen > MAX_OID_LEN) {
- psTraceCrypto("Malformed extension OID\n");
- return PS_PARSE_FAIL;
- }
+ /* Parse CertPolicyId. */
+ if (*p++ != ASN_OID)
+ {
+ psTraceCrypto("Malformed extension header\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnLength(&p, fullExtLen, &len) < 0 ||
+ fullExtLen < len)
+ {
+ psTraceCrypto("Malformed extension length\n");
+ return PS_PARSE_FAIL;
+ }
+ if ((oidlen = asnParseOid(p, len, oid)) < 1)
+ {
+ psTraceCrypto("Malformed extension OID\n");
+ return PS_PARSE_FAIL;
+ }
+ p += len;
+ if (oidlen == 0 || oidlen > MAX_OID_LEN)
+ {
+ psTraceCrypto("Malformed extension OID\n");
+ return PS_PARSE_FAIL;
+ }
- /* Store the policy ID. */
- polInfo->policyOid = psMalloc(pool, oidlen*sizeof(uint32_t));
- if (polInfo->policyOid == NULL)
- return PS_MEM_FAIL;
- for (i = 0; i < oidlen; i++) {
- polInfo->policyOid[i] = oid[i];
- }
- polInfo->policyOidLen = oidlen;
+ /* Store the policy ID. */
+ polInfo->policyOid = psMalloc(pool, oidlen * sizeof(uint32_t));
+ if (polInfo->policyOid == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ for (i = 0; i < oidlen; i++)
+ {
+ polInfo->policyOid[i] = oid[i];
+ }
+ polInfo->policyOidLen = oidlen;
- if ((p >= polInfoEnd) ||
- (*p != (ASN_SEQUENCE | ASN_CONSTRUCTED))) {
- /* No optional PolicyQualifierInfos. */
- return PS_SUCCESS;
- }
+ if ((p >= polInfoEnd) ||
+ (*p != (ASN_SEQUENCE | ASN_CONSTRUCTED)))
+ {
+ /* No optional PolicyQualifierInfos. */
+ return PS_SUCCESS;
+ }
- /* Parse policyQualifiers := SEQUENCE SIZE (1..MAX) OF
- PolicyQualifierInfo OPTIONAL*/
- if (getAsnSequence(&p, (uint32)(extEnd - p), &len) < 0) {
- psTraceCrypto("Error parsing certificatePolicies extension\n");
- return PS_PARSE_FAIL;
- }
- qualifierEnd = p + len;
+ /* Parse policyQualifiers := SEQUENCE SIZE (1..MAX) OF
+ PolicyQualifierInfo OPTIONAL*/
+ if (getAsnSequence(&p, (uint32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("Error parsing certificatePolicies extension\n");
+ return PS_PARSE_FAIL;
+ }
+ qualifierEnd = p + len;
- polInfo->qualifiers = psMalloc(pool, sizeof(x509PolicyQualifierInfo_t));
- if (polInfo->qualifiers == NULL)
- return PS_MEM_FAIL;
- memset(polInfo->qualifiers, 0, sizeof(x509PolicyQualifierInfo_t));
- qualInfo = polInfo->qualifiers;
+ polInfo->qualifiers = psMalloc(pool, sizeof(x509PolicyQualifierInfo_t));
+ if (polInfo->qualifiers == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ memset(polInfo->qualifiers, 0, sizeof(x509PolicyQualifierInfo_t));
+ qualInfo = polInfo->qualifiers;
- /* Parse initial PolicyQualifierInfo. */
- if (parsePolicyQualifierInfo(pool,
- p,
- extEnd,
- fullExtLen,
- qualInfo,
- &qualInfoLen) < 0) {
- return PS_PARSE_FAIL;
- }
- p += qualInfoLen;
+ /* Parse initial PolicyQualifierInfo. */
+ if (parsePolicyQualifierInfo(pool,
+ p,
+ extEnd,
+ fullExtLen,
+ qualInfo,
+ &qualInfoLen) < 0)
+ {
+ return PS_PARSE_FAIL;
+ }
+ p += qualInfoLen;
- /* More PolicyQualifierInfos? */
- while ((p < qualifierEnd)
- && (p < extEnd)
- && (*p == (ASN_SEQUENCE | ASN_CONSTRUCTED))) {
- qualInfo->next = psMalloc(pool, sizeof(x509PolicyQualifierInfo_t));
- if (qualInfo->next == NULL)
- return PS_MEM_FAIL;
- memset(qualInfo->next, 0, sizeof(x509PolicyQualifierInfo_t));
- qualInfo = qualInfo->next;
+ /* More PolicyQualifierInfos? */
+ while ((p < qualifierEnd)
+ && (p < extEnd)
+ && (*p == (ASN_SEQUENCE | ASN_CONSTRUCTED)))
+ {
+ qualInfo->next = psMalloc(pool, sizeof(x509PolicyQualifierInfo_t));
+ if (qualInfo->next == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ memset(qualInfo->next, 0, sizeof(x509PolicyQualifierInfo_t));
+ qualInfo = qualInfo->next;
- if (parsePolicyQualifierInfo(pool,
- p,
- extEnd,
- fullExtLen,
- qualInfo,
- &qualInfoLen) < 0) {
- return PS_PARSE_FAIL;
- }
- p += qualInfoLen;
- }
+ if (parsePolicyQualifierInfo(pool,
+ p,
+ extEnd,
+ fullExtLen,
+ qualInfo,
+ &qualInfoLen) < 0)
+ {
+ return PS_PARSE_FAIL;
+ }
+ p += qualInfoLen;
+ }
- return PS_SUCCESS;
+ return PS_SUCCESS;
}
static
int32_t parsePolicyConstraints(psPool_t *pool,
- const unsigned char *p,
- const unsigned char *extEnd,
- x509policyConstraints_t *policyConstraints,
- uint16_t *polConstraintsLen)
+ const unsigned char *p,
+ const unsigned char *extEnd,
+ x509policyConstraints_t *policyConstraints,
+ psSize_t *polConstraintsLen)
{
- uint16_t len;
- const unsigned char *polConstraintsStart, *polConstraintsEnd;
- unsigned char tag;
- int num_ints = 0;
+ psSize_t len;
+ const unsigned char *polConstraintsStart, *polConstraintsEnd;
+ unsigned char tag;
+ int num_ints = 0;
- /*
- PolicyConstraints ::= SEQUENCE {
- requireExplicitPolicy [0] SkipCerts OPTIONAL,
- inhibitPolicyMapping [1] SkipCerts OPTIONAL }
+ /*
+ PolicyConstraints ::= SEQUENCE {
+ requireExplicitPolicy [0] SkipCerts OPTIONAL,
+ inhibitPolicyMapping [1] SkipCerts OPTIONAL }
- SkipCerts ::= INTEGER (0..MAX)
- */
+ SkipCerts ::= INTEGER (0..MAX)
+ */
- polConstraintsStart = p;
+ polConstraintsStart = p;
- if (getAsnSequence(&p, (uint32)(extEnd - p), &len) < 0) {
- psTraceCrypto("Error parsing policyConstraints extension\n");
- return PS_PARSE_FAIL;
- }
- polConstraintsEnd = p + len;
- *polConstraintsLen = (polConstraintsEnd - polConstraintsStart);
+ if (getAsnSequence(&p, (uint32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("Error parsing policyConstraints extension\n");
+ return PS_PARSE_FAIL;
+ }
+ polConstraintsEnd = p + len;
+ *polConstraintsLen = (polConstraintsEnd - polConstraintsStart);
- if (len == 0) {
- /* Empty PolicyConstraints. This is allowed by RFC 5280:
- "The behavior of clients that encounter an empty policy
- constraints field is not addressed in this profile.*/
- return PS_SUCCESS;
- }
+ if (len == 0)
+ {
+ /* Empty PolicyConstraints. This is allowed by RFC 5280:
+ "The behavior of clients that encounter an empty policy
+ constraints field is not addressed in this profile.*/
+ return PS_SUCCESS;
+ }
- /* Parse up to 2 SkipCerts INTEGERS with context-specific tags 0 and 1. */
- while( num_ints < 2 && (*p == ASN_CONTEXT_SPECIFIC ||
- *p == (ASN_CONTEXT_SPECIFIC + 1)) ) {
- tag = *p++;
- if (getAsnLength(&p, (uint32)(polConstraintsEnd - p), &len) < 0 ||
- (uint32)(polConstraintsEnd - p) < len) {
- psTraceCrypto("getAsnLength failure in policyConstraints parsing\n");
- return PS_PARSE_FAIL;
- }
- /* We only accept single-octet SkipCerts values. Should be enough
- for all reasonable applications. */
- if (len != 1) {
- psTraceCrypto("Too large SkipCerts value in PolicyConstraints.\n");
- return PS_PARSE_FAIL;
- }
- if (tag == ASN_CONTEXT_SPECIFIC)
- policyConstraints->requireExplicitPolicy = (int32_t)*p;
- else
- policyConstraints->inhibitPolicyMappings = (int32_t)*p;
- p += len;
- ++num_ints;
- }
+ /* Parse up to 2 SkipCerts INTEGERS with context-specific tags 0 and 1. */
+ while ( num_ints < 2 && (*p == ASN_CONTEXT_SPECIFIC ||
+ *p == (ASN_CONTEXT_SPECIFIC + 1)) )
+ {
+ tag = *p++;
+ if (getAsnLength(&p, (uint32) (polConstraintsEnd - p), &len) < 0 ||
+ (uint32) (polConstraintsEnd - p) < len)
+ {
+ psTraceCrypto("getAsnLength failure in policyConstraints parsing\n");
+ return PS_PARSE_FAIL;
+ }
+ /* We only accept single-octet SkipCerts values. Should be enough
+ for all reasonable applications. */
+ if (len != 1)
+ {
+ psTraceCrypto("Too large SkipCerts value in PolicyConstraints.\n");
+ return PS_PARSE_FAIL;
+ }
+ if (tag == ASN_CONTEXT_SPECIFIC)
+ {
+ policyConstraints->requireExplicitPolicy = (int32_t) *p;
+ }
+ else
+ {
+ policyConstraints->inhibitPolicyMappings = (int32_t) *p;
+ }
+ p += len;
+ ++num_ints;
+ }
- if (p != polConstraintsEnd) {
- psTraceCrypto("Error parsing policyConstraints extension\n");
- return PS_PARSE_FAIL;
- }
+ if (p != polConstraintsEnd)
+ {
+ psTraceCrypto("Error parsing policyConstraints extension\n");
+ return PS_PARSE_FAIL;
+ }
- return PS_SUCCESS;
+ return PS_SUCCESS;
}
static
int32_t parsePolicyMappings(psPool_t *pool,
- const unsigned char *p,
- const unsigned char *extEnd,
- x509policyMappings_t *policyMappings,
- uint16_t *polMappingsLen)
+ const unsigned char *p,
+ const unsigned char *extEnd,
+ x509policyMappings_t *policyMappings,
+ psSize_t *polMappingsLen)
{
- uint32_t oid[MAX_OID_LEN] = {0};
- uint16_t len, oidlen;
- const unsigned char *polMappingsStart, *polMappingsEnd;
- x509policyMappings_t *pol_map;
- int i;
- int num_mappings = 0;
+ uint32_t oid[MAX_OID_LEN] = { 0 };
+ psSize_t len, oidlen;
+ const unsigned char *polMappingsStart, *polMappingsEnd;
+ x509policyMappings_t *pol_map;
+ int i;
+ int num_mappings = 0;
- /*
- PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
- issuerDomainPolicy CertPolicyId,
- subjectDomainPolicy CertPolicyId }
- */
+ /*
+ PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
+ issuerDomainPolicy CertPolicyId,
+ subjectDomainPolicy CertPolicyId }
+ */
- polMappingsStart = p;
+ polMappingsStart = p;
- if (getAsnSequence(&p, (uint32)(extEnd - p), &len) < 0) {
- psTraceCrypto("Error parsing policyMappings extension\n");
- return PS_PARSE_FAIL;
- }
- polMappingsEnd = p + len;
- *polMappingsLen = (polMappingsEnd - polMappingsStart);
+ if (getAsnSequence(&p, (uint32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("Error parsing policyMappings extension\n");
+ return PS_PARSE_FAIL;
+ }
+ polMappingsEnd = p + len;
+ *polMappingsLen = (polMappingsEnd - polMappingsStart);
- pol_map = policyMappings;
- while (p < polMappingsEnd &&
- *p == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
+ pol_map = policyMappings;
+ while (p < polMappingsEnd &&
+ *p == (ASN_SEQUENCE | ASN_CONSTRUCTED))
+ {
- if (num_mappings > 0) {
- pol_map->next = psMalloc(pool, sizeof(x509policyMappings_t));
- if (pol_map->next == NULL)
- return PS_MEM_FAIL;
- memset(pol_map->next, 0, sizeof(x509policyMappings_t));
- pol_map = pol_map->next;
- }
+ if (num_mappings > 0)
+ {
+ pol_map->next = psMalloc(pool, sizeof(x509policyMappings_t));
+ if (pol_map->next == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ memset(pol_map->next, 0, sizeof(x509policyMappings_t));
+ pol_map = pol_map->next;
+ }
- if (getAsnSequence(&p, (uint32)(extEnd - p), &len) < 0) {
- psTraceCrypto("Error parsing policyMappings extension\n");
- return PS_PARSE_FAIL;
- }
+ if (getAsnSequence(&p, (uint32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("Error parsing policyMappings extension\n");
+ return PS_PARSE_FAIL;
+ }
- /* Parse issuerDomainPolicy OID. */
- if (*p++ != ASN_OID) {
- psTraceCrypto("Malformed extension header\n");
- return PS_PARSE_FAIL;
- }
+ /* Parse issuerDomainPolicy OID. */
+ if (*p++ != ASN_OID)
+ {
+ psTraceCrypto("Malformed extension header\n");
+ return PS_PARSE_FAIL;
+ }
- if (getAsnLength(&p, (uint32)(polMappingsEnd - p), &len) < 0 ||
- (uint32)(polMappingsEnd - p) < len) {
- psTraceCrypto("getAsnLength failure in policyMappings parsing\n");
- return PS_PARSE_FAIL;
- }
- memset(oid, 0, sizeof(oid));
- if ((oidlen = psParseOid(p, len, oid)) < 1) {
- psTraceCrypto("Malformed extension OID\n");
- return PS_PARSE_FAIL;
- }
- p += len;
+ if (getAsnLength(&p, (uint32) (polMappingsEnd - p), &len) < 0 ||
+ (uint32) (polMappingsEnd - p) < len)
+ {
+ psTraceCrypto("getAsnLength failure in policyMappings parsing\n");
+ return PS_PARSE_FAIL;
+ }
+ memset(oid, 0, sizeof(oid));
+ if ((oidlen = asnParseOid(p, len, oid)) < 1)
+ {
+ psTraceCrypto("Malformed extension OID\n");
+ return PS_PARSE_FAIL;
+ }
+ p += len;
- pol_map->issuerDomainPolicy = psMalloc(pool, len*sizeof(uint32_t));
- memset(pol_map->issuerDomainPolicy, 0, len*sizeof(uint32_t));
+ pol_map->issuerDomainPolicy = psMalloc(pool, len * sizeof(uint32_t));
+ memset(pol_map->issuerDomainPolicy, 0, len * sizeof(uint32_t));
- for (i = 0; i < oidlen; i++) {
- pol_map->issuerDomainPolicy[i] = oid[i];
- }
- pol_map->issuerDomainPolicyLen = len;
+ for (i = 0; i < oidlen; i++)
+ {
+ pol_map->issuerDomainPolicy[i] = oid[i];
+ }
+ pol_map->issuerDomainPolicyLen = len;
- /* Parse subjectDomainPolicy OID. */
- if (*p++ != ASN_OID) {
- psTraceCrypto("Malformed extension header\n");
- return PS_PARSE_FAIL;
- }
+ /* Parse subjectDomainPolicy OID. */
+ if (*p++ != ASN_OID)
+ {
+ psTraceCrypto("Malformed extension header\n");
+ return PS_PARSE_FAIL;
+ }
- if (getAsnLength(&p, (uint32)(polMappingsEnd - p), &len) < 0 ||
- (uint32)(polMappingsEnd - p) < len) {
- psTraceCrypto("getAsnLength failure in policyMappings parsing\n");
- return PS_PARSE_FAIL;
- }
- memset(oid, 0, sizeof(oid));
- if ((oidlen = psParseOid(p, len, oid)) < 1) {
- psTraceCrypto("Malformed extension OID\n");
- return PS_PARSE_FAIL;
- }
- p += len;
+ if (getAsnLength(&p, (uint32) (polMappingsEnd - p), &len) < 0 ||
+ (uint32) (polMappingsEnd - p) < len)
+ {
+ psTraceCrypto("getAsnLength failure in policyMappings parsing\n");
+ return PS_PARSE_FAIL;
+ }
+ memset(oid, 0, sizeof(oid));
+ if ((oidlen = asnParseOid(p, len, oid)) < 1)
+ {
+ psTraceCrypto("Malformed extension OID\n");
+ return PS_PARSE_FAIL;
+ }
+ p += len;
- pol_map->subjectDomainPolicy = psMalloc(pool, len*sizeof(uint32_t));
- memset(pol_map->subjectDomainPolicy, 0, len*sizeof(uint32_t));
+ pol_map->subjectDomainPolicy = psMalloc(pool, len * sizeof(uint32_t));
+ memset(pol_map->subjectDomainPolicy, 0, len * sizeof(uint32_t));
- for (i = 0; i < oidlen; i++) {
- pol_map->subjectDomainPolicy[i] = oid[i];
- }
- pol_map->subjectDomainPolicyLen = len;
+ for (i = 0; i < oidlen; i++)
+ {
+ pol_map->subjectDomainPolicy[i] = oid[i];
+ }
+ pol_map->subjectDomainPolicyLen = len;
- ++num_mappings;
- }
+ ++num_mappings;
+ }
- if (p != polMappingsEnd) {
- psTraceCrypto("Error parsing policyMappings extension\n");
- return PS_PARSE_FAIL;
- }
+ if (p != polMappingsEnd)
+ {
+ psTraceCrypto("Error parsing policyMappings extension\n");
+ return PS_PARSE_FAIL;
+ }
- return PS_SUCCESS;
+ return PS_SUCCESS;
}
static
int32_t parseAuthorityInfoAccess(psPool_t *pool,
- const unsigned char *p,
- const unsigned char *extEnd,
- x509authorityInfoAccess_t **authInfo,
- uint16_t *authInfoLen)
+ const unsigned char *p,
+ const unsigned char *extEnd,
+ x509authorityInfoAccess_t **authInfo,
+ psSize_t *authInfoLen)
{
- uint16_t len, oidlen, adLen;
- const unsigned char *authInfoStart, *authInfoEnd;
- x509authorityInfoAccess_t *pAuthInfo;
- uint32_t oid[MAX_OID_LEN] = {0};
- oid_e noid;
- int first_entry = 0;
+ psSize_t len, oidlen, adLen;
+ const unsigned char *authInfoStart, *authInfoEnd;
+ x509authorityInfoAccess_t *pAuthInfo;
+ uint32_t oid[MAX_OID_LEN] = { 0 };
+ oid_e noid;
+ int first_entry = 0;
- authInfoStart = p;
+ authInfoStart = p;
/*
id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
@@ -2342,2710 +3103,3182 @@ int32_t parseAuthorityInfoAccess(psPool_t *pool,
id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
-*/
+ */
- /* AuthorityInfoAccessSyntax. */
- if (getAsnSequence(&p, (int32)(extEnd - p), &len) < 0) {
- psTraceCrypto("Error parsing authKeyId extension\n");
- return PS_PARSE_FAIL;
- }
+ /* AuthorityInfoAccessSyntax. */
+ if (getAsnSequence(&p, (int32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("Error parsing authKeyId extension\n");
+ return PS_PARSE_FAIL;
+ }
- authInfoEnd = p + len;
- *authInfoLen = (authInfoEnd - authInfoStart);
+ authInfoEnd = p + len;
+ *authInfoLen = (authInfoEnd - authInfoStart);
- if (*authInfo == NULL) {
- *authInfo = psMalloc(pool, sizeof(x509authorityInfoAccess_t));
- if (*authInfo == NULL)
- return PS_MEM_FAIL;
- memset(*authInfo, 0, sizeof(x509authorityInfoAccess_t));
- first_entry = 1;
- }
+ if (*authInfo == NULL)
+ {
+ *authInfo = psMalloc(pool, sizeof(x509authorityInfoAccess_t));
+ if (*authInfo == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ memset(*authInfo, 0, sizeof(x509authorityInfoAccess_t));
+ first_entry = 1;
+ }
- pAuthInfo = *authInfo;
+ pAuthInfo = *authInfo;
- while (p < authInfoEnd &&
- *p == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
+ while (p < authInfoEnd &&
+ *p == (ASN_SEQUENCE | ASN_CONSTRUCTED))
+ {
- /* Find the end of the list. */
- while (pAuthInfo->next != NULL) {
- pAuthInfo = pAuthInfo->next;
- }
- if (!first_entry) {
- /* Malloc space for a new entry. */
- pAuthInfo->next = psMalloc(pool,
- sizeof(x509authorityInfoAccess_t));
- if (pAuthInfo->next == NULL)
- return PS_MEM_FAIL;
- memset(pAuthInfo->next, 0,
- sizeof(x509authorityInfoAccess_t));
- pAuthInfo = pAuthInfo->next;
- } else
- first_entry = 0;
+ /* Find the end of the list. */
+ while (pAuthInfo->next != NULL)
+ {
+ pAuthInfo = pAuthInfo->next;
+ }
+ if (!first_entry)
+ {
+ /* Malloc space for a new entry. */
+ pAuthInfo->next = psMalloc(pool,
+ sizeof(x509authorityInfoAccess_t));
+ if (pAuthInfo->next == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ memset(pAuthInfo->next, 0,
+ sizeof(x509authorityInfoAccess_t));
+ pAuthInfo = pAuthInfo->next;
+ }
+ else
+ {
+ first_entry = 0;
+ }
- /* AccessDescription. */
- if (getAsnSequence(&p, (int32)(extEnd - p), &adLen) < 0) {
- psTraceCrypto("Error parsing authKeyId extension\n");
- return PS_PARSE_FAIL;
- }
- /* accessMethod. */
- if (*p++ != ASN_OID) {
- psTraceCrypto("Malformed extension header\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnLength(&p, (uint32)(authInfoEnd - p), &len) < 0 ||
- (uint32)(authInfoEnd - p) < len) {
- psTraceCrypto("getAsnLength failure in authInfo parsing\n");
- return PS_PARSE_FAIL;
- }
- memset(oid, 0, sizeof(oid));
- if ((oidlen = psParseOid(p, len, oid)) < 1) {
- psTraceCrypto("Malformed extension OID\n");
- return PS_PARSE_FAIL;
- }
- noid = psFindOid(oid, oidlen);
- p += len;
- if (noid != oid_id_ad_caIssuers &&
- noid != oid_id_ad_ocsp) {
- psTraceCrypto("Unsupported AccessDescription: " \
- "only oid_ad_caIssuers and id_ad_ocsp " \
- "are supported. \n");
- return PS_PARSE_FAIL;
- }
- /* accessLocation. */
- switch (*p++) {
- case (ASN_CONTEXT_SPECIFIC + 6):
- /* uniformResourceIdentifier [6] IA5String. */
- if (getAsnLength(&p, (uint32)(authInfoEnd - p), &len) < 0 ||
- (uint32)(authInfoEnd - p) < len) {
- psTraceCrypto("getAsnLength failure in authInfo parsing\n");
- return PS_PARSE_FAIL;
- }
- if (noid == oid_id_ad_ocsp) {
- pAuthInfo->ocsp = psMalloc(pool, len);
- if (pAuthInfo->ocsp == NULL)
- return PS_MEM_FAIL;
- memcpy(pAuthInfo->ocsp, p, len);
- pAuthInfo->ocspLen = len;
- p += len;
- } else { /* oid_id_ad_caIssuers */
- pAuthInfo->caIssuers = psMalloc(pool, len);
- if (pAuthInfo->caIssuers == NULL)
- return PS_MEM_FAIL;
- memcpy(pAuthInfo->caIssuers, p, len);
- pAuthInfo->caIssuersLen = len;
- p += len;
- }
- break;
- default:
- psTraceCrypto("Unsupported string type in AUTH_INFO ACC " \
- "(only uniformResourceIdenfitier is " \
- "supported). \n");
- return PS_PARSE_FAIL;
- }
- } /* Next AccessDescription, if any. */
+ /* AccessDescription. */
+ if (getAsnSequence(&p, (int32) (extEnd - p), &adLen) < 0)
+ {
+ psTraceCrypto("Error parsing authKeyId extension\n");
+ return PS_PARSE_FAIL;
+ }
+ /* accessMethod. */
+ if (*p++ != ASN_OID)
+ {
+ psTraceCrypto("Malformed extension header\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnLength(&p, (uint32) (authInfoEnd - p), &len) < 0 ||
+ (uint32) (authInfoEnd - p) < len)
+ {
+ psTraceCrypto("getAsnLength failure in authInfo parsing\n");
+ return PS_PARSE_FAIL;
+ }
+ memset(oid, 0, sizeof(oid));
+ if ((oidlen = asnParseOid(p, len, oid)) < 1)
+ {
+ psTraceCrypto("Malformed extension OID\n");
+ return PS_PARSE_FAIL;
+ }
+ noid = psFindOid(oid, oidlen);
+ p += len;
+ if (noid != oid_id_ad_caIssuers &&
+ noid != oid_id_ad_ocsp)
+ {
+ psTraceCrypto("Unsupported AccessDescription: "
+ "only oid_ad_caIssuers and id_ad_ocsp "
+ "are supported. \n");
+ return PS_PARSE_FAIL;
+ }
+ /* accessLocation. */
+ switch (*p++)
+ {
+ case (ASN_CONTEXT_SPECIFIC + 6):
+ /* uniformResourceIdentifier [6] IA5String. */
+ if (getAsnLength(&p, (uint32) (authInfoEnd - p), &len) < 0 ||
+ (uint32) (authInfoEnd - p) < len)
+ {
+ psTraceCrypto("getAsnLength failure in authInfo parsing\n");
+ return PS_PARSE_FAIL;
+ }
+ if (noid == oid_id_ad_ocsp)
+ {
+ pAuthInfo->ocsp = psMalloc(pool, len);
+ if (pAuthInfo->ocsp == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ memcpy(pAuthInfo->ocsp, p, len);
+ pAuthInfo->ocspLen = len;
+ p += len;
+ }
+ else /* oid_id_ad_caIssuers */
+ {
+ pAuthInfo->caIssuers = psMalloc(pool, len);
+ if (pAuthInfo->caIssuers == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ memcpy(pAuthInfo->caIssuers, p, len);
+ pAuthInfo->caIssuersLen = len;
+ p += len;
+ }
+ break;
+ default:
+ psTraceCrypto("Unsupported string type in AUTH_INFO ACC "
+ "(only uniformResourceIdenfitier is "
+ "supported). \n");
+ return PS_PARSE_FAIL;
+ }
+ } /* Next AccessDescription, if any. */
- return PS_SUCCESS;
+ return PS_SUCCESS;
}
-#endif /* USE_FULL_CERT_PARSE */
+# endif /* USE_FULL_CERT_PARSE */
int32_t getExplicitExtensions(psPool_t *pool, const unsigned char **pp,
- uint16_t inlen, int32_t expVal,
- x509v3extensions_t *extensions, uint8_t known)
+ psSize_t inlen, int32_t expVal,
+ x509v3extensions_t *extensions, uint8_t known)
{
- const unsigned char *p = *pp, *end;
- const unsigned char *extEnd, *extStart, *save;
- unsigned char critical;
- uint16_t len, fullExtLen;
- uint32_t oid[MAX_OID_LEN];
- uint8_t oidlen;
- oid_e noid;
-#ifdef USE_FULL_CERT_PARSE
- uint16_t subExtLen;
- const unsigned char *subSave;
- int32_t nc = 0;
- x509PolicyInformation_t *pPolicy;
- const unsigned char *policiesEnd;
-#endif /* USE_FULL_CERT_PARSE */
+ const unsigned char *p = *pp, *end;
+ const unsigned char *extEnd, *extStart, *save;
+ unsigned char critical;
+ psSize_t len, fullExtLen;
+ uint32_t oid[MAX_OID_LEN];
+ uint8_t oidlen;
+ oid_e noid;
- end = p + inlen;
- if (inlen < 1) {
- return PS_ARG_FAIL;
- }
- extensions->pool = pool;
- extensions->bc.cA = CA_UNDEFINED;
+# ifdef USE_FULL_CERT_PARSE
+ psSize_t subExtLen;
+ const unsigned char *subSave;
+ int32_t nc = 0;
+ x509PolicyInformation_t *pPolicy;
+ const unsigned char *policiesEnd;
+# endif /* USE_FULL_CERT_PARSE */
- if (known) {
- goto KNOWN_EXT;
- }
+ end = p + inlen;
+ if (inlen < 1)
+ {
+ return PS_ARG_FAIL;
+ }
+ extensions->pool = pool;
+ extensions->bc.cA = CA_UNDEFINED;
+
+ if (known)
+ {
+ goto KNOWN_EXT;
+ }
/*
- Not treating this as an error because it is optional.
-*/
- if (*p != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | expVal)) {
- return 0;
- }
- p++;
- if (getAsnLength(&p, (uint32)(end - p), &len) < 0 ||
- (uint32)(end - p) < len) {
- psTraceCrypto("Initial getAsnLength failure in extension parse\n");
- return PS_PARSE_FAIL;
- }
+ Not treating this as an error because it is optional.
+ */
+ if (*p != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | expVal))
+ {
+ return 0;
+ }
+ p++;
+ if (getAsnLength(&p, (uint32) (end - p), &len) < 0 ||
+ (uint32) (end - p) < len)
+ {
+ psTraceCrypto("Initial getAsnLength failure in extension parse\n");
+ return PS_PARSE_FAIL;
+ }
KNOWN_EXT:
/*
- Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
+ Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
- Extension ::= SEQUENCE {
- extnID OBJECT IDENTIFIER,
- extnValue OCTET STRING }
-*/
- if (getAsnSequence(&p, (uint32)(end - p), &len) < 0 ||
- (uint32)(end - p) < len) {
- psTraceCrypto("Initial getAsnSequence failure in extension parse\n");
- return PS_PARSE_FAIL;
- }
- extEnd = p + len;
- while ((p != extEnd) && *p == (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
- if (getAsnSequence(&p, (uint32)(extEnd - p), &fullExtLen) < 0) {
- psTraceCrypto("getAsnSequence failure in extension parse\n");
- return PS_PARSE_FAIL;
- }
- extStart = p;
+ Extension ::= SEQUENCE {
+ extnID OBJECT IDENTIFIER,
+ extnValue OCTET STRING }
+ */
+ if (getAsnSequence(&p, (uint32) (end - p), &len) < 0 ||
+ (uint32) (end - p) < len)
+ {
+ psTraceCrypto("Initial getAsnSequence failure in extension parse\n");
+ return PS_PARSE_FAIL;
+ }
+ extEnd = p + len;
+ while ((p != extEnd) && *p == (ASN_SEQUENCE | ASN_CONSTRUCTED))
+ {
+ if (getAsnSequence(&p, (uint32) (extEnd - p), &fullExtLen) < 0)
+ {
+ psTraceCrypto("getAsnSequence failure in extension parse\n");
+ return PS_PARSE_FAIL;
+ }
+ extStart = p;
/*
- Conforming CAs MUST support key identifiers, basic constraints,
- key usage, and certificate policies extensions
-*/
- if (extEnd - p < 1 || *p++ != ASN_OID) {
- psTraceCrypto("Malformed extension header\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnLength(&p, (uint32)(extEnd - p), &len) < 0 ||
- (uint32)(extEnd - p) < len) {
- psTraceCrypto("Malformed extension length\n");
- return PS_PARSE_FAIL;
- }
- if ((oidlen = psParseOid(p, len, oid)) < 1) {
- psTraceCrypto("Malformed extension OID\n");
- return PS_PARSE_FAIL;
- }
- noid = psFindOid(oid, oidlen);
- p += len;
+ Conforming CAs MUST support key identifiers, basic constraints,
+ key usage, and certificate policies extensions
+ */
+ if (extEnd - p < 1 || *p++ != ASN_OID)
+ {
+ psTraceCrypto("Malformed extension header\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnLength(&p, (uint32) (extEnd - p), &len) < 0 ||
+ (uint32) (extEnd - p) < len)
+ {
+ psTraceCrypto("Malformed extension length\n");
+ return PS_PARSE_FAIL;
+ }
+ if ((oidlen = asnParseOid(p, len, oid)) < 1)
+ {
+ psTraceCrypto("Malformed extension OID\n");
+ return PS_PARSE_FAIL;
+ }
+ noid = psFindOid(oid, oidlen);
+ p += len;
/*
- Possible boolean value here for 'critical' id. It's a failure if a
- critical extension is found that is not supported
-*/
- critical = 0;
- if (extEnd - p < 1) {
- psTraceCrypto("Malformed extension length\n");
- return PS_PARSE_FAIL;
- }
- if (*p == ASN_BOOLEAN) {
- p++;
- if (extEnd - p < 2) {
- psTraceCrypto("Error parsing critical id len for cert extension\n");
- return PS_PARSE_FAIL;
- }
- if (*p != 1) {
- psTraceCrypto("Error parsing critical id for cert extension\n");
- return PS_PARSE_FAIL;
- }
- p++;
- if (*p > 0) {
- /* Officially DER TRUE must be 0xFF, openssl is more lax */
- if (*p != 0xFF) {
- psTraceCrypto("Warning: DER BOOLEAN TRUE should be 0xFF\n");
- }
- critical = 1;
- }
- p++;
- }
- if (extEnd - p < 1 || (*p++ != ASN_OCTET_STRING) ||
- getAsnLength(&p, (uint32)(extEnd - p), &len) < 0 ||
- (uint32)(extEnd - p) < len) {
- psTraceCrypto("Expecting OCTET STRING in ext parse\n");
- return PS_PARSE_FAIL;
- }
+ Possible boolean value here for 'critical' id. It's a failure if a
+ critical extension is found that is not supported
+ */
+ critical = 0;
+ if (extEnd - p < 1)
+ {
+ psTraceCrypto("Malformed extension length\n");
+ return PS_PARSE_FAIL;
+ }
+ if (*p == ASN_BOOLEAN)
+ {
+ p++;
+ if (extEnd - p < 2)
+ {
+ psTraceCrypto("Error parsing critical id len for cert extension\n");
+ return PS_PARSE_FAIL;
+ }
+ if (*p != 1)
+ {
+ psTraceCrypto("Error parsing critical id for cert extension\n");
+ return PS_PARSE_FAIL;
+ }
+ p++;
+ if (*p > 0)
+ {
+ /* Officially DER TRUE must be 0xFF, openssl is more lax */
+ if (*p != 0xFF)
+ {
+ psTraceCrypto("Warning: DER BOOLEAN TRUE should be 0xFF\n");
+ }
+ critical = 1;
+ }
+ p++;
+ }
+ if (extEnd - p < 1 || (*p++ != ASN_OCTET_STRING) ||
+ getAsnLength(&p, (uint32) (extEnd - p), &len) < 0 ||
+ (uint32) (extEnd - p) < len)
+ {
+ psTraceCrypto("Expecting OCTET STRING in ext parse\n");
+ return PS_PARSE_FAIL;
+ }
- /* Set bits 1..9 to indicate criticality of known extensions */
- if (critical) {
- extensions->critFlags |= EXT_CRIT_FLAG(noid);
- }
+ /* Set bits 1..9 to indicate criticality of known extensions */
+ if (critical)
+ {
+ extensions->critFlags |= EXT_CRIT_FLAG(noid);
+ }
- switch (noid) {
+ switch (noid)
+ {
/*
- BasicConstraints ::= SEQUENCE {
- cA BOOLEAN DEFAULT FALSE,
- pathLenConstraint INTEGER (0..MAX) OPTIONAL }
-*/
- case OID_ENUM(id_ce_basicConstraints):
- if (getAsnSequence(&p, (uint32)(extEnd - p), &len) < 0) {
- psTraceCrypto("Error parsing BasicConstraints extension\n");
- return PS_PARSE_FAIL;
- }
+ BasicConstraints ::= SEQUENCE {
+ cA BOOLEAN DEFAULT FALSE,
+ pathLenConstraint INTEGER (0..MAX) OPTIONAL }
+ */
+ case OID_ENUM(id_ce_basicConstraints):
+ if (getAsnSequence(&p, (uint32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("Error parsing BasicConstraints extension\n");
+ return PS_PARSE_FAIL;
+ }
/*
- "This goes against PKIX guidelines but some CAs do it and some
- software requires this to avoid interpreting an end user
- certificate as a CA."
- - OpenSSL certificate configuration doc
+ "This goes against PKIX guidelines but some CAs do it and some
+ software requires this to avoid interpreting an end user
+ certificate as a CA."
+ - OpenSSL certificate configuration doc
- basicConstraints=CA:FALSE
-*/
- if (len == 0) {
- break;
- }
+ basicConstraints=CA:FALSE
+ */
+ if (len == 0)
+ {
+ extensions->bc.cA = CA_FALSE;
+ break;
+ }
/*
- Have seen some certs that don't include a cA bool.
-*/
- if (*p == ASN_BOOLEAN) {
- if (extEnd - p < 3) {
- psTraceCrypto("Error parsing BC extension\n");
- return PS_PARSE_FAIL;
- }
- p++;
- if (*p++ != 1) {
- psTraceCrypto("Error parse BasicConstraints CA bool\n");
- return PS_PARSE_FAIL;
- }
- /* Officially DER TRUE must be 0xFF, openssl is more lax */
- if (*p > 0 && *p != 0xFF) {
- psTraceCrypto("Warning: cA TRUE should be 0xFF\n");
- }
- if (*p > 0)
- extensions->bc.cA = CA_TRUE;
- else
- extensions->bc.cA = CA_FALSE;
- p++;
- } else {
- extensions->bc.cA = CA_FALSE;
- }
+ Have seen some certs that don't include a cA bool.
+ */
+ if (*p == ASN_BOOLEAN)
+ {
+ if (extEnd - p < 3)
+ {
+ psTraceCrypto("Error parsing BC extension\n");
+ return PS_PARSE_FAIL;
+ }
+ p++;
+ if (*p++ != 1)
+ {
+ psTraceCrypto("Error parse BasicConstraints CA bool\n");
+ return PS_PARSE_FAIL;
+ }
+ /* Officially DER TRUE must be 0xFF, openssl is more lax */
+ if (*p > 0 && *p != 0xFF)
+ {
+ psTraceCrypto("Warning: cA TRUE should be 0xFF\n");
+ }
+ if (*p > 0)
+ {
+ extensions->bc.cA = CA_TRUE;
+ }
+ else
+ {
+ extensions->bc.cA = CA_FALSE;
+ }
+ p++;
+ }
+ else
+ {
+ extensions->bc.cA = CA_FALSE;
+ }
/*
- Now need to check if there is a path constraint. Only makes
- sense if cA is true. If it's missing, there is no limit to
- the cert path
-*/
- if (*p == ASN_INTEGER) {
- if (getAsnInteger(&p, (uint32)(extEnd - p),
- &(extensions->bc.pathLenConstraint)) < 0) {
- psTraceCrypto("Error parsing BasicConstraints pathLen\n");
- return PS_PARSE_FAIL;
- }
- } else {
- extensions->bc.pathLenConstraint = -1;
- }
- break;
+ Now need to check if there is a path constraint. Only makes
+ sense if cA is true. If it's missing, there is no limit to
+ the cert path
+ */
+ if (*p == ASN_INTEGER)
+ {
+ if (getAsnInteger(&p, (uint32) (extEnd - p),
+ &(extensions->bc.pathLenConstraint)) < 0)
+ {
+ psTraceCrypto("Error parsing BasicConstraints pathLen\n");
+ return PS_PARSE_FAIL;
+ }
+ }
+ else
+ {
+ extensions->bc.pathLenConstraint = -1;
+ }
+ break;
- case OID_ENUM(id_ce_subjectAltName):
- if (getAsnSequence(&p, (uint32)(extEnd - p), &len) < 0) {
- psTraceCrypto("Error parsing altSubjectName extension\n");
- return PS_PARSE_FAIL;
- }
- /* NOTE: The final limit parameter was introduced for this
- case because a well known search engine site sends back
- about 7 KB worth of subject alt names and that has created
- memory problems for a couple users. Set the -1 here to
- something reasonable (5) if you've found yourself here
- for this memory reason */
- if (parseGeneralNames(pool, &p, len, extEnd, &extensions->san,
- -1) < 0) {
- psTraceCrypto("Error parsing altSubjectName names\n");
- return PS_PARSE_FAIL;
- }
+ case OID_ENUM(id_ce_subjectAltName):
+ if (getAsnSequence(&p, (uint32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("Error parsing altSubjectName extension\n");
+ return PS_PARSE_FAIL;
+ }
+ /* NOTE: The final limit parameter was introduced for this
+ case because a well known search engine site sends back
+ about 7 KB worth of subject alt names and that has created
+ memory problems for a couple users. Set the -1 here to
+ something reasonable (5) if you've found yourself here
+ for this memory reason */
+ if (parseGeneralNames(pool, &p, len, extEnd, &extensions->san,
+ -1) < 0)
+ {
+ psTraceCrypto("Error parsing altSubjectName names\n");
+ return PS_PARSE_FAIL;
+ }
- break;
+ break;
- case OID_ENUM(id_ce_keyUsage):
+ case OID_ENUM(id_ce_keyUsage):
/*
- KeyUsage ::= BIT STRING {
- digitalSignature (0),
- nonRepudiation (1),
- keyEncipherment (2),
- dataEncipherment (3),
- keyAgreement (4),
- keyCertSign (5),
- cRLSign (6),
- encipherOnly (7),
- decipherOnly (8) }
-*/
- if (*p++ != ASN_BIT_STRING) {
- psTraceCrypto("Error parsing keyUsage extension\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnLength(&p, (int32)(extEnd - p), &len) < 0 ||
- (uint32)(extEnd - p) < len) {
- psTraceCrypto("Malformed keyUsage extension\n");
- return PS_PARSE_FAIL;
- }
- if (len < 2) {
- psTraceCrypto("Malformed keyUsage extension\n");
- return PS_PARSE_FAIL;
- }
+ KeyUsage ::= BIT STRING {
+ digitalSignature (0),
+ nonRepudiation (1),
+ keyEncipherment (2),
+ dataEncipherment (3),
+ keyAgreement (4),
+ keyCertSign (5),
+ cRLSign (6),
+ encipherOnly (7),
+ decipherOnly (8) }
+ */
+ if (*p++ != ASN_BIT_STRING)
+ {
+ psTraceCrypto("Error parsing keyUsage extension\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnLength(&p, (int32) (extEnd - p), &len) < 0 ||
+ (uint32) (extEnd - p) < len)
+ {
+ psTraceCrypto("Malformed keyUsage extension\n");
+ return PS_PARSE_FAIL;
+ }
+ if (len < 2)
+ {
+ psTraceCrypto("Malformed keyUsage extension\n");
+ return PS_PARSE_FAIL;
+ }
/*
- If the lenth is <= 3, then there might be a
- KEY_USAGE_DECIPHER_ONLY (or maybe just some empty bytes).
-*/
- if (len >= 3) {
- if (p[2] == (KEY_USAGE_DECIPHER_ONLY >> 8) && p[0] == 7) {
- extensions->keyUsageFlags |= KEY_USAGE_DECIPHER_ONLY;
- }
- }
- extensions->keyUsageFlags |= p[1];
- p = p + len;
- break;
+ If the lenth is <= 3, then there might be a
+ KEY_USAGE_DECIPHER_ONLY (or maybe just some empty bytes).
+ */
+ if (len >= 3)
+ {
+ if (p[2] == (KEY_USAGE_DECIPHER_ONLY >> 8) && p[0] == 7)
+ {
+ extensions->keyUsageFlags |= KEY_USAGE_DECIPHER_ONLY;
+ }
+ }
+ extensions->keyUsageFlags |= p[1];
+ p = p + len;
+ break;
- case OID_ENUM(id_ce_extKeyUsage):
- if (getAsnSequence(&p, (int32)(extEnd - p), &fullExtLen) < 0) {
- psTraceCrypto("Error parsing authKeyId extension\n");
- return PS_PARSE_FAIL;
- }
- save = p;
- while (fullExtLen > 0) {
- if (*p++ != ASN_OID) {
- psTraceCrypto("Malformed extension header\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnLength(&p, fullExtLen, &len) < 0 ||
- fullExtLen < len) {
- psTraceCrypto("Malformed extension length\n");
- return PS_PARSE_FAIL;
- }
- if ((oidlen = psParseOid(p, len, oid)) < 1) {
- psTraceCrypto("Malformed extension OID\n");
- return PS_PARSE_FAIL;
- }
- noid = psFindOid(oid, oidlen);
- p += len;
- if (fullExtLen < (uint32)(p - save)) {
- psTraceCrypto("Inner OID parse fail EXTND_KEY_USAGE\n");
- return PS_PARSE_FAIL;
- }
- fullExtLen -= (p - save);
- save = p;
- switch (noid) {
- case OID_ENUM(id_kp_serverAuth):
- extensions->ekuFlags |= EXT_KEY_USAGE_TLS_SERVER_AUTH;
- break;
- case OID_ENUM(id_kp_clientAuth):
- extensions->ekuFlags |= EXT_KEY_USAGE_TLS_CLIENT_AUTH;
- break;
- case OID_ENUM(id_kp_codeSigning):
- extensions->ekuFlags |= EXT_KEY_USAGE_CODE_SIGNING;
- break;
- case OID_ENUM(id_kp_emailProtection):
- extensions->ekuFlags |= EXT_KEY_USAGE_EMAIL_PROTECTION;
- break;
- case OID_ENUM(id_kp_timeStamping):
- extensions->ekuFlags |= EXT_KEY_USAGE_TIME_STAMPING;
- break;
- case OID_ENUM(id_kp_OCSPSigning):
- extensions->ekuFlags |= EXT_KEY_USAGE_OCSP_SIGNING;
- break;
- case OID_ENUM(id_ce_eku_anyExtendedKeyUsage):
- extensions->ekuFlags |= EXT_KEY_USAGE_ANY;
- break;
- default:
- psTraceCrypto("WARNING: Unknown EXT_KEY_USAGE:");
- psTraceOid(oid, oidlen);
- break;
- } /* end switch */
- }
- break;
+ case OID_ENUM(id_ce_extKeyUsage):
+ if (getAsnSequence(&p, (int32) (extEnd - p), &fullExtLen) < 0)
+ {
+ psTraceCrypto("Error parsing authKeyId extension\n");
+ return PS_PARSE_FAIL;
+ }
+ save = p;
+ while (fullExtLen > 0)
+ {
+ if (*p++ != ASN_OID)
+ {
+ psTraceCrypto("Malformed extension header\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnLength(&p, fullExtLen, &len) < 0 ||
+ fullExtLen < len)
+ {
+ psTraceCrypto("Malformed extension length\n");
+ return PS_PARSE_FAIL;
+ }
+ if ((oidlen = asnParseOid(p, len, oid)) < 1)
+ {
+ psTraceCrypto("Malformed extension OID\n");
+ return PS_PARSE_FAIL;
+ }
+ noid = psFindOid(oid, oidlen);
+ p += len;
+ if (fullExtLen < (uint32) (p - save))
+ {
+ psTraceCrypto("Inner OID parse fail EXTND_KEY_USAGE\n");
+ return PS_PARSE_FAIL;
+ }
+ fullExtLen -= (p - save);
+ save = p;
+ switch (noid)
+ {
+ case OID_ENUM(id_kp_serverAuth):
+ extensions->ekuFlags |= EXT_KEY_USAGE_TLS_SERVER_AUTH;
+ break;
+ case OID_ENUM(id_kp_clientAuth):
+ extensions->ekuFlags |= EXT_KEY_USAGE_TLS_CLIENT_AUTH;
+ break;
+ case OID_ENUM(id_kp_codeSigning):
+ extensions->ekuFlags |= EXT_KEY_USAGE_CODE_SIGNING;
+ break;
+ case OID_ENUM(id_kp_emailProtection):
+ extensions->ekuFlags |= EXT_KEY_USAGE_EMAIL_PROTECTION;
+ break;
+ case OID_ENUM(id_kp_timeStamping):
+ extensions->ekuFlags |= EXT_KEY_USAGE_TIME_STAMPING;
+ break;
+ case OID_ENUM(id_kp_OCSPSigning):
+ extensions->ekuFlags |= EXT_KEY_USAGE_OCSP_SIGNING;
+ break;
+ case OID_ENUM(id_ce_eku_anyExtendedKeyUsage):
+ extensions->ekuFlags |= EXT_KEY_USAGE_ANY;
+ break;
+ default:
+ psTraceCrypto("WARNING: Unknown EXT_KEY_USAGE:");
+ psTraceOid(oid, oidlen);
+ break;
+ } /* end switch */
+ }
+ break;
-#ifdef USE_FULL_CERT_PARSE
+# ifdef USE_FULL_CERT_PARSE
- case OID_ENUM(id_ce_nameConstraints):
- if (critical) {
- /* We're going to fail if critical since no real
- pattern matching is happening yet */
- psTraceCrypto("ERROR: critical nameConstraints unsupported\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnSequence(&p, (int32)(extEnd - p), &fullExtLen) < 0) {
- psTraceCrypto("Error parsing authKeyId extension\n");
- return PS_PARSE_FAIL;
- }
- while (fullExtLen > 0) {
- save = p;
+ case OID_ENUM(id_ce_nameConstraints):
+ if (critical)
+ {
+ /* We're going to fail if critical since no real
+ pattern matching is happening yet */
+ psTraceCrypto("ERROR: critical nameConstraints unsupported\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnSequence(&p, (int32) (extEnd - p), &fullExtLen) < 0)
+ {
+ psTraceCrypto("Error parsing authKeyId extension\n");
+ return PS_PARSE_FAIL;
+ }
+ while (fullExtLen > 0)
+ {
+ save = p;
- if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
- /* permittedSubtrees */
- p++;
- nc = 0;
- }
- if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
- /* excludedSubtrees */
- p++;
- nc = 1;
- }
- subExtLen = 0;
- if (getAsnLength(&p, (uint32)(extEnd - p), &subExtLen) < 0 ||
- subExtLen < 1 || (uint32)(extEnd - p) < subExtLen) {
- psTraceCrypto("ASN get len error in nameConstraint\n");
- return PS_PARSE_FAIL;
- }
- if (fullExtLen < (subExtLen + (p - save))) {
- psTraceCrypto("fullExtLen parse fail nameConstraint\n");
- return PS_PARSE_FAIL;
- }
- fullExtLen -= subExtLen + (p - save);
- while (subExtLen > 0) {
- subSave = p;
- if (getAsnSequence(&p, (int32)(extEnd - p), &len) < 0) {
- psTraceCrypto("Error parsing nameConst ext\n");
- return PS_PARSE_FAIL;
- }
- if (subExtLen < (len + (p - subSave))) {
- psTraceCrypto("subExtLen fail nameConstraint\n");
- return PS_PARSE_FAIL;
- }
- subExtLen -= len + (p - subSave);
- if (nc == 0) {
- if (parseGeneralNames(pool, &p, len, extEnd,
- &extensions->nameConstraints.permitted, -1) <0){
- psTraceCrypto("Error parsing nameConstraint\n");
- return PS_PARSE_FAIL;
- }
- } else {
- if (parseGeneralNames(pool, &p, len, extEnd,
- &extensions->nameConstraints.excluded, -1) < 0){
- psTraceCrypto("Error parsing nameConstraint\n");
- return PS_PARSE_FAIL;
- }
- }
- }
- }
- break;
+ if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
+ {
+ /* permittedSubtrees */
+ p++;
+ nc = 0;
+ }
+ if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
+ {
+ /* excludedSubtrees */
+ p++;
+ nc = 1;
+ }
+ subExtLen = 0;
+ if (getAsnLength(&p, (uint32) (extEnd - p), &subExtLen) < 0 ||
+ subExtLen < 1 || (uint32) (extEnd - p) < subExtLen)
+ {
+ psTraceCrypto("ASN get len error in nameConstraint\n");
+ return PS_PARSE_FAIL;
+ }
+ if (fullExtLen < (subExtLen + (p - save)))
+ {
+ psTraceCrypto("fullExtLen parse fail nameConstraint\n");
+ return PS_PARSE_FAIL;
+ }
+ fullExtLen -= subExtLen + (p - save);
+ while (subExtLen > 0)
+ {
+ subSave = p;
+ if (getAsnSequence(&p, (int32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("Error parsing nameConst ext\n");
+ return PS_PARSE_FAIL;
+ }
+ if (subExtLen < (len + (p - subSave)))
+ {
+ psTraceCrypto("subExtLen fail nameConstraint\n");
+ return PS_PARSE_FAIL;
+ }
+ subExtLen -= len + (p - subSave);
+ if (nc == 0)
+ {
+ if (parseGeneralNames(pool, &p, len, extEnd,
+ &extensions->nameConstraints.permitted, -1) < 0)
+ {
+ psTraceCrypto("Error parsing nameConstraint\n");
+ return PS_PARSE_FAIL;
+ }
+ }
+ else
+ {
+ if (parseGeneralNames(pool, &p, len, extEnd,
+ &extensions->nameConstraints.excluded, -1) < 0)
+ {
+ psTraceCrypto("Error parsing nameConstraint\n");
+ return PS_PARSE_FAIL;
+ }
+ }
+ }
+ }
+ break;
-#ifdef USE_CRL
- case OID_ENUM(id_ce_cRLNumber):
- /* A required extension within a CRL. Our getSerialNum is
- the version of getInteger that allows very large
- numbers. Spec says this could be 20 octets long */
- if (getSerialNum(pool, &p, (int32)(extEnd - p),
- &(extensions->crlNum), &len) < 0) {
- psTraceCrypto("Error parsing ak.serialNum\n");
- return PS_PARSE_FAIL;
- }
- extensions->crlNumLen = len;
- break;
-
- case OID_ENUM(id_ce_issuingDistributionPoint):
- /* RFC 3280 - Although the extension is critical, conforming
- implementations are not required to support this extension. */
- p++;
- p = p + (fullExtLen - (p - extStart));
- break;
-
- case OID_ENUM(id_ce_cRLDistributionPoints):
- if (getAsnSequence(&p, (int32)(extEnd - p), &fullExtLen) < 0) {
- psTraceCrypto("Error parsing authKeyId extension\n");
- return PS_PARSE_FAIL;
- }
+# ifdef USE_CRL
+ case OID_ENUM(id_ce_cRLNumber):
+ /* A required extension within a CRL. Our getSerialNum is
+ the version of getInteger that allows very large
+ numbers. Spec says this could be 20 octets long */
+ if (getSerialNum(pool, &p, (int32) (extEnd - p),
+ &(extensions->crlNum), &len) < 0)
+ {
+ psTraceCrypto("Error parsing ak.serialNum\n");
+ return PS_PARSE_FAIL;
+ }
+ extensions->crlNumLen = len;
+ break;
- while (fullExtLen > 0) {
- save = p;
- if (getAsnSequence(&p, (uint32)(extEnd - p), &len) < 0) {
- psTraceCrypto("getAsnSequence fail in crldist parse\n");
- return PS_PARSE_FAIL;
- }
- if (fullExtLen < (len + (p - save))) {
- psTraceCrypto("fullExtLen parse fail crldist\n");
- return PS_PARSE_FAIL;
- }
- fullExtLen -= len + (p - save);
- /* All memebers are optional */
- if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
- /* DistributionPointName */
- p++;
- if (getAsnLength(&p, (uint32)(extEnd - p), &len) < 0 ||
- len < 1 || (uint32)(extEnd - p) < len) {
- psTraceCrypto("ASN get len error in CRL extension\n");
- return PS_PARSE_FAIL;
- }
+ case OID_ENUM(id_ce_issuingDistributionPoint):
+ /* RFC 3280 - Although the extension is critical, conforming
+ implementations are not required to support this extension. */
+ p++;
+ p = p + (fullExtLen - (p - extStart));
+ break;
- if ((*p & 0xF) == 0) { /* fullName (GeneralNames) */
- p++;
- if (getAsnLength(&p, (uint32)(extEnd - p), &len) < 0
- || len < 1 || (uint32)(extEnd - p) < len) {
- psTraceCrypto("ASN get len error in CRL extension\n");
- return PS_PARSE_FAIL;
- }
- if (parseGeneralNames(pool, &p, len, extEnd,
- &extensions->crlDist, -1) > 0) {
- psTraceCrypto("dist gen name parse fail\n");
- return PS_PARSE_FAIL;
- }
- } else if ((*p & 0xF) == 1) { /* RelativeDistName */
- p++;
- /* RelativeDistName not parsed */
- if (getAsnLength(&p, (uint32)(extEnd - p), &len) < 0
- || len < 1 || (uint32)(extEnd - p) < len) {
- psTraceCrypto("ASN get len error in CRL extension\n");
- return PS_PARSE_FAIL;
- }
- p += len;
- } else {
- psTraceCrypto("DistributionPointName parse fail\n");
- return PS_PARSE_FAIL;
- }
- }
- if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
- p++;
- /* ReasonFlags not parsed */
- if (getAsnLength(&p, (uint32)(extEnd - p), &len) < 0 ||
- len < 1 || (uint32)(extEnd - p) < len) {
- psTraceCrypto("ASN get len error in CRL extension\n");
- return PS_PARSE_FAIL;
- }
- p += len;
- }
- if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) {
- p++;
- /* General Names not parsed */
- if (getAsnLength(&p, (uint32)(extEnd - p), &len) < 0 ||
- len < 1 || (uint32)(extEnd - p) < len) {
- psTraceCrypto("ASN get len error in CRL extension\n");
- return PS_PARSE_FAIL;
- }
- p += len;
- }
- }
- break;
- case OID_ENUM(id_pe_authorityInfoAccess):
- if (parseAuthorityInfoAccess(pool, p,
- extEnd,
- &extensions->authorityInfoAccess,
- &len) < 0) {
- return PS_PARSE_FAIL;
- }
- p += len;
- break;
-#endif /* USE_CRL */
-#endif /* FULL_CERT_PARSE */
+ case OID_ENUM(id_ce_cRLDistributionPoints):
+ if (getAsnSequence(&p, (int32) (extEnd - p), &fullExtLen) < 0)
+ {
+ psTraceCrypto("Error parsing authKeyId extension\n");
+ return PS_PARSE_FAIL;
+ }
- case OID_ENUM(id_ce_authorityKeyIdentifier):
+ while (fullExtLen > 0)
+ {
+ save = p;
+ if (getAsnSequence(&p, (uint32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("getAsnSequence fail in crldist parse\n");
+ return PS_PARSE_FAIL;
+ }
+ if (fullExtLen < (len + (p - save)))
+ {
+ psTraceCrypto("fullExtLen parse fail crldist\n");
+ return PS_PARSE_FAIL;
+ }
+ fullExtLen -= len + (p - save);
+ /* All memebers are optional */
+ if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
+ {
+ /* DistributionPointName */
+ p++;
+ if (getAsnLength(&p, (uint32) (extEnd - p), &len) < 0 ||
+ len < 1 || (uint32) (extEnd - p) < len)
+ {
+ psTraceCrypto("ASN get len error in CRL extension\n");
+ return PS_PARSE_FAIL;
+ }
+
+ if ((*p & 0xF) == 0) /* fullName (GeneralNames) */
+ {
+ p++;
+ if (getAsnLength(&p, (uint32) (extEnd - p), &len) < 0
+ || len < 1 || (uint32) (extEnd - p) < len)
+ {
+ psTraceCrypto("ASN get len error in CRL extension\n");
+ return PS_PARSE_FAIL;
+ }
+ if (parseGeneralNames(pool, &p, len, extEnd,
+ &extensions->crlDist, -1) > 0)
+ {
+ psTraceCrypto("dist gen name parse fail\n");
+ return PS_PARSE_FAIL;
+ }
+ }
+ else if ((*p & 0xF) == 1) /* RelativeDistName */
+ {
+ p++;
+ /* RelativeDistName not parsed */
+ if (getAsnLength(&p, (uint32) (extEnd - p), &len) < 0
+ || len < 1 || (uint32) (extEnd - p) < len)
+ {
+ psTraceCrypto("ASN get len error in CRL extension\n");
+ return PS_PARSE_FAIL;
+ }
+ p += len;
+ }
+ else
+ {
+ psTraceCrypto("DistributionPointName parse fail\n");
+ return PS_PARSE_FAIL;
+ }
+ }
+ if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
+ {
+ p++;
+ /* ReasonFlags not parsed */
+ if (getAsnLength(&p, (uint32) (extEnd - p), &len) < 0 ||
+ len < 1 || (uint32) (extEnd - p) < len)
+ {
+ psTraceCrypto("ASN get len error in CRL extension\n");
+ return PS_PARSE_FAIL;
+ }
+ p += len;
+ }
+ if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2))
+ {
+ p++;
+ /* General Names not parsed */
+ if (getAsnLength(&p, (uint32) (extEnd - p), &len) < 0 ||
+ len < 1 || (uint32) (extEnd - p) < len)
+ {
+ psTraceCrypto("ASN get len error in CRL extension\n");
+ return PS_PARSE_FAIL;
+ }
+ p += len;
+ }
+ }
+ break;
+ case OID_ENUM(id_pe_authorityInfoAccess):
+ if (parseAuthorityInfoAccess(pool, p,
+ extEnd,
+ &extensions->authorityInfoAccess,
+ &len) < 0)
+ {
+ return PS_PARSE_FAIL;
+ }
+ p += len;
+ break;
+# endif /* USE_CRL */
+# endif /* FULL_CERT_PARSE */
+
+ case OID_ENUM(id_ce_authorityKeyIdentifier):
/*
- AuthorityKeyIdentifier ::= SEQUENCE {
- keyIdentifier [0] KeyIdentifier OPTIONAL,
- authorityCertIssuer [1] GeneralNames OPTIONAL,
- authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
+ AuthorityKeyIdentifier ::= SEQUENCE {
+ keyIdentifier [0] KeyIdentifier OPTIONAL,
+ authorityCertIssuer [1] GeneralNames OPTIONAL,
+ authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
- KeyIdentifier ::= OCTET STRING
-*/
- if (getAsnSequence(&p, (int32)(extEnd - p), &len) < 0) {
- psTraceCrypto("Error parsing authKeyId extension\n");
- return PS_PARSE_FAIL;
- }
- /* Have seen a cert that has a zero length ext here. Let it pass. */
- if (len == 0) {
- break;
- }
- /* All members are optional */
- if (*p == (ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE | 0)) {
- p++;
- if (getAsnLength(&p, (int32)(extEnd - p),
- &extensions->ak.keyLen) < 0 ||
- (uint32)(extEnd - p) < extensions->ak.keyLen) {
- psTraceCrypto("Error keyLen in authKeyId extension\n");
- return PS_PARSE_FAIL;
- }
- extensions->ak.keyId = psMalloc(pool, extensions->ak.keyLen);
- if (extensions->ak.keyId == NULL) {
- psError("Mem allocation err: extensions->ak.keyId\n");
- return PS_MEM_FAIL;
- }
- memcpy(extensions->ak.keyId, p, extensions->ak.keyLen);
- p = p + extensions->ak.keyLen;
- }
- if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
- p++;
- if (getAsnLength(&p, (int32)(extEnd - p), &len) < 0 ||
- len < 1 || (uint32)(extEnd - p) < len) {
- psTraceCrypto("ASN get len error in authKeyId extension\n");
- return PS_PARSE_FAIL;
- }
- if ((*p ^ ASN_CONTEXT_SPECIFIC ^ ASN_CONSTRUCTED) != 4) {
- /* We are just dealing with DN formats here */
- psTraceIntCrypto("Error auth key-id name type: %d\n",
- *p ^ ASN_CONTEXT_SPECIFIC ^ ASN_CONSTRUCTED);
- return PS_PARSE_FAIL;
- }
- p++;
- if (getAsnLength(&p, (int32)(extEnd - p), &len) < 0 ||
- (uint32)(extEnd - p) < len) {
- psTraceCrypto("ASN get len error2 in authKeyId extension\n");
- return PS_PARSE_FAIL;
- }
- if (psX509GetDNAttributes(pool, &p, (int32)(extEnd - p),
- &(extensions->ak.attribs), 0) < 0) {
- psTraceCrypto("Error parsing ak.attribs\n");
- return PS_PARSE_FAIL;
- }
- }
- if ((*p == (ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE | 2)) ||
- (*p == ASN_INTEGER)){
+ KeyIdentifier ::= OCTET STRING
+ */
+ if (getAsnSequence(&p, (int32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("Error parsing authKeyId extension\n");
+ return PS_PARSE_FAIL;
+ }
+ /* Have seen a cert that has a zero length ext here. Let it pass. */
+ if (len == 0)
+ {
+ break;
+ }
+ /* All members are optional */
+ if (*p == (ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE | 0))
+ {
+ p++;
+ if (getAsnLength(&p, (int32) (extEnd - p),
+ &extensions->ak.keyLen) < 0 ||
+ (uint32) (extEnd - p) < extensions->ak.keyLen)
+ {
+ psTraceCrypto("Error keyLen in authKeyId extension\n");
+ return PS_PARSE_FAIL;
+ }
+ extensions->ak.keyId = psMalloc(pool, extensions->ak.keyLen);
+ if (extensions->ak.keyId == NULL)
+ {
+ psError("Mem allocation err: extensions->ak.keyId\n");
+ return PS_MEM_FAIL;
+ }
+ memcpy(extensions->ak.keyId, p, extensions->ak.keyLen);
+ p = p + extensions->ak.keyLen;
+ }
+ if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
+ {
+ p++;
+ if (getAsnLength(&p, (int32) (extEnd - p), &len) < 0 ||
+ len < 1 || (uint32) (extEnd - p) < len)
+ {
+ psTraceCrypto("ASN get len error in authKeyId extension\n");
+ return PS_PARSE_FAIL;
+ }
+ if ((*p ^ ASN_CONTEXT_SPECIFIC ^ ASN_CONSTRUCTED) != 4)
+ {
+ /* We are just dealing with DN formats here */
+ psTraceIntCrypto("Error auth key-id name type: %d\n",
+ *p ^ ASN_CONTEXT_SPECIFIC ^ ASN_CONSTRUCTED);
+ return PS_PARSE_FAIL;
+ }
+ p++;
+ if (getAsnLength(&p, (int32) (extEnd - p), &len) < 0 ||
+ (uint32) (extEnd - p) < len)
+ {
+ psTraceCrypto("ASN get len error2 in authKeyId extension\n");
+ return PS_PARSE_FAIL;
+ }
+ if (psX509GetDNAttributes(pool, &p, (int32) (extEnd - p),
+ &(extensions->ak.attribs), 0) < 0)
+ {
+ psTraceCrypto("Error parsing ak.attribs\n");
+ return PS_PARSE_FAIL;
+ }
+ }
+ if ((*p == (ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE | 2)) ||
+ (*p == ASN_INTEGER))
+ {
/*
- Treat as a serial number (not a native INTEGER)
-*/
- if (getSerialNum(pool, &p, (int32)(extEnd - p),
- &(extensions->ak.serialNum), &len) < 0) {
- psTraceCrypto("Error parsing ak.serialNum\n");
- return PS_PARSE_FAIL;
- }
- extensions->ak.serialNumLen = len;
- }
- break;
+ Treat as a serial number (not a native INTEGER)
+ */
+ if (getSerialNum(pool, &p, (int32) (extEnd - p),
+ &(extensions->ak.serialNum), &len) < 0)
+ {
+ psTraceCrypto("Error parsing ak.serialNum\n");
+ return PS_PARSE_FAIL;
+ }
+ extensions->ak.serialNumLen = len;
+ }
+ break;
- case OID_ENUM(id_ce_subjectKeyIdentifier):
+ case OID_ENUM(id_ce_subjectKeyIdentifier):
/*
- The value of the subject key identifier MUST be the value
- placed in the key identifier field of the Auth Key Identifier
- extension of certificates issued by the subject of
- this certificate.
-*/
- if (*p++ != ASN_OCTET_STRING || getAsnLength(&p,
- (int32)(extEnd - p), &(extensions->sk.len)) < 0 ||
- (uint32)(extEnd - p) < extensions->sk.len) {
- psTraceCrypto("Error parsing subjectKeyId extension\n");
- return PS_PARSE_FAIL;
- }
- extensions->sk.id = psMalloc(pool, extensions->sk.len);
- if (extensions->sk.id == NULL) {
- psError("Memory allocation error extensions->sk.id\n");
- return PS_MEM_FAIL;
- }
- memcpy(extensions->sk.id, p, extensions->sk.len);
- p = p + extensions->sk.len;
- break;
-#ifdef USE_FULL_CERT_PARSE
+ The value of the subject key identifier MUST be the value
+ placed in the key identifier field of the Auth Key Identifier
+ extension of certificates issued by the subject of
+ this certificate.
+ */
+ if (*p++ != ASN_OCTET_STRING || getAsnLength(&p,
+ (int32) (extEnd - p), &(extensions->sk.len)) < 0 ||
+ (uint32) (extEnd - p) < extensions->sk.len)
+ {
+ psTraceCrypto("Error parsing subjectKeyId extension\n");
+ return PS_PARSE_FAIL;
+ }
+ extensions->sk.id = psMalloc(pool, extensions->sk.len);
+ if (extensions->sk.id == NULL)
+ {
+ psError("Memory allocation error extensions->sk.id\n");
+ return PS_MEM_FAIL;
+ }
+ memcpy(extensions->sk.id, p, extensions->sk.len);
+ p = p + extensions->sk.len;
+ break;
+# ifdef USE_FULL_CERT_PARSE
- case OID_ENUM(id_ce_certificatePolicies):
+ case OID_ENUM(id_ce_certificatePolicies):
/*
certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
-*/
- /* Parse certificatePolicies := SEQUENCE SIZE (1..MAX) OF
- PolicyInformation. */
- if (getAsnSequence(&p, (uint32)(extEnd - p), &len) < 0) {
- psTraceCrypto("Error parsing certificatePolicies extension\n");
- return PS_PARSE_FAIL;
- }
- policiesEnd = p + len;
- extensions->certificatePolicy.policy
- = psMalloc(pool, sizeof(x509PolicyInformation_t));
- memset(extensions->certificatePolicy.policy, 0,
- sizeof(x509PolicyInformation_t));
- pPolicy = extensions->certificatePolicy.policy;
-
- /* Parse a single PolicyInformation. */
- if (parsePolicyInformation(pool, p, extEnd, fullExtLen,
- pPolicy, &len) < 0) {
- return PS_PARSE_FAIL;
- }
- p += len;
-
- /* Parse further PolicyInformations, if present. */
- while ((p < policiesEnd)
- && (p < extEnd)
- && (*p == (ASN_SEQUENCE | ASN_CONSTRUCTED))) {
-
- pPolicy->next = psMalloc(pool, sizeof(x509PolicyInformation_t));
- memset(pPolicy->next, 0, sizeof(x509PolicyInformation_t));
- pPolicy = pPolicy->next;
- if (parsePolicyInformation(pool, p, extEnd, fullExtLen,
- pPolicy, &len) < 0) {
- return PS_PARSE_FAIL;
- }
- p += len;
- } /* End or PolicyInformation parsing. */
- break;
- case OID_ENUM(id_ce_policyConstraints):
- if (parsePolicyConstraints(pool, p,
- extEnd,
- &extensions->policyConstraints,
- &len) < 0) {
- return PS_PARSE_FAIL;
- }
- p += len;
- break;
- case OID_ENUM(id_ce_policyMappings):
- extensions->policyMappings = psMalloc(pool,
- sizeof(x509policyMappings_t));
- memset(extensions->policyMappings, 0, sizeof(x509policyMappings_t));
- if (parsePolicyMappings(pool, p,
- extEnd,
- extensions->policyMappings,
- &len) < 0) {
- return PS_PARSE_FAIL;
- }
-
- p += len;
- break;
- case OID_ENUM(id_ce_issuerAltName):
- if (getAsnSequence(&p, (uint32)(extEnd - p), &len) < 0) {
- psTraceCrypto("Error parsing issuerAltName extension\n");
- return PS_PARSE_FAIL;
- }
- /* NOTE: The final limit parameter was introduced for this
- case because a well known search engine site sends back
- about 7 KB worth of subject alt names and that has created
- memory problems for a couple users. Set the -1 here to
- something reasonable (5) if you've found yourself here
- for this memory reason */
- if (parseGeneralNames(pool, &p, len, extEnd, &extensions->issuerAltName,
- -1) < 0) {
- psTraceCrypto("Error parsing altSubjectName names\n");
- return PS_PARSE_FAIL;
- }
- break;
-#endif /* USE_FULL_CERT_PARSE */
- /* These extensions are known but not handled */
- case OID_ENUM(id_ce_subjectDirectoryAttributes):
- case OID_ENUM(id_ce_inhibitAnyPolicy):
- case OID_ENUM(id_ce_freshestCRL):
- case OID_ENUM(id_pe_subjectInfoAccess):
- default:
- /* Unsupported or skipping because USE_FULL_CERT_PARSE undefd */
- if (critical) {
- psTraceCrypto("Unsupported critical ext encountered: ");
- psTraceOid(oid, oidlen);
-#ifndef ALLOW_UNKNOWN_CRITICAL_EXTENSIONS
- _psTrace("An unsupported critical extension was "
- "encountered. X.509 specifications say "
- "connections must be terminated in this case. "
- "Define ALLOW_UNKNOWN_CRITICAL_EXTENSIONS to "
- "bypass this rule if testing and email Inside "
- "support to inquire about this extension.\n\n");
- return PS_PARSE_FAIL;
-#else
-#ifdef WIN32
-#pragma message("IGNORING UNKNOWN CRITICAL EXTENSIONS IS A SECURITY RISK")
-#else
-#warning "IGNORING UNKNOWN CRITICAL EXTENSIONS IS A SECURITY RISK"
-#endif
-#endif
- }
- p++;
-/*
- Skip over based on the length reported from the ASN_SEQUENCE
- surrounding the entire extension. It is not a guarantee that
- the value of the extension itself will contain it's own length.
-*/
- p = p + (fullExtLen - (p - extStart));
- break;
- }
- }
- *pp = p;
- return 0;
-}
-
-/******************************************************************************/
-/*
- Although a certificate serial number is encoded as an integer type, that
- doesn't prevent it from being abused as containing a variable length
- binary value. Get it here.
-*/
-int32_t getSerialNum(psPool_t *pool, const unsigned char **pp, uint16_t len,
- unsigned char **sn, uint16_t *snLen)
-{
- const unsigned char *p = *pp;
- uint16_t vlen;
-
- if ((*p != (ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE | 2)) &&
- (*p != ASN_INTEGER)) {
- psTraceCrypto("X.509 getSerialNum failed on first bytes\n");
- return PS_PARSE_FAIL;
- }
- p++;
-
- if (len < 1 || getAsnLength(&p, len - 1, &vlen) < 0 || (len - 1) < vlen) {
- psTraceCrypto("ASN getSerialNum failed\n");
- return PS_PARSE_FAIL;
- }
- *snLen = vlen;
-
- if (vlen > 0) {
- *sn = psMalloc(pool, vlen);
- if (*sn == NULL) {
- psError("Memory allocation failure in getSerialNum\n");
- return PS_MEM_FAIL;
- }
- memcpy(*sn, p, vlen);
- p += vlen;
- }
- *pp = p;
- return PS_SUCCESS;
-}
-
-/******************************************************************************/
-/**
- Explicit value encoding has an additional tag layer.
*/
-static int32_t getExplicitVersion(const unsigned char **pp, uint16_t len,
- int32_t expVal, int32_t *val)
-{
- const unsigned char *p = *pp;
- uint16_t exLen;
+ /* Parse certificatePolicies := SEQUENCE SIZE (1..MAX) OF
+ PolicyInformation. */
+ if (getAsnSequence(&p, (uint32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("Error parsing certificatePolicies extension\n");
+ return PS_PARSE_FAIL;
+ }
+ policiesEnd = p + len;
+ extensions->certificatePolicy.policy
+ = psMalloc(pool, sizeof(x509PolicyInformation_t));
+ memset(extensions->certificatePolicy.policy, 0,
+ sizeof(x509PolicyInformation_t));
+ pPolicy = extensions->certificatePolicy.policy;
- if (len < 1) {
- psTraceCrypto("Invalid length to getExplicitVersion\n");
- return PS_PARSE_FAIL;
- }
+ /* Parse a single PolicyInformation. */
+ if (parsePolicyInformation(pool, p, extEnd, fullExtLen,
+ pPolicy, &len) < 0)
+ {
+ return PS_PARSE_FAIL;
+ }
+ p += len;
+
+ /* Parse further PolicyInformations, if present. */
+ while ((p < policiesEnd)
+ && (p < extEnd)
+ && (*p == (ASN_SEQUENCE | ASN_CONSTRUCTED)))
+ {
+
+ pPolicy->next = psMalloc(pool, sizeof(x509PolicyInformation_t));
+ memset(pPolicy->next, 0, sizeof(x509PolicyInformation_t));
+ pPolicy = pPolicy->next;
+ if (parsePolicyInformation(pool, p, extEnd, fullExtLen,
+ pPolicy, &len) < 0)
+ {
+ return PS_PARSE_FAIL;
+ }
+ p += len;
+ } /* End or PolicyInformation parsing. */
+ break;
+ case OID_ENUM(id_ce_policyConstraints):
+ if (parsePolicyConstraints(pool, p,
+ extEnd,
+ &extensions->policyConstraints,
+ &len) < 0)
+ {
+ return PS_PARSE_FAIL;
+ }
+ p += len;
+ break;
+ case OID_ENUM(id_ce_policyMappings):
+ extensions->policyMappings = psMalloc(pool,
+ sizeof(x509policyMappings_t));
+ memset(extensions->policyMappings, 0, sizeof(x509policyMappings_t));
+ if (parsePolicyMappings(pool, p,
+ extEnd,
+ extensions->policyMappings,
+ &len) < 0)
+ {
+ return PS_PARSE_FAIL;
+ }
+
+ p += len;
+ break;
+ case OID_ENUM(id_ce_issuerAltName):
+ if (getAsnSequence(&p, (uint32) (extEnd - p), &len) < 0)
+ {
+ psTraceCrypto("Error parsing issuerAltName extension\n");
+ return PS_PARSE_FAIL;
+ }
+ /* NOTE: The final limit parameter was introduced for this
+ case because a well known search engine site sends back
+ about 7 KB worth of subject alt names and that has created
+ memory problems for a couple users. Set the -1 here to
+ something reasonable (5) if you've found yourself here
+ for this memory reason */
+ if (parseGeneralNames(pool, &p, len, extEnd, &extensions->issuerAltName,
+ -1) < 0)
+ {
+ psTraceCrypto("Error parsing altSubjectName names\n");
+ return PS_PARSE_FAIL;
+ }
+ break;
+# endif /* USE_FULL_CERT_PARSE */
+ /* These extensions are known but not handled */
+ case OID_ENUM(id_ce_subjectDirectoryAttributes):
+ case OID_ENUM(id_ce_inhibitAnyPolicy):
+ case OID_ENUM(id_ce_freshestCRL):
+ case OID_ENUM(id_pe_subjectInfoAccess):
+ default:
+ /* Unsupported or skipping because USE_FULL_CERT_PARSE undefd */
+ if (critical)
+ {
+ psTraceCrypto("Unsupported critical ext encountered: ");
+ psTraceOid(oid, oidlen);
+# ifndef ALLOW_UNKNOWN_CRITICAL_EXTENSIONS
+ _psTrace("An unsupported critical extension was "
+ "encountered. X.509 specifications say "
+ "connections must be terminated in this case. "
+ "Define ALLOW_UNKNOWN_CRITICAL_EXTENSIONS to "
+ "bypass this rule if testing and email Inside "
+ "support to inquire about this extension.\n");
+ return PS_PARSE_FAIL;
+# else
+# ifdef WIN32
+# pragma message("IGNORING UNKNOWN CRITICAL EXTENSIONS IS A SECURITY RISK")
+# else
+# warning "IGNORING UNKNOWN CRITICAL EXTENSIONS IS A SECURITY RISK"
+# endif
+# endif
+ }
+ p++;
/*
- This is an optional value, so don't error if not present. The default
- value is version 1
-*/
- if (*p != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | expVal)) {
- *val = 0;
- return PS_SUCCESS;
- }
- p++;
- if (getAsnLength(&p, len - 1, &exLen) < 0 || (len - 1) < exLen) {
- psTraceCrypto("getAsnLength failure in getExplicitVersion\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnInteger(&p, exLen, val) < 0) {
- psTraceCrypto("getAsnInteger failure in getExplicitVersion\n");
- return PS_PARSE_FAIL;
- }
- *pp = p;
- return PS_SUCCESS;
+ Skip over based on the length reported from the ASN_SEQUENCE
+ surrounding the entire extension. It is not a guarantee that
+ the value of the extension itself will contain it's own length.
+ */
+ p = p + (fullExtLen - (p - extStart));
+ break;
+ }
+ }
+ *pp = p;
+ return 0;
+}
+
+/******************************************************************************/
+/*
+ Although a certificate serial number is encoded as an integer type, that
+ doesn't prevent it from being abused as containing a variable length
+ binary value. Get it here.
+ */
+int32_t getSerialNum(psPool_t *pool, const unsigned char **pp, psSize_t len,
+ unsigned char **sn, psSize_t *snLen)
+{
+ const unsigned char *p = *pp;
+ psSize_t vlen;
+
+ if ((*p != (ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE | 2)) &&
+ (*p != ASN_INTEGER))
+ {
+ psTraceCrypto("X.509 getSerialNum failed on first bytes\n");
+ return PS_PARSE_FAIL;
+ }
+ p++;
+
+ if (len < 1 || getAsnLength(&p, len - 1, &vlen) < 0 || (len - 1) < vlen)
+ {
+ psTraceCrypto("ASN getSerialNum failed\n");
+ return PS_PARSE_FAIL;
+ }
+ *snLen = vlen;
+
+ if (vlen > 0)
+ {
+ *sn = psMalloc(pool, vlen);
+ if (*sn == NULL)
+ {
+ psError("Memory allocation failure in getSerialNum\n");
+ return PS_MEM_FAIL;
+ }
+ memcpy(*sn, p, vlen);
+ p += vlen;
+ }
+ *pp = p;
+ return PS_SUCCESS;
}
/******************************************************************************/
/**
- Tests if the certificate was issued before the given date.
- Because there is no actual issuance date in the certificate, we use the
- 'notBefore' date (the initial date the certificate is valid) as the
- effective issuance date.
- @security This api is used to be more lenient on certificates that are still
- valid, but were created before certain more strict certificate rules
- were specified.
+ Explicit value encoding has an additional tag layer.
+ */
+static int32_t getExplicitVersion(const unsigned char **pp, psSize_t len,
+ int32_t expVal, int32_t *val)
+{
+ const unsigned char *p = *pp;
+ psSize_t exLen;
- @param[in] rfc The RFC to check against.
- @param[in] cert The cert to check the issuing date on.
- @return 1 if yes, 0 if no, -1 on parse error.
-*/
+ if (len < 1)
+ {
+ psTraceCrypto("Invalid length to getExplicitVersion\n");
+ return PS_PARSE_FAIL;
+ }
+/*
+ This is an optional value, so don't error if not present. The default
+ value is version 1
+ */
+ if (*p != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | expVal))
+ {
+ *val = 0;
+ return PS_SUCCESS;
+ }
+ p++;
+ if (getAsnLength(&p, len - 1, &exLen) < 0 || (len - 1) < exLen)
+ {
+ psTraceCrypto("getAsnLength failure in getExplicitVersion\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnInteger(&p, exLen, val) < 0)
+ {
+ psTraceCrypto("getAsnInteger failure in getExplicitVersion\n");
+ return PS_PARSE_FAIL;
+ }
+ *pp = p;
+ return PS_SUCCESS;
+}
+
+/******************************************************************************/
+/**
+ Tests if the certificate was issued before the given date.
+ Because there is no actual issuance date in the certificate, we use the
+ 'notBefore' date (the initial date the certificate is valid) as the
+ effective issuance date.
+ @security This api is used to be more lenient on certificates that are still
+ valid, but were created before certain more strict certificate rules
+ were specified.
+
+ @param[in] rfc The RFC to check against.
+ @param[in] cert The cert to check the issuing date on.
+ @return 1 if yes, 0 if no, -1 on parse error.
+ */
static int32 issuedBefore(rfc_e rfc, const psX509Cert_t *cert)
{
- unsigned char *c;
- unsigned int y;
- unsigned short m;
- psBrokenDownTime_t t;
- int32 err;
+ unsigned char *c;
+ unsigned int y;
+ unsigned short m;
+ psBrokenDownTime_t t;
+ int32 err;
- /* Validate the 'not before' date */
- if ((c = (unsigned char *)cert->notBefore) == NULL) {
- return PS_FAILURE;
- }
- err = psBrokenDownTimeImport(
- &t, (const char *) c, strlen((const char *)c),
- cert->notBeforeTimeType == ASN_UTCTIME ?
- PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0);
+ /* Validate the 'not before' date */
+ if ((c = (unsigned char *) cert->notBefore) == NULL)
+ {
+ return PS_FAILURE;
+ }
+ err = psBrokenDownTimeImport(
+ &t, (const char *) c, strlen((const char *) c),
+ cert->notBeforeTimeType == ASN_UTCTIME ?
+ PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0);
- if (err)
- return err;
+ if (err)
+ {
+ return err;
+ }
- /* Get y and m from broken-down time. */
- y = 1900 + (unsigned int) t.tm_year;
- m = 1 + (unsigned short) t.tm_mon;
+ /* Get y and m from broken-down time. */
+ y = 1900 + (unsigned int) t.tm_year;
+ m = 1 + (unsigned short) t.tm_mon;
- /* Must have been issued at least when X509v3 was added */
- if (y < 1996 || m < 1 || m > 12) {
- return -1;
- }
- switch (rfc) {
- case RFC_6818:
- if (y < 2013) { /* No month check needed for Jan */
- return 1;
- }
- return 0;
- case RFC_5280:
- if (y < 2008 || (y == 2008 && m < 5)) {
- return 1;
- }
- return 0;
- case RFC_3280:
- if (y < 2002 || (y == 2002 && m < 4)) {
- return 1;
- }
- return 0;
- case RFC_2459:
- if (y < 1999) { /* No month check needed for Jan */
- return 1;
- }
- return 0;
- default:
- return -1;
- }
- return -1;
+ /* Must have been issued at least when X509v3 was added */
+ if (y < 1996 || m < 1 || m > 12)
+ {
+ return -1;
+ }
+ switch (rfc)
+ {
+ case RFC_6818:
+ if (y < 2013) /* No month check needed for Jan */
+ {
+ return 1;
+ }
+ return 0;
+ case RFC_5280:
+ if (y < 2008 || (y == 2008 && m < 5))
+ {
+ return 1;
+ }
+ return 0;
+ case RFC_3280:
+ if (y < 2002 || (y == 2002 && m < 4))
+ {
+ return 1;
+ }
+ return 0;
+ case RFC_2459:
+ if (y < 1999) /* No month check needed for Jan */
+ {
+ return 1;
+ }
+ return 0;
+ default:
+ return -1;
+ }
+ return -1;
}
/**
- Validate the dates in the cert to machine date.
- SECURITY - always succeeds on systems without date support
- Returns
- 0 on parse success (FAIL_DATE_FLAG could be set)
- PS_FAILURE on parse error
-*/
+ Validate the dates in the cert to machine date.
+ SECURITY - always succeeds on systems without date support
+ Returns
+ 0 on parse success (FAIL_DATE_FLAG could be set)
+ PS_FAILURE on parse error
+ */
static int32 validateDateRange(psX509Cert_t *cert)
{
- int32 err;
- psBrokenDownTime_t timeNow;
- psBrokenDownTime_t timeNowLinger;
- psBrokenDownTime_t beforeTime;
- psBrokenDownTime_t afterTime;
- psBrokenDownTime_t afterTimeLinger;
+ int32 err;
+ psBrokenDownTime_t timeNow;
+ psBrokenDownTime_t timeNowLinger;
+ psBrokenDownTime_t beforeTime;
+ psBrokenDownTime_t afterTime;
+ psBrokenDownTime_t afterTimeLinger;
- if (cert->notBefore == NULL || cert->notAfter == NULL)
- return PS_FAIL;
+ if (cert->notBefore == NULL || cert->notAfter == NULL)
+ {
+ return PS_FAIL;
+ }
- err = psGetBrokenDownGMTime(&timeNow, 0);
- if (err != PS_SUCCESS)
- return PS_FAIL;
+ err = psGetBrokenDownGMTime(&timeNow, 0);
+ if (err != PS_SUCCESS)
+ {
+ return PS_FAIL;
+ }
- memcpy(&timeNowLinger, &timeNow, sizeof timeNowLinger);
- err = psBrokenDownTimeAdd(&timeNowLinger, PS_X509_TIME_LINGER);
- if (err != PS_SUCCESS)
- return PS_FAIL;
+ memcpy(&timeNowLinger, &timeNow, sizeof timeNowLinger);
+ err = psBrokenDownTimeAdd(&timeNowLinger, PS_X509_TIME_LINGER);
+ if (err != PS_SUCCESS)
+ {
+ return PS_FAIL;
+ }
- err = psBrokenDownTimeImport(
- &beforeTime, cert->notBefore, strlen(cert->notBefore),
- cert->notBeforeTimeType == ASN_UTCTIME ?
- PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0);
- if (err != PS_SUCCESS)
- return PS_FAIL;
+ err = psBrokenDownTimeImport(
+ &beforeTime, cert->notBefore, strlen(cert->notBefore),
+ cert->notBeforeTimeType == ASN_UTCTIME ?
+ PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0);
+ if (err != PS_SUCCESS)
+ {
+ return PS_FAIL;
+ }
- err = psBrokenDownTimeImport(
- &afterTime, cert->notAfter, strlen(cert->notAfter),
- cert->notAfterTimeType == ASN_UTCTIME ?
- PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0);
- if (err != PS_SUCCESS)
- return PS_FAIL;
+ err = psBrokenDownTimeImport(
+ &afterTime, cert->notAfter, strlen(cert->notAfter),
+ cert->notAfterTimeType == ASN_UTCTIME ?
+ PS_BROKENDOWN_TIME_IMPORT_2DIGIT_YEAR : 0);
+ if (err != PS_SUCCESS)
+ {
+ return PS_FAIL;
+ }
- memcpy(&afterTimeLinger, &afterTime, sizeof afterTimeLinger);
- err = psBrokenDownTimeAdd(&afterTimeLinger, PS_X509_TIME_LINGER);
- if (err != PS_SUCCESS)
- return PS_FAIL;
+ memcpy(&afterTimeLinger, &afterTime, sizeof afterTimeLinger);
+ err = psBrokenDownTimeAdd(&afterTimeLinger, PS_X509_TIME_LINGER);
+ if (err != PS_SUCCESS)
+ {
+ return PS_FAIL;
+ }
- if (psBrokenDownTimeCmp(&beforeTime, &timeNowLinger) > 0) {
- /* beforeTime is in future. */
- cert->authFailFlags |= PS_CERT_AUTH_FAIL_DATE_FLAG;
- } else if (psBrokenDownTimeCmp(&timeNow, &afterTimeLinger) > 0) {
- /* afterTime is in past. */
- cert->authFailFlags |= PS_CERT_AUTH_FAIL_DATE_FLAG;
- }
- return 0;
+ if (psBrokenDownTimeCmp(&beforeTime, &timeNowLinger) > 0)
+ {
+ /* beforeTime is in future. */
+ cert->authFailFlags |= PS_CERT_AUTH_FAIL_DATE_FLAG;
+ }
+ else if (psBrokenDownTimeCmp(&timeNow, &afterTimeLinger) > 0)
+ {
+ /* afterTime is in past. */
+ cert->authFailFlags |= PS_CERT_AUTH_FAIL_DATE_FLAG;
+ }
+ return 0;
}
/******************************************************************************/
/*
- Implementation specific date parser.
-*/
+ Implementation specific date parser.
+ */
static int32_t getTimeValidity(psPool_t *pool, const unsigned char **pp,
- uint16_t len, int32_t *notBeforeTimeType,
- int32_t *notAfterTimeType,
- char **notBefore, char **notAfter)
+ psSize_t len, int32_t *notBeforeTimeType,
+ int32_t *notAfterTimeType,
+ char **notBefore, char **notAfter)
{
- const unsigned char *p = *pp, *end;
- uint16_t seqLen, timeLen;
+ const unsigned char *p = *pp, *end;
+ psSize_t seqLen, timeLen;
- end = p + len;
- if (len < 1 || *(p++) != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
- getAsnLength(&p, len - 1, &seqLen) < 0 ||
- (uint32)(end - p) < seqLen) {
- psTraceCrypto("getTimeValidity failed on inital parse\n");
- return PS_PARSE_FAIL;
- }
+ end = p + len;
+ if (len < 1 || *(p++) != (ASN_SEQUENCE | ASN_CONSTRUCTED) ||
+ getAsnLength(&p, len - 1, &seqLen) < 0 ||
+ (uint32) (end - p) < seqLen)
+ {
+ psTraceCrypto("getTimeValidity failed on inital parse\n");
+ return PS_PARSE_FAIL;
+ }
/*
- Have notBefore and notAfter times in UTCTime or GeneralizedTime formats
-*/
- if ((end - p) < 1 || ((*p != ASN_UTCTIME) && (*p != ASN_GENERALIZEDTIME))) {
- psTraceCrypto("Malformed validity\n");
- return PS_PARSE_FAIL;
- }
- *notBeforeTimeType = *p;
- p++;
+ Have notBefore and notAfter times in UTCTime or GeneralizedTime formats
+ */
+ if ((end - p) < 1 || ((*p != ASN_UTCTIME) && (*p != ASN_GENERALIZEDTIME)))
+ {
+ psTraceCrypto("Malformed validity\n");
+ return PS_PARSE_FAIL;
+ }
+ *notBeforeTimeType = *p;
+ p++;
/*
- Allocate them as null terminated strings
-*/
- if (getAsnLength(&p, seqLen, &timeLen) < 0 || (uint32)(end - p) < timeLen) {
- psTraceCrypto("Malformed validity 2\n");
- return PS_PARSE_FAIL;
- }
- if (timeLen > MAX_TIME_LEN)
- return PS_PARSE_FAIL;
- *notBefore = psMalloc(pool, timeLen + 1);
- if (*notBefore == NULL) {
- psError("Memory allocation error in getTimeValidity for notBefore\n");
- return PS_MEM_FAIL;
- }
- memcpy(*notBefore, p, timeLen);
- (*notBefore)[timeLen] = '\0';
- p = p + timeLen;
- if ((end - p) < 1 || ((*p != ASN_UTCTIME) && (*p != ASN_GENERALIZEDTIME))) {
- psTraceCrypto("Malformed validity 3\n");
- return PS_PARSE_FAIL;
- }
- *notAfterTimeType = *p;
- p++;
- if (getAsnLength(&p, seqLen - timeLen, &timeLen) < 0 ||
- (uint32)(end - p) < timeLen) {
- psTraceCrypto("Malformed validity 4\n");
- return PS_PARSE_FAIL;
- }
- if (timeLen > MAX_TIME_LEN)
- return PS_PARSE_FAIL;
- *notAfter = psMalloc(pool, timeLen + 1);
- if (*notAfter == NULL) {
- psError("Memory allocation error in getTimeValidity for notAfter\n");
- return PS_MEM_FAIL;
- }
- memcpy(*notAfter, p, timeLen);
- (*notAfter)[timeLen] = '\0';
- p = p + timeLen;
+ Allocate them as null terminated strings
+ */
+ if (getAsnLength(&p, seqLen, &timeLen) < 0 || (uint32) (end - p) < timeLen)
+ {
+ psTraceCrypto("Malformed validity 2\n");
+ return PS_PARSE_FAIL;
+ }
+ if (timeLen > MAX_TIME_LEN)
+ {
+ return PS_PARSE_FAIL;
+ }
+ *notBefore = psMalloc(pool, timeLen + 1);
+ if (*notBefore == NULL)
+ {
+ psError("Memory allocation error in getTimeValidity for notBefore\n");
+ return PS_MEM_FAIL;
+ }
+ memcpy(*notBefore, p, timeLen);
+ (*notBefore)[timeLen] = '\0';
+ p = p + timeLen;
+ if ((end - p) < 1 || ((*p != ASN_UTCTIME) && (*p != ASN_GENERALIZEDTIME)))
+ {
+ psTraceCrypto("Malformed validity 3\n");
+ return PS_PARSE_FAIL;
+ }
+ *notAfterTimeType = *p;
+ p++;
+ if (getAsnLength(&p, seqLen - timeLen, &timeLen) < 0 ||
+ (uint32) (end - p) < timeLen)
+ {
+ psTraceCrypto("Malformed validity 4\n");
+ return PS_PARSE_FAIL;
+ }
+ if (timeLen > MAX_TIME_LEN)
+ {
+ return PS_PARSE_FAIL;
+ }
+ *notAfter = psMalloc(pool, timeLen + 1);
+ if (*notAfter == NULL)
+ {
+ psError("Memory allocation error in getTimeValidity for notAfter\n");
+ return PS_MEM_FAIL;
+ }
+ memcpy(*notAfter, p, timeLen);
+ (*notAfter)[timeLen] = '\0';
+ p = p + timeLen;
- *pp = p;
- return PS_SUCCESS;
+ *pp = p;
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- Could be optional. If the tag doesn't contain the value from the left
- of the IMPLICIT keyword we don't have a match and we don't incr the pointer.
-*/
+ Could be optional. If the tag doesn't contain the value from the left
+ of the IMPLICIT keyword we don't have a match and we don't incr the pointer.
+ */
static int32_t getImplicitBitString(psPool_t *pool, const unsigned char **pp,
- uint16_t len, int32_t impVal, unsigned char **bitString,
- uint16_t *bitLen)
+ psSize_t len, int32_t impVal, unsigned char **bitString,
+ psSize_t *bitLen)
{
- const unsigned char *p = *pp;
- int32_t ignore_bits;
+ const unsigned char *p = *pp;
+ int32_t ignore_bits;
- if (len < 1) {
- psTraceCrypto("Initial parse error in getImplicitBitString\n");
- return PS_PARSE_FAIL;
- }
+ if (len < 1)
+ {
+ psTraceCrypto("Initial parse error in getImplicitBitString\n");
+ return PS_PARSE_FAIL;
+ }
/*
- We don't treat this case as an error, because of the optional nature.
-*/
- if (*p != (ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE | impVal)) {
- return PS_SUCCESS;
- }
+ We don't treat this case as an error, because of the optional nature.
+ */
+ if (*p != (ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE | impVal))
+ {
+ return PS_SUCCESS;
+ }
- p++;
- if (getAsnLength(&p, len, bitLen) < 0
- || *bitLen < 2) {
- psTraceCrypto("Malformed implicitBitString\n");
- return PS_PARSE_FAIL;
- }
- ignore_bits = *p++;
- (*bitLen)--;
- psAssert(ignore_bits == 0);
+ p++;
+ if (getAsnLength(&p, len, bitLen) < 0
+ || *bitLen < 2)
+ {
+ psTraceCrypto("Malformed implicitBitString\n");
+ return PS_PARSE_FAIL;
+ }
+ ignore_bits = *p++;
+ (*bitLen)--;
+ psAssert(ignore_bits == 0);
- *bitString = psMalloc(pool, *bitLen);
- if (*bitString == NULL) {
- psError("Memory allocation error in getImplicitBitString\n");
- return PS_MEM_FAIL;
- }
- memcpy(*bitString, p, *bitLen);
- *pp = p + *bitLen;
- return PS_SUCCESS;
+ *bitString = psMalloc(pool, *bitLen);
+ if (*bitString == NULL)
+ {
+ psError("Memory allocation error in getImplicitBitString\n");
+ return PS_MEM_FAIL;
+ }
+ memcpy(*bitString, p, *bitLen);
+ *pp = p + *bitLen;
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- Implementations of this specification MUST be prepared to receive
- the following standard attribute types in issuer names:
- country, organization, organizational-unit, distinguished name qualifier,
- state or province name, and common name
-*/
+ Implementations of this specification MUST be prepared to receive
+ the following standard attribute types in issuer names:
+ country, organization, organizational-unit, distinguished name qualifier,
+ state or province name, and common name
+ */
int32_t psX509GetDNAttributes(psPool_t *pool, const unsigned char **pp,
- uint16_t len, x509DNattributes_t *attribs, uint32_t flags)
+ psSize_t len, x509DNattributes_t *attribs, uint32_t flags)
{
- const unsigned char *p = *pp;
- const unsigned char *dnEnd, *dnStart, *moreInSetPtr;
- x509OrgUnit_t *orgUnit;
- x509DomainComponent_t *domainComponent;
- int32 id, stringType, checkHiddenNull, moreInSet;
- uint16_t llen, setlen, arcLen;
- char *stringOut;
- uint32_t i;
-#ifdef USE_SHA1
- psSha1_t hash;
-#elif defined(USE_SHA256)
- psSha256_t hash;
-#else
-//TODO can we avoid hash altogether? We do not free/finalize the hash ctx on error return below.
-#error USE_SHA1 or USE_SHA256 must be defined
-#endif
+ const unsigned char *p = *pp;
+ const unsigned char *dnEnd, *dnStart, *moreInSetPtr;
+ x509OrgUnit_t *orgUnit;
+ x509DomainComponent_t *domainComponent;
+ int32 id, stringType, checkHiddenNull, moreInSet;
+ psSize_t llen, setlen, arcLen;
+ char *stringOut;
+ uint32_t i;
- dnStart = p;
- if (getAsnSequence(&p, len, &llen) < 0) {
- return PS_PARSE_FAIL;
- }
- dnEnd = p + llen;
+# ifdef USE_SHA1
+ psSha1_t hash;
+# elif defined(USE_SHA256)
+ psSha256_t hash;
+# else
+/* TODO can we avoid hash altogether? We do not free/finalize the hash ctx on error return below. */
+# error USE_SHA1 or USE_SHA256 must be defined
+# endif
+
+ dnStart = p;
+ if (getAsnSequence(&p, len, &llen) < 0)
+ {
+ return PS_PARSE_FAIL;
+ }
+ dnEnd = p + llen;
/*
- The possibility of a CERTIFICATE_REQUEST message. Set aside full DN
-*/
- if (flags & CERT_STORE_DN_BUFFER) {
- attribs->dnencLen = (uint32)(dnEnd - dnStart);
- attribs->dnenc = psMalloc(pool, attribs->dnencLen);
- if (attribs->dnenc == NULL) {
- psError("Memory allocation error in getDNAttributes\n");
- return PS_MEM_FAIL;
- }
- memcpy(attribs->dnenc, dnStart, attribs->dnencLen);
- }
- moreInSet = 0;
- while (p < dnEnd) {
- if (getAsnSet(&p, (uint32)(dnEnd - p), &setlen) < 0) {
- psTraceCrypto("Malformed DN attributes\n");
- return PS_PARSE_FAIL;
- }
- /* 99.99% of certs have one attribute per SET but did come across
- one that nested a couple at this level so let's watch out for
- that with the "moreInSet" logic */
+ The possibility of a CERTIFICATE_REQUEST message. Set aside full DN
+ */
+ if (flags & CERT_STORE_DN_BUFFER)
+ {
+ attribs->dnencLen = (uint32) (dnEnd - dnStart);
+ attribs->dnenc = psMalloc(pool, attribs->dnencLen);
+ if (attribs->dnenc == NULL)
+ {
+ psError("Memory allocation error in getDNAttributes\n");
+ return PS_MEM_FAIL;
+ }
+ memcpy(attribs->dnenc, dnStart, attribs->dnencLen);
+ }
+ moreInSet = 0;
+ while (p < dnEnd)
+ {
+ if (getAsnSet(&p, (uint32) (dnEnd - p), &setlen) < 0)
+ {
+ psTraceCrypto("Malformed DN attributes\n");
+ return PS_PARSE_FAIL;
+ }
+ /* 99.99% of certs have one attribute per SET but did come across
+ one that nested a couple at this level so let's watch out for
+ that with the "moreInSet" logic */
MORE_IN_SET:
- moreInSetPtr = p;
- if (getAsnSequence(&p, (uint32)(dnEnd - p), &llen) < 0) {
- psTraceCrypto("Malformed DN attributes 2\n");
- return PS_PARSE_FAIL;
- }
- if (moreInSet > 0) {
- moreInSet -= llen + (int32)(p - moreInSetPtr);
- } else {
- if (setlen != llen + (int32)(p - moreInSetPtr)) {
- moreInSet = setlen - (int32)(p - moreInSetPtr) - llen;
- }
- }
- if (dnEnd <= p || (*(p++) != ASN_OID) ||
- getAsnLength(&p, (uint32)(dnEnd - p), &arcLen) < 0 ||
- (uint32)(dnEnd - p) < arcLen) {
- psTraceCrypto("Malformed DN attributes 3\n");
- return PS_PARSE_FAIL;
- }
+ moreInSetPtr = p;
+ if (getAsnSequence(&p, (uint32) (dnEnd - p), &llen) < 0)
+ {
+ psTraceCrypto("Malformed DN attributes 2\n");
+ return PS_PARSE_FAIL;
+ }
+ if (moreInSet > 0)
+ {
+ moreInSet -= llen + (int32) (p - moreInSetPtr);
+ }
+ else
+ {
+ if (setlen != llen + (int32) (p - moreInSetPtr))
+ {
+ moreInSet = setlen - (int32) (p - moreInSetPtr) - llen;
+ }
+ }
+ if (dnEnd <= p || (*(p++) != ASN_OID) ||
+ getAsnLength(&p, (uint32) (dnEnd - p), &arcLen) < 0 ||
+ (uint32) (dnEnd - p) < arcLen)
+ {
+ psTraceCrypto("Malformed DN attributes 3\n");
+ return PS_PARSE_FAIL;
+ }
/*
- id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4}
- id-at-commonName OBJECT IDENTIFIER ::= {id-at 3}
- id-at-serialNumber OBJECT IDENTIFIER ::= {id-at 5}
- id-at-countryName OBJECT IDENTIFIER ::= {id-at 6}
- id-at-localityName OBJECT IDENTIFIER ::= {id-at 7}
- id-at-stateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8}
- id-at-organizationName OBJECT IDENTIFIER ::= {id-at 10}
- id-at-organizationalUnitName OBJECT IDENTIFIER ::= {id-at 11}
-*/
- *pp = p;
+ id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4}
+ id-at-commonName OBJECT IDENTIFIER ::= {id-at 3}
+ id-at-serialNumber OBJECT IDENTIFIER ::= {id-at 5}
+ id-at-countryName OBJECT IDENTIFIER ::= {id-at 6}
+ id-at-localityName OBJECT IDENTIFIER ::= {id-at 7}
+ id-at-stateOrProvinceName OBJECT IDENTIFIER ::= {id-at 8}
+ id-at-organizationName OBJECT IDENTIFIER ::= {id-at 10}
+ id-at-organizationalUnitName OBJECT IDENTIFIER ::= {id-at 11}
+ */
+ *pp = p;
/*
- Currently we are skipping OIDs not of type {joint-iso-ccitt(2) ds(5) 4}
- (domainComponent is currently the only exception).
- However, we could be dealing with an OID we MUST support per RFC.
-*/
- if (dnEnd - p < 2) {
- psTraceCrypto("Malformed DN attributes 4\n");
- return PS_LIMIT_FAIL;
- }
+ Currently we are skipping OIDs not of type {joint-iso-ccitt(2) ds(5) 4}
+ (domainComponent is currently the only exception).
+ However, we could be dealing with an OID we MUST support per RFC.
+ */
+ if (dnEnd - p < 2)
+ {
+ psTraceCrypto("Malformed DN attributes 4\n");
+ return PS_LIMIT_FAIL;
+ }
- /*
- Check separately for domainComponent and uid, since those do not
- start with the 0x5504 (id-at) pattern the code below expects.
- */
- /*
- Note: According to RFC 5280, "... implementations of this
- specification MUST be prepared to receive the domainComponent
- attribute, as defined in [RFC4519]."
- */
- if (arcLen == 10 &&
- *p == 0x09 &&
- *(p+1) == 0x92 &&
- *(p+2) == 0x26 &&
- *(p+3) == 0x89 &&
- *(p+4) == 0x93 &&
- *(p+5) == 0xf2 &&
- *(p+6) == 0x2c &&
- *(p+7) == 0x64 &&
- *(p+8) == 0x01) {
- if (*(p+9) == 0x19) {
- p += 10;
- id = ATTRIB_DOMAIN_COMPONENT;
- goto oid_parsing_done;
- }
-#ifdef USE_EXTRA_DN_ATTRIBUTES
- else if (*(p+9) == 0x01) {
- p += 10;
- id = ATTRIB_UID;
- goto oid_parsing_done;
- }
-#endif /* USE_EXTRA_DN_ATTRIBUTES */
- }
-#ifdef USE_EXTRA_DN_ATTRIBUTES
- if (arcLen == 9 &&
- *p == 0x2a &&
- *(p+1) == 0x86 &&
- *(p+2) == 0x48 &&
- *(p+3) == 0x86 &&
- *(p+4) == 0xf7 &&
- *(p+5) == 0x0d &&
- *(p+6) == 0x01 &&
- *(p+7) == 0x09 &&
- *(p+8) == 0x01) {
- p += 9;
- id = ATTRIB_EMAIL;
- goto oid_parsing_done;
- }
-#endif /* USE_EXTRA_DN_ATTRIBUTES */
+ /*
+ Check separately for domainComponent and uid, since those do not
+ start with the 0x5504 (id-at) pattern the code below expects.
+ */
+ /*
+ Note: According to RFC 5280, "... implementations of this
+ specification MUST be prepared to receive the domainComponent
+ attribute, as defined in [RFC4519]."
+ */
+ if (arcLen == 10 &&
+ *p == 0x09 &&
+ *(p + 1) == 0x92 &&
+ *(p + 2) == 0x26 &&
+ *(p + 3) == 0x89 &&
+ *(p + 4) == 0x93 &&
+ *(p + 5) == 0xf2 &&
+ *(p + 6) == 0x2c &&
+ *(p + 7) == 0x64 &&
+ *(p + 8) == 0x01)
+ {
+ if (*(p + 9) == 0x19)
+ {
+ p += 10;
+ id = ATTRIB_DOMAIN_COMPONENT;
+ goto oid_parsing_done;
+ }
+# ifdef USE_EXTRA_DN_ATTRIBUTES
+ else if (*(p + 9) == 0x01)
+ {
+ p += 10;
+ id = ATTRIB_UID;
+ goto oid_parsing_done;
+ }
+# endif /* USE_EXTRA_DN_ATTRIBUTES */
+ }
+# ifdef USE_EXTRA_DN_ATTRIBUTES
+ if (arcLen == 9 &&
+ *p == 0x2a &&
+ *(p + 1) == 0x86 &&
+ *(p + 2) == 0x48 &&
+ *(p + 3) == 0x86 &&
+ *(p + 4) == 0xf7 &&
+ *(p + 5) == 0x0d &&
+ *(p + 6) == 0x01 &&
+ *(p + 7) == 0x09 &&
+ *(p + 8) == 0x01)
+ {
+ p += 9;
+ id = ATTRIB_EMAIL;
+ goto oid_parsing_done;
+ }
+# endif /* USE_EXTRA_DN_ATTRIBUTES */
- /* check id-at */
- if ((*p++ != 85) || (*p++ != 4)) {
- /* OIDs we are not parsing */
- p = *pp;
+ /* check id-at */
+ if ((*p++ != 85) || (*p++ != 4))
+ {
+ /* OIDs we are not parsing */
+ p = *pp;
/*
- Move past the OID and string type, get data size, and skip it.
- NOTE: Have had problems parsing older certs in this area.
-*/
- if ((uint32)(dnEnd - p) < arcLen + 1) {
- psTraceCrypto("Malformed DN attributes 5\n");
- return PS_LIMIT_FAIL;
- }
- p += arcLen + 1;
- if (getAsnLength(&p, (uint32)(dnEnd - p), &llen) < 0 ||
- (uint32)(dnEnd - p) < llen) {
- psTraceCrypto("Malformed DN attributes 6\n");
- return PS_PARSE_FAIL;
- }
- p = p + llen;
- continue;
- }
- /* Next are the id of the attribute type and the ASN string type */
- if (arcLen != 3 || dnEnd - p < 2) {
- psTraceCrypto("Malformed DN attributes 7\n");
- return PS_LIMIT_FAIL;
- }
- id = (int32)*p++;
- oid_parsing_done:
- /* Done with OID parsing */
- stringType = (int32)*p++;
+ Move past the OID and string type, get data size, and skip it.
+ NOTE: Have had problems parsing older certs in this area.
+ */
+ if ((uint32) (dnEnd - p) < arcLen + 1)
+ {
+ psTraceCrypto("Malformed DN attributes 5\n");
+ return PS_LIMIT_FAIL;
+ }
+ p += arcLen + 1;
+ if (getAsnLength(&p, (uint32) (dnEnd - p), &llen) < 0 ||
+ (uint32) (dnEnd - p) < llen)
+ {
+ psTraceCrypto("Malformed DN attributes 6\n");
+ return PS_PARSE_FAIL;
+ }
+ p = p + llen;
+ continue;
+ }
+ /* Next are the id of the attribute type and the ASN string type */
+ if (arcLen != 3 || dnEnd - p < 2)
+ {
+ psTraceCrypto("Malformed DN attributes 7\n");
+ return PS_LIMIT_FAIL;
+ }
+ id = (int32) * p++;
+oid_parsing_done:
+ /* Done with OID parsing */
+ stringType = (int32) * p++;
- if (getAsnLength(&p, (uint32)(dnEnd - p), &llen) < 0 ||
- (uint32)(dnEnd - p) < llen) {
- psTraceCrypto("Malformed DN attributes 8\n");
- return PS_LIMIT_FAIL;
- }
+ if (getAsnLength(&p, (uint32) (dnEnd - p), &llen) < 0 ||
+ (uint32) (dnEnd - p) < llen)
+ {
+ psTraceCrypto("Malformed DN attributes 8\n");
+ return PS_LIMIT_FAIL;
+ }
/*
- For the known 8-bit character string types, we flag that we want
- to test for a hidden null in the middle of the string to address the
- issue of www.goodguy.com\0badguy.com.
+ For the known 8-bit character string types, we flag that we want
+ to test for a hidden null in the middle of the string to address the
+ issue of www.goodguy.com\0badguy.com.
For validation purposes, BMPSTRINGs are converted to UTF-8 format.
-*/
- checkHiddenNull = PS_FALSE;
- switch (stringType) {
- case ASN_BMPSTRING:
- {
- /* MatrixSSL generally uses single byte character string
- formats. This function converts ASN_BMPSTRING to
- UTF-8 for further handling. */
- unsigned char *uc_stringOut = NULL;
- size_t length;
- int32 str_err;
- str_err = psToUtf8String(pool,
- (const unsigned char *)p,
- (size_t)llen,
- (psStringType_t)ASN_BMPSTRING,
- &uc_stringOut,
- &length,
-#if DN_NUM_TERMINATING_NULLS == 2
- PS_STRING_DUAL_NIL
-#elif DN_NUM_TERMINATING_NULLS == 1
- 0
-#else
-#error "Unsupported value for DN_NUM_TERMINATING_NULLS."
-#endif
- );
- if (str_err != PS_SUCCESS)
- return str_err;
- /* Length checking. */
- if (length >= 0x7FFE) {
- /* Notice if length is too long to fit in 15 bits. */
- psFree(uc_stringOut, pool);
- return PS_LIMIT_FAIL;
- }
- stringOut = (char *) uc_stringOut;
- p = p + llen;
- llen = (uint16_t) length + DN_NUM_TERMINATING_NULLS;
- break;
- }
- case ASN_PRINTABLESTRING:
- case ASN_UTF8STRING:
- case ASN_IA5STRING:
- case ASN_T61STRING:
- /* coverity[unterminated_case] */
- checkHiddenNull = PS_TRUE;
- /* fall through */
- case ASN_BIT_STRING:
- stringOut = psMalloc(pool, llen + DN_NUM_TERMINATING_NULLS);
- if (stringOut == NULL) {
- psError("Memory allocation error in getDNAttributes\n");
- return PS_MEM_FAIL;
- }
- memcpy(stringOut, p, llen);
+ */
+ checkHiddenNull = PS_FALSE;
+ switch (stringType)
+ {
+ case ASN_BMPSTRING:
+ {
+ /* MatrixSSL generally uses single byte character string
+ formats. This function converts ASN_BMPSTRING to
+ UTF-8 for further handling. */
+ unsigned char *uc_stringOut = NULL;
+ size_t length;
+ int32 str_err;
+ str_err = psToUtf8String(pool,
+ (const unsigned char *) p,
+ (size_t) llen,
+ (psStringType_t) ASN_BMPSTRING,
+ &uc_stringOut,
+ &length,
+# if DN_NUM_TERMINATING_NULLS == 2
+ PS_STRING_DUAL_NIL
+# elif DN_NUM_TERMINATING_NULLS == 1
+ 0
+# else
+# error "Unsupported value for DN_NUM_TERMINATING_NULLS."
+# endif
+ );
+ if (str_err != PS_SUCCESS)
+ {
+ return str_err;
+ }
+ /* Length checking. */
+ if (length >= 0x7FFE)
+ {
+ /* Notice if length is too long to fit in 15 bits. */
+ psFree(uc_stringOut, pool);
+ return PS_LIMIT_FAIL;
+ }
+ stringOut = (char *) uc_stringOut;
+ p = p + llen;
+ llen = (uint16_t) length + DN_NUM_TERMINATING_NULLS;
+ break;
+ }
+ case ASN_PRINTABLESTRING:
+ case ASN_UTF8STRING:
+ case ASN_IA5STRING:
+ case ASN_T61STRING:
+ /* coverity[unterminated_case] */
+ checkHiddenNull = PS_TRUE;
+ /* fall through */
+ case ASN_BIT_STRING:
+ stringOut = psMalloc(pool, llen + DN_NUM_TERMINATING_NULLS);
+ if (stringOut == NULL)
+ {
+ psError("Memory allocation error in getDNAttributes\n");
+ return PS_MEM_FAIL;
+ }
+ memcpy(stringOut, p, llen);
/*
- Terminate with DN_NUM_TERMINATING_NULLS null chars to support
- standard string manipulations with any potential unicode types.
-*/
- for (i = 0; i < DN_NUM_TERMINATING_NULLS; i++) {
- stringOut[llen + i] = '\0';
- }
+ Terminate with DN_NUM_TERMINATING_NULLS null chars to support
+ standard string manipulations with any potential unicode types.
+ */
+ for (i = 0; i < DN_NUM_TERMINATING_NULLS; i++)
+ {
+ stringOut[llen + i] = '\0';
+ }
- if (checkHiddenNull) {
- if ((uint32)strlen(stringOut) != llen) {
- psFree(stringOut, pool);
- psTraceCrypto("Malformed DN attributes 9\n");
- return PS_PARSE_FAIL;
- }
- }
+ if (checkHiddenNull)
+ {
+ if ((uint32) strlen(stringOut) != llen)
+ {
+ psFree(stringOut, pool);
+ psTraceCrypto("Malformed DN attributes 9\n");
+ return PS_PARSE_FAIL;
+ }
+ }
- p = p + llen;
- llen += DN_NUM_TERMINATING_NULLS; /* Add null bytes for length assignments */
- break;
- default:
- psTraceIntCrypto("Unsupported DN attrib type %d\n", stringType);
- return PS_UNSUPPORTED_FAIL;
- }
+ p = p + llen;
+ llen += DN_NUM_TERMINATING_NULLS; /* Add null bytes for length assignments */
+ break;
+ default:
+ psTraceIntCrypto("Unsupported DN attrib type %d\n", stringType);
+ return PS_UNSUPPORTED_FAIL;
+ }
- switch (id) {
- case ATTRIB_COUNTRY_NAME:
- if (attribs->country) {
- psFree(attribs->country, pool);
- }
- attribs->country = stringOut;
- attribs->countryType = (short)stringType;
- attribs->countryLen = (short)llen;
- break;
- case ATTRIB_ORGANIZATION:
- if (attribs->organization) {
- psFree(attribs->organization, pool);
- }
- attribs->organization = stringOut;
- attribs->organizationType = (short)stringType;
- attribs->organizationLen = (short)llen;
- break;
- case ATTRIB_ORG_UNIT:
- orgUnit = psMalloc(pool, sizeof(x509OrgUnit_t));
- orgUnit->name = stringOut;
- orgUnit->type = (short)stringType;
- orgUnit->len = llen;
- /* Push the org unit onto the front of the list */
- orgUnit->next = attribs->orgUnit;
- attribs->orgUnit = orgUnit;
- break;
- case ATTRIB_DN_QUALIFIER:
- if (attribs->dnQualifier) {
- psFree(attribs->dnQualifier, pool);
- }
- attribs->dnQualifier = stringOut;
- attribs->dnQualifierType = (short)stringType;
- attribs->dnQualifierLen = (short)llen;
- break;
- case ATTRIB_STATE_PROVINCE:
- if (attribs->state) {
- psFree(attribs->state, pool);
- }
- attribs->state = stringOut;
- attribs->stateType = (short)stringType;
- attribs->stateLen = (short)llen;
- break;
- case ATTRIB_COMMON_NAME:
- if (attribs->commonName) {
- psFree(attribs->commonName, pool);
- }
- attribs->commonName = stringOut;
- attribs->commonNameType = (short)stringType;
- attribs->commonNameLen = (short)llen;
- break;
- case ATTRIB_SERIALNUMBER:
- if (attribs->serialNumber) {
- psFree(attribs->serialNumber, pool);
- }
- attribs->serialNumber = stringOut;
- attribs->serialNumberType = (short)stringType;
- attribs->serialNumberLen = (short)llen;
- break;
- case ATTRIB_DOMAIN_COMPONENT:
- domainComponent = psMalloc(pool, sizeof(x509DomainComponent_t));
- domainComponent->name = stringOut;
- domainComponent->type = (short)stringType;
- domainComponent->len = llen;
- /* Push the org unit onto the front of the list */
- domainComponent->next = attribs->domainComponent;
- attribs->domainComponent = domainComponent;
- break;
-#ifdef USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
- case ATTRIB_LOCALITY:
- if (attribs->locality) {
- psFree(attribs->locality, pool);
- }
- attribs->locality = stringOut;
- attribs->localityType = (short)stringType;
- attribs->localityLen = (short)llen;
- break;
- case ATTRIB_TITLE:
- if (attribs->title) {
- psFree(attribs->title, pool);
- }
- attribs->title = stringOut;
- attribs->titleType = (short)stringType;
- attribs->titleLen = (short)llen;
- break;
- case ATTRIB_SURNAME:
- if (attribs->surname) {
- psFree(attribs->surname, pool);
- }
- attribs->surname = stringOut;
- attribs->surnameType = (short)stringType;
- attribs->surnameLen = (short)llen;
- break;
- case ATTRIB_GIVEN_NAME:
- if (attribs->givenName) {
- psFree(attribs->givenName, pool);
- }
- attribs->givenName = stringOut;
- attribs->givenNameType = (short)stringType;
- attribs->givenNameLen = (short)llen;
- break;
- case ATTRIB_INITIALS:
- if (attribs->initials) {
- psFree(attribs->initials, pool);
- }
- attribs->initials = stringOut;
- attribs->initialsType = (short)stringType;
- attribs->initialsLen = (short)llen;
- break;
- case ATTRIB_PSEUDONYM:
- if (attribs->pseudonym) {
- psFree(attribs->pseudonym, pool);
- }
- attribs->pseudonym = stringOut;
- attribs->pseudonymType = (short)stringType;
- attribs->pseudonymLen = (short)llen;
- break;
- case ATTRIB_GEN_QUALIFIER:
- if (attribs->generationQualifier) {
- psFree(attribs->generationQualifier, pool);
- }
- attribs->generationQualifier = stringOut;
- attribs->generationQualifierType = (short)stringType;
- attribs->generationQualifierLen = (short)llen;
- break;
-#endif /* USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
-#ifdef USE_EXTRA_DN_ATTRIBUTES
- case ATTRIB_STREET_ADDRESS:
- if (attribs->streetAddress) {
- psFree(attribs->streetAddress, pool);
- }
- attribs->streetAddress = stringOut;
- attribs->streetAddressType = (short)stringType;
- attribs->streetAddressLen = (short)llen;
- break;
- case ATTRIB_POSTAL_ADDRESS:
- if (attribs->postalAddress) {
- psFree(attribs->postalAddress, pool);
- }
- attribs->postalAddress = stringOut;
- attribs->postalAddressType = (short)stringType;
- attribs->postalAddressLen = (short)llen;
- break;
- case ATTRIB_TELEPHONE_NUMBER:
- if (attribs->telephoneNumber) {
- psFree(attribs->telephoneNumber, pool);
- }
- attribs->telephoneNumber = stringOut;
- attribs->telephoneNumberType = (short)stringType;
- attribs->telephoneNumberLen = (short)llen;
- break;
- case ATTRIB_UID:
- if (attribs->uid) {
- psFree(attribs->uid, pool);
- }
- attribs->uid = stringOut;
- attribs->uidType = (short)stringType;
- attribs->uidLen = (short)llen;
- break;
- case ATTRIB_NAME:
- if (attribs->name) {
- psFree(attribs->name, pool);
- }
- attribs->name = stringOut;
- attribs->nameType = (short)stringType;
- attribs->nameLen = (short)llen;
- break;
- case ATTRIB_EMAIL:
- if (attribs->email) {
- psFree(attribs->email, pool);
- }
- attribs->email = stringOut;
- attribs->emailType = (short)stringType;
- attribs->emailLen = (short)llen;
- break;
-#endif /* USE_EXTRA_DN_ATTRIBUTES */
- default:
- /* Not a MUST support, so just ignore unknown */
- psFree(stringOut, pool);
- stringOut = NULL;
- break;
- }
- if (moreInSet) {
- goto MORE_IN_SET;
- }
- }
- /* Hash is used to quickly compare DNs */
-#ifdef USE_SHA1
- psSha1PreInit(&hash);
- psSha1Init(&hash);
- psSha1Update(&hash, dnStart, (dnEnd - dnStart));
- psSha1Final(&hash, (unsigned char*)attribs->hash);
-#else
- psSha256PreInit(&hash);
- psSha256Init(&hash);
- psSha256Update(&hash, dnStart, (dnEnd - dnStart));
- psSha256Final(&hash, (unsigned char*)attribs->hash);
-#endif
- *pp = p;
- return PS_SUCCESS;
+ switch (id)
+ {
+ case ATTRIB_COUNTRY_NAME:
+ if (attribs->country)
+ {
+ psFree(attribs->country, pool);
+ }
+ attribs->country = stringOut;
+ attribs->countryType = (short) stringType;
+ attribs->countryLen = (short) llen;
+ break;
+ case ATTRIB_ORGANIZATION:
+ if (attribs->organization)
+ {
+ psFree(attribs->organization, pool);
+ }
+ attribs->organization = stringOut;
+ attribs->organizationType = (short) stringType;
+ attribs->organizationLen = (short) llen;
+ break;
+ case ATTRIB_ORG_UNIT:
+ orgUnit = psMalloc(pool, sizeof(x509OrgUnit_t));
+ orgUnit->name = stringOut;
+ orgUnit->type = (short) stringType;
+ orgUnit->len = llen;
+ /* Push the org unit onto the front of the list */
+ orgUnit->next = attribs->orgUnit;
+ attribs->orgUnit = orgUnit;
+ break;
+ case ATTRIB_DN_QUALIFIER:
+ if (attribs->dnQualifier)
+ {
+ psFree(attribs->dnQualifier, pool);
+ }
+ attribs->dnQualifier = stringOut;
+ attribs->dnQualifierType = (short) stringType;
+ attribs->dnQualifierLen = (short) llen;
+ break;
+ case ATTRIB_STATE_PROVINCE:
+ if (attribs->state)
+ {
+ psFree(attribs->state, pool);
+ }
+ attribs->state = stringOut;
+ attribs->stateType = (short) stringType;
+ attribs->stateLen = (short) llen;
+ break;
+ case ATTRIB_COMMON_NAME:
+ if (attribs->commonName)
+ {
+ psFree(attribs->commonName, pool);
+ }
+ attribs->commonName = stringOut;
+ attribs->commonNameType = (short) stringType;
+ attribs->commonNameLen = (short) llen;
+ break;
+ case ATTRIB_SERIALNUMBER:
+ if (attribs->serialNumber)
+ {
+ psFree(attribs->serialNumber, pool);
+ }
+ attribs->serialNumber = stringOut;
+ attribs->serialNumberType = (short) stringType;
+ attribs->serialNumberLen = (short) llen;
+ break;
+ case ATTRIB_DOMAIN_COMPONENT:
+ domainComponent = psMalloc(pool, sizeof(x509DomainComponent_t));
+ domainComponent->name = stringOut;
+ domainComponent->type = (short) stringType;
+ domainComponent->len = llen;
+ /* Push the org unit onto the front of the list */
+ domainComponent->next = attribs->domainComponent;
+ attribs->domainComponent = domainComponent;
+ break;
+# ifdef USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
+ case ATTRIB_LOCALITY:
+ if (attribs->locality)
+ {
+ psFree(attribs->locality, pool);
+ }
+ attribs->locality = stringOut;
+ attribs->localityType = (short) stringType;
+ attribs->localityLen = (short) llen;
+ break;
+ case ATTRIB_TITLE:
+ if (attribs->title)
+ {
+ psFree(attribs->title, pool);
+ }
+ attribs->title = stringOut;
+ attribs->titleType = (short) stringType;
+ attribs->titleLen = (short) llen;
+ break;
+ case ATTRIB_SURNAME:
+ if (attribs->surname)
+ {
+ psFree(attribs->surname, pool);
+ }
+ attribs->surname = stringOut;
+ attribs->surnameType = (short) stringType;
+ attribs->surnameLen = (short) llen;
+ break;
+ case ATTRIB_GIVEN_NAME:
+ if (attribs->givenName)
+ {
+ psFree(attribs->givenName, pool);
+ }
+ attribs->givenName = stringOut;
+ attribs->givenNameType = (short) stringType;
+ attribs->givenNameLen = (short) llen;
+ break;
+ case ATTRIB_INITIALS:
+ if (attribs->initials)
+ {
+ psFree(attribs->initials, pool);
+ }
+ attribs->initials = stringOut;
+ attribs->initialsType = (short) stringType;
+ attribs->initialsLen = (short) llen;
+ break;
+ case ATTRIB_PSEUDONYM:
+ if (attribs->pseudonym)
+ {
+ psFree(attribs->pseudonym, pool);
+ }
+ attribs->pseudonym = stringOut;
+ attribs->pseudonymType = (short) stringType;
+ attribs->pseudonymLen = (short) llen;
+ break;
+ case ATTRIB_GEN_QUALIFIER:
+ if (attribs->generationQualifier)
+ {
+ psFree(attribs->generationQualifier, pool);
+ }
+ attribs->generationQualifier = stringOut;
+ attribs->generationQualifierType = (short) stringType;
+ attribs->generationQualifierLen = (short) llen;
+ break;
+# endif /* USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
+# ifdef USE_EXTRA_DN_ATTRIBUTES
+ case ATTRIB_STREET_ADDRESS:
+ if (attribs->streetAddress)
+ {
+ psFree(attribs->streetAddress, pool);
+ }
+ attribs->streetAddress = stringOut;
+ attribs->streetAddressType = (short) stringType;
+ attribs->streetAddressLen = (short) llen;
+ break;
+ case ATTRIB_POSTAL_ADDRESS:
+ if (attribs->postalAddress)
+ {
+ psFree(attribs->postalAddress, pool);
+ }
+ attribs->postalAddress = stringOut;
+ attribs->postalAddressType = (short) stringType;
+ attribs->postalAddressLen = (short) llen;
+ break;
+ case ATTRIB_TELEPHONE_NUMBER:
+ if (attribs->telephoneNumber)
+ {
+ psFree(attribs->telephoneNumber, pool);
+ }
+ attribs->telephoneNumber = stringOut;
+ attribs->telephoneNumberType = (short) stringType;
+ attribs->telephoneNumberLen = (short) llen;
+ break;
+ case ATTRIB_UID:
+ if (attribs->uid)
+ {
+ psFree(attribs->uid, pool);
+ }
+ attribs->uid = stringOut;
+ attribs->uidType = (short) stringType;
+ attribs->uidLen = (short) llen;
+ break;
+ case ATTRIB_NAME:
+ if (attribs->name)
+ {
+ psFree(attribs->name, pool);
+ }
+ attribs->name = stringOut;
+ attribs->nameType = (short) stringType;
+ attribs->nameLen = (short) llen;
+ break;
+ case ATTRIB_EMAIL:
+ if (attribs->email)
+ {
+ psFree(attribs->email, pool);
+ }
+ attribs->email = stringOut;
+ attribs->emailType = (short) stringType;
+ attribs->emailLen = (short) llen;
+ break;
+# endif /* USE_EXTRA_DN_ATTRIBUTES */
+ default:
+ /* Not a MUST support, so just ignore unknown */
+ psFree(stringOut, pool);
+ stringOut = NULL;
+ break;
+ }
+ if (moreInSet)
+ {
+ goto MORE_IN_SET;
+ }
+ }
+ /* Hash is used to quickly compare DNs */
+# ifdef USE_SHA1
+ psSha1PreInit(&hash);
+ psSha1Init(&hash);
+ psSha1Update(&hash, dnStart, (dnEnd - dnStart));
+ psSha1Final(&hash, (unsigned char *) attribs->hash);
+# else
+ psSha256PreInit(&hash);
+ psSha256Init(&hash);
+ psSha256Update(&hash, dnStart, (dnEnd - dnStart));
+ psSha256Final(&hash, (unsigned char *) attribs->hash);
+# endif
+ *pp = p;
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- Free helper
-*/
+ Free helper
+ */
void psX509FreeDNStruct(x509DNattributes_t *dn, psPool_t *allocPool)
{
- psFree(dn->dnenc, allocPool);
+ psFree(dn->dnenc, allocPool);
- psFree(dn->country, allocPool);
- psFree(dn->organization, allocPool);
- freeOrgUnitList(dn->orgUnit, allocPool);
- psFree(dn->dnQualifier, allocPool);
- psFree(dn->state, allocPool);
- psFree(dn->commonName, allocPool);
- psFree(dn->serialNumber, allocPool);
- freeDomainComponentList(dn->domainComponent, allocPool);
-#ifdef USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
- psFree(dn->locality, allocPool);
- psFree(dn->title, allocPool);
- psFree(dn->surname, allocPool);
- psFree(dn->givenName, allocPool);
- psFree(dn->initials, allocPool);
- psFree(dn->pseudonym, allocPool);
- psFree(dn->generationQualifier, allocPool);
-#endif /* USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
-#ifdef USE_EXTRA_DN_ATTRIBUTES
- psFree(dn->streetAddress, allocPool);
- psFree(dn->postalAddress, allocPool);
- psFree(dn->telephoneNumber, allocPool);
- psFree(dn->uid, allocPool);
- psFree(dn->name, allocPool);
- psFree(dn->email, allocPool);
-#endif /* USE_EXTRA_DN_ATTRIBUTES */
+ psFree(dn->country, allocPool);
+ psFree(dn->organization, allocPool);
+ freeOrgUnitList(dn->orgUnit, allocPool);
+ psFree(dn->dnQualifier, allocPool);
+ psFree(dn->state, allocPool);
+ psFree(dn->commonName, allocPool);
+ psFree(dn->serialNumber, allocPool);
+ freeDomainComponentList(dn->domainComponent, allocPool);
+# ifdef USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
+ psFree(dn->locality, allocPool);
+ psFree(dn->title, allocPool);
+ psFree(dn->surname, allocPool);
+ psFree(dn->givenName, allocPool);
+ psFree(dn->initials, allocPool);
+ psFree(dn->pseudonym, allocPool);
+ psFree(dn->generationQualifier, allocPool);
+# endif /* USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
+# ifdef USE_EXTRA_DN_ATTRIBUTES
+ psFree(dn->streetAddress, allocPool);
+ psFree(dn->postalAddress, allocPool);
+ psFree(dn->telephoneNumber, allocPool);
+ psFree(dn->uid, allocPool);
+ psFree(dn->name, allocPool);
+ psFree(dn->email, allocPool);
+# endif /* USE_EXTRA_DN_ATTRIBUTES */
}
/******************************************************************************/
/*
- Fundamental routine to test whether the supplied issuerCert issued
- the supplied subjectCert. There are currently two tests that are
- performed here:
- 1. A strict SHA1 hash comparison of the Distinguished Name details
- 2. A test of the public key cryptographic cert signature
+ Fundamental routine to test whether the supplied issuerCert issued
+ the supplied subjectCert. There are currently two tests that are
+ performed here:
+ 1. A strict SHA1 hash comparison of the Distinguished Name details
+ 2. A test of the public key cryptographic cert signature
- subjectCert may be a chain. Cert chains must always be passed with
- the child-most as the first in the list (the 'next' structure member
- points to the parent). The authentication of the entire chain
- will be tested before the issuerCert is used to authenticate the
- parent-most certificate
+ subjectCert may be a chain. Cert chains must always be passed with
+ the child-most as the first in the list (the 'next' structure member
+ points to the parent). The authentication of the entire chain
+ will be tested before the issuerCert is used to authenticate the
+ parent-most certificate
- issuerCert will always be a treated as a single certificate even if it
- is a chain
+ issuerCert will always be a treated as a single certificate even if it
+ is a chain
- If there is no issuerCert the parent-most subejct cert will always
- be tested as a self-signed CA certificate.
+ If there is no issuerCert the parent-most subejct cert will always
+ be tested as a self-signed CA certificate.
- So there are three uses:
- 1. Test a cert was issued by another (single subjectCert, single issuerCert)
- 1. Test a self signed cert (single cert to subjectCert, no issuerCert)
- 2. Test a CA terminated chain (cert chain to subjectCert, no issuerCert)
+ So there are three uses:
+ 1. Test a cert was issued by another (single subjectCert, single issuerCert)
+ 1. Test a self signed cert (single cert to subjectCert, no issuerCert)
+ 2. Test a CA terminated chain (cert chain to subjectCert, no issuerCert)
- This function exits with a failure code on the first authentication
- that doesn't succeed. The 'authStatus' members may be examined for more
- information of where the authentication failed.
+ This function exits with a failure code on the first authentication
+ that doesn't succeed. The 'authStatus' members may be examined for more
+ information of where the authentication failed.
- The 'authStatus' member of the issuerCert will be set to PS_FALSE
- since it will not be authenticated.
+ The 'authStatus' member of the issuerCert will be set to PS_FALSE
+ since it will not be authenticated.
- The 'authStatus' members of the subjectCert structures will always
- be reset to PS_FALSE when this routine is called and set to PS_TRUE
- when authenticated. Any error during the authentication will set the
- current subject cert 'authStatus' member to PS_CERT_AUTH_FAIL and the
- function will return with an error code.
+ The 'authStatus' members of the subjectCert structures will always
+ be reset to PS_FALSE when this routine is called and set to PS_TRUE
+ when authenticated. Any error during the authentication will set the
+ current subject cert 'authStatus' member to PS_CERT_AUTH_FAIL and the
+ function will return with an error code.
- Return codes:
- PS_SUCCESS - yes
+ Return codes:
+ PS_SUCCESS - yes
- PS_CERT_AUTH_FAIL - nope. these certs are not a match
- PS_UNSUPPORTED_FAIL - unrecognized cert format
- PS_ARG_FAIL - local, psRsaDecryptPub
- PS_LIMIT_FAIL - psRsaDecryptPub
- PS_FAILURE - internal psRsaDecryptPub failure
+ PS_CERT_AUTH_FAIL - nope. these certs are not a match
+ PS_UNSUPPORTED_FAIL - unrecognized cert format
+ PS_ARG_FAIL - local, psRsaDecryptPub
+ PS_LIMIT_FAIL - psRsaDecryptPub
+ PS_FAILURE - internal psRsaDecryptPub failure
- There is nothing for the caller to free at the completion of this
- routine.
-*/
+ There is nothing for the caller to free at the completion of this
+ routine.
+ */
int32 psX509AuthenticateCert(psPool_t *pool, psX509Cert_t *subjectCert,
- psX509Cert_t *issuerCert, psX509Cert_t **foundIssuer,
- void *hwCtx, void *poolUserPtr)
+ psX509Cert_t *issuerCert, psX509Cert_t **foundIssuer,
+ void *hwCtx, void *poolUserPtr)
{
- psX509Cert_t *ic, *sc;
- int32 sigType, rc;
- uint32 sigLen;
- void *rsaData;
-#ifdef USE_ECC
- int32 sigStat;
-#endif /* USE_ECC */
-#ifdef USE_RSA
- unsigned char sigOut[10 + MAX_HASH_SIZE + 9]; /* Max size */
- unsigned char *tempSig = NULL;
-#endif /* USE_RSA */
- psPool_t *pkiPool = NULL;
-#ifdef USE_PKCS1_PSS
- uint16_t pssLen;
-#endif
+ psX509Cert_t *ic, *sc;
+ int32 sigType, rc;
+ uint32 sigLen;
+ void *rsaData;
- rc = 0;
- sigLen = 0;
- if (subjectCert == NULL) {
- psTraceCrypto("No subject cert given to psX509AuthenticateCert\n");
- return PS_ARG_FAIL;
- }
+# ifdef USE_ECC
+ int32 sigStat;
+# endif /* USE_ECC */
+# ifdef USE_RSA
+ unsigned char sigOut[10 + MAX_HASH_SIZE + 9]; /* Max size */
+ unsigned char *tempSig = NULL;
+# endif /* USE_RSA */
+ psPool_t *pkiPool = NULL;
+# ifdef USE_PKCS1_PSS
+ psSize_t pssLen;
+# endif
+
+ rc = 0;
+ sigLen = 0;
+ if (subjectCert == NULL)
+ {
+ psTraceCrypto("No subject cert given to psX509AuthenticateCert\n");
+ return PS_ARG_FAIL;
+ }
/*
- Determine what we've been passed
-*/
- if (issuerCert == NULL) {
- /* reset auth flags in subjectCert chain and find first sc and ic */
- sc = subjectCert;
- while (sc) {
- sc->authStatus = PS_FALSE;
- sc = sc->next;
- }
- /* Now see if this is a chain or just a single cert */
- sc = subjectCert;
- if (sc->next == NULL) {
- ic = sc; /* A single subject cert for self-signed test */
- } else {
- ic = sc->next;
- }
- } else {
- issuerCert->authStatus = PS_FALSE;
- ic = issuerCert; /* Easy case of single subject and single issuer */
- sc = subjectCert;
- }
+ Determine what we've been passed
+ */
+ if (issuerCert == NULL)
+ {
+ /* reset auth flags in subjectCert chain and find first sc and ic */
+ sc = subjectCert;
+ while (sc)
+ {
+ sc->authStatus = PS_FALSE;
+ sc = sc->next;
+ }
+ /* Now see if this is a chain or just a single cert */
+ sc = subjectCert;
+ if (sc->next == NULL)
+ {
+ ic = sc; /* A single subject cert for self-signed test */
+ }
+ else
+ {
+ ic = sc->next;
+ }
+ }
+ else
+ {
+ issuerCert->authStatus = PS_FALSE;
+ ic = issuerCert; /* Easy case of single subject and single issuer */
+ sc = subjectCert;
+ }
/*
- Error on first problem seen and set the subject status to FAIL
-*/
- while (ic) {
+ Error on first problem seen and set the subject status to FAIL
+ */
+ while (ic)
+ {
/*
- Certificate authority constraint only available in version 3 certs.
- Only parsing version 3 certs by default though.
-*/
- if ((ic->version > 1) && (ic->extensions.bc.cA != CA_TRUE)) {
- if (sc != ic) {
- psTraceCrypto("Issuer does not have basicConstraint CA permissions\n");
- sc->authStatus = PS_CERT_AUTH_FAIL_BC;
- return PS_CERT_AUTH_FAIL_BC;
- }
- }
+ Certificate authority constraint only available in version 3 certs.
+ Only parsing version 3 certs by default though.
+ */
+ if ((ic->version > 1) && (ic->extensions.bc.cA != CA_TRUE))
+ {
+ if (sc != ic)
+ {
+ psTraceCrypto("Issuer does not have basicConstraint CA permissions\n");
+ sc->authStatus = PS_CERT_AUTH_FAIL_BC;
+ return PS_CERT_AUTH_FAIL_BC;
+ }
+ }
/*
- Use sha1 hash of issuer fields computed at parse time to compare
-*/
- if (memcmp(sc->issuer.hash, ic->subject.hash, SHA1_HASH_SIZE) != 0) {
- if (sc == ic) {
- psTraceCrypto("Info: not a self-signed certificate\n");
- } else {
- //psTraceCrypto("Issuer DN attributes do not match subject\n");
- }
- sc->authStatus = PS_CERT_AUTH_FAIL_DN;
- return PS_CERT_AUTH_FAIL_DN;
- }
+ Use sha1 hash of issuer fields computed at parse time to compare
+ */
+ if (memcmp(sc->issuer.hash, ic->subject.hash, SHA1_HASH_SIZE) != 0)
+ {
+/* #define ALLOW_INTERMEDIATES_AS_ROOTS */
+# ifdef ALLOW_INTERMEDIATES_AS_ROOTS
+ /* In a typical deployment, we have this trust chain:
+ leaf->intermediate->(root)
+ Where leaf and intermediate are sent by the peer and root is loaded by the
+ application as a trusted CA.
+ In some cases, it may not be desireable to load the root cert as a CA and
+ validate every certificate it has signed. This is usually due to a
+ legacy v1 certificate or certificate using a weak cryptographic
+ algorithm.
+ Ideally, the certificate chain can be re-issued or cross-signed by a modern
+ root certifiate. However, a workaround is to load the final intermediate
+ certificate in the application as a trusted, non self-signed root.
+ The peer sends the leaf->intermediate chain as before, but the application
+ loads the intermediate, not the root as a trusted CA cert.
+ Without special treatment, this arranement will fail validation because the
+ intermediate has been issued by 'root', and that is what it wants to validate
+ against. However, if we check to see if a copy of intermediate is itself in the
+ issuer list, then we have validated to a trusted root and do not need
+ to verify the signature on the intermediate.
+ Note this implementation only allows the last cert in the chain sent by
+ the client to be treated as root, for example in a chain with 2 intermediates:
+ Peer sends l->i1->i2->(root)
+ Valid CA to load: i2 or root
+ Invalid CA to load: l or i1
+ */
+ if (sc->signatureLen == ic->signatureLen
+ && memcmpct(sc->signature, ic->signature, sc->signatureLen) == 0)
+ {
+ /* Skip some of the signature and issuer checks */
+ goto L_INTERMEDIATE_ROOT;
+ }
+# endif
+ if (sc == ic)
+ {
+ psTraceCrypto("Info: not a self-signed certificate\n");
+ }
+ else
+ {
+ psTraceCrypto("Issuer DN attributes do not match subject\n");
+ }
+ sc->authStatus = PS_CERT_AUTH_FAIL_DN;
+ return PS_CERT_AUTH_FAIL_DN;
+ }
-#ifdef USE_CRL
- /* This function operates on the global cache */
- psCRL_determineRevokedStatus(sc);
- /* The only status that is going to make us terminate the connection
- immediately is if we find REVOKED_AND_AUTHENTICATED */
- if (sc->revokedStatus == CRL_CHECK_REVOKED_AND_AUTHENTICATED) {
- sc->authStatus = PS_CERT_AUTH_FAIL_REVOKED;
- return PS_CERT_AUTH_FAIL_REVOKED;
- }
-#endif
+# ifdef USE_CRL
+ /* This function operates on the global cache */
+ psCRL_determineRevokedStatus(sc);
+ /* The only status that is going to make us terminate the connection
+ immediately is if we find REVOKED_AND_AUTHENTICATED */
+ if (sc->revokedStatus == CRL_CHECK_REVOKED_AND_AUTHENTICATED)
+ {
+ sc->authStatus = PS_CERT_AUTH_FAIL_REVOKED;
+ return PS_CERT_AUTH_FAIL_REVOKED;
+ }
+# endif
/*
- Signature confirmation
- The sigLen is the ASN.1 size in bytes for encoding the hash.
- The magic 10 is comprised of the SEQUENCE and ALGORITHM ID overhead.
- The magic 9, 8, or 5 is the OID length of the corresponding algorithm.
-*/
- switch (sc->sigAlgorithm) {
-#ifdef USE_RSA
-#ifdef ENABLE_MD5_SIGNED_CERTS
-#ifdef USE_MD2
- case OID_MD2_RSA_SIG:
-#endif
- case OID_MD5_RSA_SIG:
- sigType = RSA_TYPE_SIG;
- sigLen = 10 + MD5_HASH_SIZE + 8;
- break;
-#endif
-#ifdef ENABLE_SHA1_SIGNED_CERTS
- case OID_SHA1_RSA_SIG:
- sigLen = 10 + SHA1_HASH_SIZE + 5;
- sigType = RSA_TYPE_SIG;
- break;
-#endif
-#ifdef USE_SHA256
- case OID_SHA256_RSA_SIG:
- sigLen = 10 + SHA256_HASH_SIZE + 9;
- sigType = RSA_TYPE_SIG;
- break;
-#endif
-#ifdef USE_SHA384
- case OID_SHA384_RSA_SIG:
- sigLen = 10 + SHA384_HASH_SIZE + 9;
- sigType = RSA_TYPE_SIG;
- break;
-#endif
-#ifdef USE_SHA512
- case OID_SHA512_RSA_SIG:
- sigLen = 10 + SHA512_HASH_SIZE + 9;
- sigType = RSA_TYPE_SIG;
- break;
-#endif
-#endif /* USE_RSA */
-#ifdef USE_ECC
-#ifdef ENABLE_SHA1_SIGNED_CERTS
- case OID_SHA1_ECDSA_SIG:
- sigLen = SHA1_HASH_SIZE;
- sigType = ECDSA_TYPE_SIG;
- break;
-#endif
-#ifdef USE_SHA256
- case OID_SHA256_ECDSA_SIG:
- sigLen = SHA256_HASH_SIZE;
- sigType = ECDSA_TYPE_SIG;
- break;
-#endif
-#ifdef USE_SHA384
- case OID_SHA384_ECDSA_SIG:
- sigLen = SHA384_HASH_SIZE;
- sigType = ECDSA_TYPE_SIG;
- break;
-#endif
-#ifdef USE_SHA512
- case OID_SHA512_ECDSA_SIG:
- sigLen = SHA512_HASH_SIZE;
- sigType = ECDSA_TYPE_SIG;
- break;
-#endif
-#endif /* USE_ECC */
+ Signature confirmation
+ The sigLen is the ASN.1 size in bytes for encoding the hash.
+ The magic 10 is comprised of the SEQUENCE and ALGORITHM ID overhead.
+ The magic 9, 8, or 5 is the OID length of the corresponding algorithm.
+ */
+ switch (sc->sigAlgorithm)
+ {
+# ifdef USE_RSA
+# ifdef ENABLE_MD5_SIGNED_CERTS
+# ifdef USE_MD2
+ case OID_MD2_RSA_SIG:
+# endif
+ case OID_MD5_RSA_SIG:
+ sigType = RSA_TYPE_SIG;
+ sigLen = 10 + MD5_HASH_SIZE + 8;
+ break;
+# endif
+# ifdef ENABLE_SHA1_SIGNED_CERTS
+ case OID_SHA1_RSA_SIG:
+ case OID_SHA1_RSA_SIG2:
+ sigLen = 10 + SHA1_HASH_SIZE + 5;
+ sigType = RSA_TYPE_SIG;
+ break;
+# endif
+# ifdef USE_SHA256
+ case OID_SHA256_RSA_SIG:
+ sigLen = 10 + SHA256_HASH_SIZE + 9;
+ sigType = RSA_TYPE_SIG;
+ break;
+# endif
+# ifdef USE_SHA384
+ case OID_SHA384_RSA_SIG:
+ sigLen = 10 + SHA384_HASH_SIZE + 9;
+ sigType = RSA_TYPE_SIG;
+ break;
+# endif
+# ifdef USE_SHA512
+ case OID_SHA512_RSA_SIG:
+ sigLen = 10 + SHA512_HASH_SIZE + 9;
+ sigType = RSA_TYPE_SIG;
+ break;
+# endif
+# endif /* USE_RSA */
+# ifdef USE_ECC
+# ifdef ENABLE_SHA1_SIGNED_CERTS
+ case OID_SHA1_ECDSA_SIG:
+ sigLen = SHA1_HASH_SIZE;
+ sigType = ECDSA_TYPE_SIG;
+ break;
+# endif
+# ifdef USE_SHA256
+ case OID_SHA256_ECDSA_SIG:
+ sigLen = SHA256_HASH_SIZE;
+ sigType = ECDSA_TYPE_SIG;
+ break;
+# endif
+# ifdef USE_SHA384
+ case OID_SHA384_ECDSA_SIG:
+ sigLen = SHA384_HASH_SIZE;
+ sigType = ECDSA_TYPE_SIG;
+ break;
+# endif
+# ifdef USE_SHA512
+ case OID_SHA512_ECDSA_SIG:
+ sigLen = SHA512_HASH_SIZE;
+ sigType = ECDSA_TYPE_SIG;
+ break;
+# endif
+# endif /* USE_ECC */
-#ifdef USE_PKCS1_PSS
- case OID_RSASSA_PSS:
- switch (sc->pssHash) {
-#ifdef ENABLE_MD5_SIGNED_CERTS
- case PKCS1_MD5_ID:
- sigLen = MD5_HASH_SIZE;
- break;
-#endif
-#ifdef ENABLE_SHA1_SIGNED_CERTS
- case PKCS1_SHA1_ID:
- sigLen = SHA1_HASH_SIZE;
- break;
-#endif
-#ifdef USE_SHA256
- case PKCS1_SHA256_ID:
- sigLen = SHA256_HASH_SIZE;
- break;
-#endif
-#ifdef USE_SHA384
- case PKCS1_SHA384_ID:
- sigLen = SHA384_HASH_SIZE;
- break;
-#endif
-#ifdef USE_SHA512
- case PKCS1_SHA512_ID:
- sigLen = SHA512_HASH_SIZE;
- break;
-#endif
- default:
- return PS_UNSUPPORTED_FAIL;
- }
- sigType = RSAPSS_TYPE_SIG;
- break;
-#endif
- default:
- sigType = PS_UNSUPPORTED_FAIL;
- break;
- }
+# ifdef USE_PKCS1_PSS
+ case OID_RSASSA_PSS:
+ switch (sc->pssHash)
+ {
+# ifdef ENABLE_MD5_SIGNED_CERTS
+ case PKCS1_MD5_ID:
+ sigLen = MD5_HASH_SIZE;
+ break;
+# endif
+# ifdef ENABLE_SHA1_SIGNED_CERTS
+ case PKCS1_SHA1_ID:
+ sigLen = SHA1_HASH_SIZE;
+ break;
+# endif
+# ifdef USE_SHA256
+ case PKCS1_SHA256_ID:
+ sigLen = SHA256_HASH_SIZE;
+ break;
+# endif
+# ifdef USE_SHA384
+ case PKCS1_SHA384_ID:
+ sigLen = SHA384_HASH_SIZE;
+ break;
+# endif
+# ifdef USE_SHA512
+ case PKCS1_SHA512_ID:
+ sigLen = SHA512_HASH_SIZE;
+ break;
+# endif
+ default:
+ return PS_UNSUPPORTED_FAIL;
+ }
+ sigType = RSAPSS_TYPE_SIG;
+ break;
+# endif
+ default:
+ sigType = PS_UNSUPPORTED_FAIL;
+ break;
+ }
- if (sigType == PS_UNSUPPORTED_FAIL) {
- sc->authStatus = PS_CERT_AUTH_FAIL_SIG;
- psTraceIntCrypto("Unsupported certificate signature algorithm %d\n",
- subjectCert->sigAlgorithm);
- return sigType;
- }
+ if (sigType == PS_UNSUPPORTED_FAIL)
+ {
+ sc->authStatus = PS_CERT_AUTH_FAIL_SIG;
+ psTraceIntCrypto("Unsupported certificate signature algorithm %d\n",
+ subjectCert->sigAlgorithm);
+ return sigType;
+ }
-#ifdef USE_RSA
- if (sigType == RSA_TYPE_SIG || sigType == RSAPSS_TYPE_SIG) {
- }
- /* Now do the signature validation */
- if (sigType == RSA_TYPE_SIG) {
- psAssert(sigLen <= sizeof(sigOut));
+# ifdef USE_RSA
+ if (sigType == RSA_TYPE_SIG || sigType == RSAPSS_TYPE_SIG)
+ {
+ }
+ /* Now do the signature validation */
+ if (sigType == RSA_TYPE_SIG)
+ {
+ psAssert(sigLen <= sizeof(sigOut));
/*
- psRsaDecryptPub destroys the 'in' parameter so let it be a tmp
-*/
- tempSig = psMalloc(pool, sc->signatureLen);
- if (tempSig == NULL) {
- psError("Memory allocation error: psX509AuthenticateCert\n");
- return PS_MEM_FAIL;
- }
- memcpy(tempSig, sc->signature, sc->signatureLen);
+ psRsaDecryptPub destroys the 'in' parameter so let it be a tmp
+ */
+ tempSig = psMalloc(pool, sc->signatureLen);
+ if (tempSig == NULL)
+ {
+ psError("Memory allocation error: psX509AuthenticateCert\n");
+ return PS_MEM_FAIL;
+ }
+ memcpy(tempSig, sc->signature, sc->signatureLen);
- rsaData = NULL;
+ rsaData = NULL;
- if ((rc = psRsaDecryptPub(pkiPool, &ic->publicKey.key.rsa,
- tempSig, sc->signatureLen, sigOut, sigLen, rsaData)) < 0) {
+ if ((rc = psRsaDecryptPub(pkiPool, &ic->publicKey.key.rsa,
+ tempSig, sc->signatureLen, sigOut, sigLen, rsaData)) < 0)
+ {
- psTraceCrypto("Unable to RSA decrypt certificate signature\n");
- sc->authStatus = PS_CERT_AUTH_FAIL_SIG;
- psFree(tempSig, pool);
- return rc;
- }
- psFree(tempSig, pool);
- rc = x509ConfirmSignature(sc->sigHash, sigOut, sigLen);
- }
-#if defined(USE_PKCS1_PSS) && !defined(USE_PKCS1_PSS_VERIFY_ONLY)
- if (sigType == RSAPSS_TYPE_SIG) {
- tempSig = psMalloc(pool, sc->signatureLen);
- if (tempSig == NULL) {
- psError("Memory allocation error: psX509AuthenticateCert\n");
- return PS_MEM_FAIL;
- }
- pssLen = sc->signatureLen;
- if ((rc = psRsaCrypt(pkiPool, &ic->publicKey.key.rsa,
- sc->signature, sc->signatureLen, tempSig, &pssLen,
- PS_PUBKEY, rsaData)) < 0) {
- psFree(tempSig, pool);
- return rc;
- }
+ psTraceCrypto("Unable to RSA decrypt certificate signature\n");
+ sc->authStatus = PS_CERT_AUTH_FAIL_SIG;
+ psFree(tempSig, pool);
+ return rc;
+ }
+ psFree(tempSig, pool);
+ rc = x509ConfirmSignature(sc->sigHash, sigOut, sigLen);
+ }
+# if defined(USE_PKCS1_PSS) && !defined(USE_PKCS1_PSS_VERIFY_ONLY)
+ if (sigType == RSAPSS_TYPE_SIG)
+ {
+ tempSig = psMalloc(pool, sc->signatureLen);
+ if (tempSig == NULL)
+ {
+ psError("Memory allocation error: psX509AuthenticateCert\n");
+ return PS_MEM_FAIL;
+ }
+ pssLen = sc->signatureLen;
+ if ((rc = psRsaCrypt(pkiPool, &ic->publicKey.key.rsa,
+ sc->signature, sc->signatureLen, tempSig, &pssLen,
+ PS_PUBKEY, rsaData)) < 0)
+ {
+ psFree(tempSig, pool);
+ return rc;
+ }
- if (pkcs1PssDecode(pkiPool, sc->sigHash, sigLen, tempSig,
- pssLen, sc->saltLen, sc->pssHash, ic->publicKey.keysize * 8,
- &rc) < 0) {
- psFree(tempSig, pool);
- return PS_FAILURE;
- }
- psFree(tempSig, pool);
+ if (psPkcs1PssDecode(pkiPool, sc->sigHash, sigLen, tempSig,
+ pssLen, sc->saltLen, sc->pssHash, ic->publicKey.keysize * 8,
+ &rc) < 0)
+ {
+ psFree(tempSig, pool);
+ return PS_FAILURE;
+ }
+ psFree(tempSig, pool);
- if (rc == 0) {
- /* This is an indication the hash did NOT match */
- rc = -1; /* The test below is looking for < 0 */
- }
- }
-#endif /* defined(USE_PKCS1_PSS) && !defined(USE_PKCS1_PSS_VERIFY_ONLY) */
-#endif /* USE_RSA */
+ if (rc == 0)
+ {
+ /* This is an indication the hash did NOT match */
+ rc = -1; /* The test below is looking for < 0 */
+ }
+ }
+# endif /* defined(USE_PKCS1_PSS) && !defined(USE_PKCS1_PSS_VERIFY_ONLY) */
+# endif /* USE_RSA */
-#ifdef USE_ECC
- if (sigType == ECDSA_TYPE_SIG) {
- rsaData = NULL;
- if ((rc = psEccDsaVerify(pkiPool,
- &ic->publicKey.key.ecc,
- sc->sigHash, sigLen,
- sc->signature, sc->signatureLen,
- &sigStat, rsaData)) != 0) {
- psTraceCrypto("Error validating ECDSA certificate signature\n");
- sc->authStatus = PS_CERT_AUTH_FAIL_SIG;
- return rc;
- }
- if (sigStat == -1) {
- /* No errors, but signature didn't pass */
- psTraceCrypto("ECDSA certificate signature failed\n");
- rc = -1;
- }
- }
-#endif /* USE_ECC */
+# ifdef USE_ECC
+ if (sigType == ECDSA_TYPE_SIG)
+ {
+ rsaData = NULL;
+ if ((rc = psEccDsaVerify(pkiPool,
+ &ic->publicKey.key.ecc,
+ sc->sigHash, sigLen,
+ sc->signature, sc->signatureLen,
+ &sigStat, rsaData)) != 0)
+ {
+ psTraceCrypto("Error validating ECDSA certificate signature\n");
+ sc->authStatus = PS_CERT_AUTH_FAIL_SIG;
+ return rc;
+ }
+ if (sigStat == -1)
+ {
+ /* No errors, but signature didn't pass */
+ psTraceCrypto("ECDSA certificate signature failed\n");
+ rc = -1;
+ }
+ }
+# endif /* USE_ECC */
/*
- Test what happen in the signature test?
-*/
- if (rc < PS_SUCCESS) {
- sc->authStatus = PS_CERT_AUTH_FAIL_SIG;
- return rc;
- }
+ Test what happen in the signature test?
+ */
+ if (rc < PS_SUCCESS)
+ {
+ sc->authStatus = PS_CERT_AUTH_FAIL_SIG;
+ return rc;
+ }
- /* X.509 extension tests. Problems below here will be collected
- in flags and given to the user */
+ /* X.509 extension tests. Problems below here will be collected
+ in flags and given to the user */
- /* If date was out of range in parse, flag it here */
- if (sc->authFailFlags & PS_CERT_AUTH_FAIL_DATE_FLAG) {
- sc->authStatus = PS_CERT_AUTH_FAIL_EXTENSION;
- }
+ /* Verify subject key and auth key if either is non-zero */
+ if (sc->extensions.ak.keyLen > 0 || ic->extensions.sk.len > 0)
+ {
+ if (ic->extensions.sk.len != sc->extensions.ak.keyLen)
+ {
+ /* The one exception to this test would be if this is a
+ self-signed CA being authenticated with the exact same
+ self-signed CA and that certificate does not popluate
+ the Authority Key Identifier extension */
+ if ((sc->signatureLen == ic->signatureLen) &&
+ (memcmp(sc->signature, ic->signature, ic->signatureLen)
+ == 0))
+ {
+ if (sc->extensions.ak.keyLen != 0)
+ {
+ psTraceCrypto("Subject/Issuer key id mismatch\n");
+ sc->authStatus = PS_CERT_AUTH_FAIL_AUTHKEY;
+ }
+ }
+ else
+ {
+ psTraceCrypto("Subject/Issuer key id mismatch\n");
+ sc->authStatus = PS_CERT_AUTH_FAIL_AUTHKEY;
+ }
+ }
+ else
+ {
+ if (memcmp(ic->extensions.sk.id, sc->extensions.ak.keyId,
+ ic->extensions.sk.len) != 0)
+ {
+ psTraceCrypto("Subject/Issuer key id data mismatch\n");
+ sc->authStatus = PS_CERT_AUTH_FAIL_AUTHKEY;
+ }
+ }
+ }
- /* Verify subject key and auth key if either is non-zero */
- if (sc->extensions.ak.keyLen > 0 || ic->extensions.sk.len > 0) {
- if (ic->extensions.sk.len != sc->extensions.ak.keyLen) {
- /* The one exception to this test would be if this is a
- self-signed CA being authenticated with the exact same
- self-signed CA and that certificate does not popluate
- the Authority Key Identifier extension */
- if ((sc->signatureLen == ic->signatureLen) &&
- (memcmp(sc->signature, ic->signature, ic->signatureLen)
- == 0)) {
- if (sc->extensions.ak.keyLen != 0) {
- psTraceCrypto("Subject/Issuer key id mismatch\n");
- sc->authStatus = PS_CERT_AUTH_FAIL_AUTHKEY;
- }
- } else {
- psTraceCrypto("Subject/Issuer key id mismatch\n");
- sc->authStatus = PS_CERT_AUTH_FAIL_AUTHKEY;
- }
- } else {
- if (memcmp(ic->extensions.sk.id, sc->extensions.ak.keyId,
- ic->extensions.sk.len) != 0) {
- psTraceCrypto("Subject/Issuer key id data mismatch\n");
- sc->authStatus = PS_CERT_AUTH_FAIL_AUTHKEY;
- }
- }
- }
-
- /* Ensure keyCertSign of KeyUsage. The second byte of the BIT STRING
- will always contain the relevant information. */
- if ( ! (ic->extensions.keyUsageFlags & KEY_USAGE_KEY_CERT_SIGN)) {
- /* @security If keyUsageFlags is zero, it may not exist at all
- in the cert. This is allowed if the cert was issued before
- the RFC was updated to require this field for CA certificates.
- RFC3280 and above specify this as a MUST for CACerts. */
- if (ic->extensions.keyUsageFlags == 0) {
- rc = issuedBefore(RFC_3280, ic);
- } else {
- rc = 0; /* Awkward code to force the compare below */
- }
- /* Iff rc == 1 we won't error */
- if (!rc) {
- psTraceCrypto("Issuer does not allow keyCertSign in keyUsage\n");
- sc->authFailFlags |= PS_CERT_AUTH_FAIL_KEY_USAGE_FLAG;
- sc->authStatus = PS_CERT_AUTH_FAIL_EXTENSION;
- } else if (rc < 0) {
- psTraceCrypto("Issue date check failed\n");
- return PS_PARSE_FAIL;
- }
- }
+ /* Ensure keyCertSign of KeyUsage. The second byte of the BIT STRING
+ will always contain the relevant information. */
+ if ( !(ic->extensions.keyUsageFlags & KEY_USAGE_KEY_CERT_SIGN))
+ {
+ /* @security If keyUsageFlags is zero, it may not exist at all
+ in the cert. This is allowed if the cert was issued before
+ the RFC was updated to require this field for CA certificates.
+ RFC3280 and above specify this as a MUST for CACerts. */
+ if (ic->extensions.keyUsageFlags == 0)
+ {
+ rc = issuedBefore(RFC_3280, ic);
+ }
+ else
+ {
+ rc = 0; /* Awkward code to force the compare below */
+ }
+ /* Iff rc == 1 we won't error */
+ if (!rc)
+ {
+ psTraceCrypto("Issuer does not allow keyCertSign in keyUsage\n");
+ sc->authFailFlags |= PS_CERT_AUTH_FAIL_KEY_USAGE_FLAG;
+ sc->authStatus = PS_CERT_AUTH_FAIL_EXTENSION;
+ }
+ else if (rc < 0)
+ {
+ psTraceCrypto("Issue date check failed\n");
+ return PS_PARSE_FAIL;
+ }
+ }
+# ifdef ALLOW_INTERMEDIATES_AS_ROOTS
+L_INTERMEDIATE_ROOT:
+# endif
+ /* If date was out of range in parse, and we have no other auth errors,
+ set it here. Other errors "take priority" in the return code, although
+ all can be accessed with authFailFlags. */
+ if (sc->authStatus == PS_FALSE
+ && sc->authFailFlags & PS_CERT_AUTH_FAIL_DATE_FLAG)
+ {
+ sc->authStatus = PS_CERT_AUTH_FAIL_EXTENSION;
+ }
/*
- Fall through to here only if passed all non-failure checks.
-*/
- if (sc->authStatus == PS_FALSE) { /* Hasn't been touched */
- sc->authStatus = PS_CERT_AUTH_PASS;
- }
+ Fall through to here only if passed all non-failure checks.
+ */
+ if (sc->authStatus == PS_FALSE) /* Hasn't been touched */
+ {
+ sc->authStatus = PS_CERT_AUTH_PASS;
+ }
/*
- Loop control for finding next ic and sc.
-*/
- if (ic == sc) {
- *foundIssuer = ic;
- ic = NULL; /* Single self-signed test completed */
- } else if (ic == issuerCert) {
- *foundIssuer = ic;
- ic = NULL; /* If issuerCert was used, that is always final test */
- } else {
- sc = ic;
- ic = sc->next;
- if (ic == NULL) { /* Reached end of chain */
- *foundIssuer = ic;
- ic = sc; /* Self-signed test on final subectCert chain */
- }
- }
+ Loop control for finding next ic and sc.
+ */
+ if (ic == sc)
+ {
+ *foundIssuer = ic;
+ ic = NULL; /* Single self-signed test completed */
+ }
+ else if (ic == issuerCert)
+ {
+ *foundIssuer = ic;
+ ic = NULL; /* If issuerCert was used, that is always final test */
+ }
+ else
+ {
+ sc = ic;
+ ic = sc->next;
+ if (ic == NULL) /* Reached end of chain */
+ {
+ *foundIssuer = ic;
+ ic = sc; /* Self-signed test on final subectCert chain */
+ }
+ }
- }
- return PS_SUCCESS;
+ }
+ return PS_SUCCESS;
}
-#ifdef USE_RSA
+# ifdef USE_RSA
/******************************************************************************/
/*
- Do the signature validation for a subject certificate against a
- known CA certificate
-*/
+ Do the signature validation for a subject certificate against a
+ known CA certificate
+ */
static int32_t x509ConfirmSignature(const unsigned char *sigHash,
- const unsigned char *sigOut, uint16_t sigLen)
+ const unsigned char *sigOut, psSize_t sigLen)
{
- const unsigned char *end;
- const unsigned char *p = sigOut;
- unsigned char hash[MAX_HASH_SIZE];
- int32_t oi;
- uint16_t len, plen;
+ const unsigned char *end;
+ const unsigned char *p = sigOut;
+ unsigned char hash[MAX_HASH_SIZE];
+ int32_t oi;
+ psSize_t len, plen;
- end = p + sigLen;
+ end = p + sigLen;
/*
- DigestInfo ::= SEQUENCE {
- digestAlgorithm DigestAlgorithmIdentifier,
- digest Digest }
+ DigestInfo ::= SEQUENCE {
+ digestAlgorithm DigestAlgorithmIdentifier,
+ digest Digest }
- DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+ DigestAlgorithmIdentifier ::= AlgorithmIdentifier
- Digest ::= OCTET STRING
-*/
- if (getAsnSequence(&p, (uint32)(end - p), &len) < 0) {
- psTraceCrypto("Initial parse error in x509ConfirmSignature\n");
- return PS_PARSE_FAIL;
- }
+ Digest ::= OCTET STRING
+ */
+ if (getAsnSequence(&p, (uint32) (end - p), &len) < 0)
+ {
+ psTraceCrypto("Initial parse error in x509ConfirmSignature\n");
+ return PS_PARSE_FAIL;
+ }
- /* Could be MD5 or SHA1 */
- if (getAsnAlgorithmIdentifier(&p, (uint32)(end - p), &oi, &plen) < 0) {
- psTraceCrypto("Algorithm ID parse error in x509ConfirmSignature\n");
- return PS_PARSE_FAIL;
- }
- psAssert(plen == 0);
- if ((*p++ != ASN_OCTET_STRING) ||
- getAsnLength(&p, (uint32)(end - p), &len) < 0 ||
- (uint32)(end - p) < len) {
- psTraceCrypto("getAsnLength parse error in x509ConfirmSignature\n");
- return PS_PARSE_FAIL;
- }
- memcpy(hash, p, len);
- switch (oi) {
-#ifdef ENABLE_MD5_SIGNED_CERTS
-#ifdef USE_MD2
- case OID_MD2_ALG:
-#endif
- case OID_MD5_ALG:
- if (len != MD5_HASH_SIZE) {
- psTraceCrypto("MD5_HASH_SIZE error in x509ConfirmSignature\n");
- return PS_LIMIT_FAIL;
- }
- break;
-#endif
-#ifdef ENABLE_SHA1_SIGNED_CERTS
- case OID_SHA1_ALG:
- if (len != SHA1_HASH_SIZE) {
- psTraceCrypto("SHA1_HASH_SIZE error in x509ConfirmSignature\n");
- return PS_LIMIT_FAIL;
- }
- break;
-#endif
-#ifdef USE_SHA256
- case OID_SHA256_ALG:
- if (len != SHA256_HASH_SIZE) {
- psTraceCrypto("SHA256_HASH_SIZE error in x509ConfirmSignature\n");
- return PS_LIMIT_FAIL;
- }
- break;
-#endif
-#ifdef USE_SHA384
- case OID_SHA384_ALG:
- if (len != SHA384_HASH_SIZE) {
- psTraceCrypto("SHA384_HASH_SIZE error in x509ConfirmSignature\n");
- return PS_LIMIT_FAIL;
- }
- break;
-#endif
-#ifdef USE_SHA512
- case OID_SHA512_ALG:
- if (len != SHA512_HASH_SIZE) {
- psTraceCrypto("SHA512_HASH_SIZE error in x509ConfirmSignature\n");
- return PS_LIMIT_FAIL;
- }
- break;
-#endif
- default:
- psTraceCrypto("Unsupported alg ID error in x509ConfirmSignature\n");
- return PS_UNSUPPORTED_FAIL;
- }
- /* hash should match sigHash */
- if (memcmp(hash, sigHash, len) != 0) {
- psTraceCrypto("Signature failure in x509ConfirmSignature\n");
- return PS_SIGNATURE_MISMATCH;
- }
- return PS_SUCCESS;
+ /* Could be MD5 or SHA1 */
+ if (getAsnAlgorithmIdentifier(&p, (uint32) (end - p), &oi, &plen) < 0)
+ {
+ psTraceCrypto("Algorithm ID parse error in x509ConfirmSignature\n");
+ return PS_PARSE_FAIL;
+ }
+ psAssert(plen == 0);
+ if ((*p++ != ASN_OCTET_STRING) ||
+ getAsnLength(&p, (uint32) (end - p), &len) < 0 ||
+ (uint32) (end - p) < len)
+ {
+ psTraceCrypto("getAsnLength parse error in x509ConfirmSignature\n");
+ return PS_PARSE_FAIL;
+ }
+ memcpy(hash, p, len);
+ switch (oi)
+ {
+# ifdef ENABLE_MD5_SIGNED_CERTS
+# ifdef USE_MD2
+ case OID_MD2_ALG:
+# endif
+ case OID_MD5_ALG:
+ if (len != MD5_HASH_SIZE)
+ {
+ psTraceCrypto("MD5_HASH_SIZE error in x509ConfirmSignature\n");
+ return PS_LIMIT_FAIL;
+ }
+ break;
+# endif
+# ifdef ENABLE_SHA1_SIGNED_CERTS
+ case OID_SHA1_ALG:
+ if (len != SHA1_HASH_SIZE)
+ {
+ psTraceCrypto("SHA1_HASH_SIZE error in x509ConfirmSignature\n");
+ return PS_LIMIT_FAIL;
+ }
+ break;
+# endif
+# ifdef USE_SHA256
+ case OID_SHA256_ALG:
+ if (len != SHA256_HASH_SIZE)
+ {
+ psTraceCrypto("SHA256_HASH_SIZE error in x509ConfirmSignature\n");
+ return PS_LIMIT_FAIL;
+ }
+ break;
+# endif
+# ifdef USE_SHA384
+ case OID_SHA384_ALG:
+ if (len != SHA384_HASH_SIZE)
+ {
+ psTraceCrypto("SHA384_HASH_SIZE error in x509ConfirmSignature\n");
+ return PS_LIMIT_FAIL;
+ }
+ break;
+# endif
+# ifdef USE_SHA512
+ case OID_SHA512_ALG:
+ if (len != SHA512_HASH_SIZE)
+ {
+ psTraceCrypto("SHA512_HASH_SIZE error in x509ConfirmSignature\n");
+ return PS_LIMIT_FAIL;
+ }
+ break;
+# endif
+ default:
+ psTraceCrypto("Unsupported alg ID error in x509ConfirmSignature\n");
+ return PS_UNSUPPORTED_FAIL;
+ }
+ /* hash should match sigHash */
+ if (memcmpct(hash, sigHash, len) != 0)
+ {
+ psTraceCrypto("Signature failure in x509ConfirmSignature\n");
+ return PS_SIGNATURE_MISMATCH;
+ }
+ return PS_SUCCESS;
}
-#endif /* USE_RSA */
+# endif /* USE_RSA */
/******************************************************************************/
-#endif /* USE_CERT_PARSE */
+# endif /* USE_CERT_PARSE */
-#ifdef USE_OCSP
+# ifdef USE_OCSP
/******************************************************************************/
static int32_t parse_nonce_ext(const unsigned char *p, size_t sz,
- psBuf_t *nonceExtension)
+ psBuf_t *nonceExtension)
{
- psParseBuf_t pb;
- psParseBuf_t extensions;
- psParseBuf_t extension;
+ psParseBuf_t pb;
+ psParseBuf_t extensions;
+ psParseBuf_t extension;
- memset(nonceExtension, 0, sizeof(psBuf_t));
- if (psParseBufFromStaticData(&pb, p, sz) == PS_SUCCESS) {
- if (psParseBufTryReadTagSub(&pb, &extensions, 0xA1)) {
- while(psParseBufTryReadSequenceSub(&extensions,
- &extension)) {
- psParseBuf_t sub;
- psParseBufReadSequenceSub(&extension, &sub);
- if (psParseBufTrySkipBytes(
- &sub,
- (const unsigned char *)
- "\x06\x09\x2b\x06\x01\x05"
- "\x05\x07\x30\x01\x02", 11)) {
- psParseBufReadTagRef(
- &sub, nonceExtension, 0x04);
- }
- psParseBufFinish(&sub);
- if (psParseBufFinish(&extension) != PS_SUCCESS)
- break;
- }
- psParseBufFinish(&extensions);
- }
- }
- return PS_SUCCESS; /* No parsing errors detected. */
+ memset(nonceExtension, 0, sizeof(psBuf_t));
+ if (psParseBufFromStaticData(&pb, p, sz) == PS_SUCCESS)
+ {
+ if (psParseBufTryReadTagSub(&pb, &extensions, 0xA1))
+ {
+ while (psParseBufTryReadSequenceSub(&extensions,
+ &extension))
+ {
+ psParseBuf_t sub;
+ psParseBufReadSequenceSub(&extension, &sub);
+ if (psParseBufTrySkipBytes(
+ &sub,
+ (const unsigned char *)
+ "\x06\x09\x2b\x06\x01\x05"
+ "\x05\x07\x30\x01\x02", 11))
+ {
+ psParseBufReadTagRef(
+ &sub, nonceExtension, 0x04);
+ }
+ psParseBufFinish(&sub);
+ if (psParseBufFinish(&extension) != PS_SUCCESS)
+ {
+ break;
+ }
+ }
+ psParseBufFinish(&extensions);
+ }
+ }
+ return PS_SUCCESS; /* No parsing errors detected. */
}
static void parseSingleResponseRevocationTimeAndReason(
- const unsigned char *p,
- uint16_t glen,
- mOCSPSingleResponse_t *res)
+ const unsigned char *p,
+ psSize_t glen,
+ psOcspSingleResponse_t *res)
{
- /* Note: res has to have been cleared before this function.
- The function does not fill-in the relevant fields if they are
- not found. */
+ /* Note: res has to have been cleared before this function.
+ The function does not fill-in the relevant fields if they are
+ not found. */
- /* get revocation time ASN.1 (GeneralizedTime / 0x18) */
- if (glen >= sizeof(res->revocationTime) + 2 &&
- p[0] == 0x18 && p[1] == sizeof(res->revocationTime)) {
- memcpy(res->revocationTime, p + 2,
- sizeof(res->revocationTime));
- /* revocationReason [0] EXPLICIT CRLReason OPTIONAL
- CRLReason ::= ENUMERATED [RFC 5280] */
- if (glen >= sizeof(res->revocationTime) + 0x5 &&
- p[17] == 0xa0 && /* [0] */
- p[18] == 0x03 && /* length */
- p[19] == 0x0a && /* ENUMERATED */
- p[20] == 0x01 && /* length */
- p[21] <= 10 && /* CRL reason code 0-10, excluding 7. */
- p[21] != 7) {
- res->revocationReason = p[21];
- }
- }
+ /* get revocation time ASN.1 (GeneralizedTime / 0x18) */
+ if (glen >= sizeof(res->revocationTime) + 2 &&
+ p[0] == 0x18 && p[1] == sizeof(res->revocationTime))
+ {
+ memcpy(res->revocationTime, p + 2,
+ sizeof(res->revocationTime));
+ /* revocationReason [0] EXPLICIT CRLReason OPTIONAL
+ CRLReason ::= ENUMERATED [RFC 5280] */
+ if (glen >= sizeof(res->revocationTime) + 0x5 &&
+ p[17] == 0xa0 && /* [0] */
+ p[18] == 0x03 && /* length */
+ p[19] == 0x0a && /* ENUMERATED */
+ p[20] == 0x01 && /* length */
+ p[21] <= 10 && /* CRL reason code 0-10, excluding 7. */
+ p[21] != 7)
+ {
+ res->revocationReason = p[21];
+ }
+ }
}
static int32_t parseSingleResponse(uint32_t len, const unsigned char **cp,
- const unsigned char *end, mOCSPSingleResponse_t *res)
+ const unsigned char *end, psOcspSingleResponse_t *res)
{
- const unsigned char *p;
- uint16_t glen, plen;
- int32_t oi;
-
- p = *cp;
-
- /* SingleResponse ::= SEQUENCE {
- certID CertID,
- certStatus CertStatus,
- thisUpdate GeneralizedTime,
- nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
- singleExtensions [1] EXPLICIT Extensions OPTIONAL }
- */
- if (getAsnSequence(&p, (int32)(end - p), &glen) < 0) {
- psTraceCrypto("Initial parseSingleResponse parse failure\n");
- return PS_PARSE_FAIL;
- }
- /* CertID ::= SEQUENCE {
- hashAlgorithm AlgorithmIdentifier
+ const unsigned char *p;
+ psSize_t glen, plen;
+ int32_t oi;
+
+ p = *cp;
+
+ /* SingleResponse ::= SEQUENCE {
+ certID CertID,
+ certStatus CertStatus,
+ thisUpdate GeneralizedTime,
+ nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
+ singleExtensions [1] EXPLICIT Extensions OPTIONAL }
+ */
+ if (getAsnSequence(&p, (int32) (end - p), &glen) < 0)
+ {
+ psTraceCrypto("Initial parseSingleResponse parse failure\n");
+ return PS_PARSE_FAIL;
+ }
+ /* CertID ::= SEQUENCE {
+ hashAlgorithm AlgorithmIdentifier
{DIGEST-ALGORITHM, {...}},
- issuerNameHash OCTET STRING, -- Hash of issuer's DN
- issuerKeyHash OCTET STRING, -- Hash of issuer's public key
- serialNumber CertificateSerialNumber }
- */
- if (getAsnSequence(&p, (int32)(end - p), &glen) < 0) {
- psTraceCrypto("Initial parseSingleResponse parse failure\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnAlgorithmIdentifier(&p, (int32)(end - p), &oi, &plen) < 0){
- return PS_FAILURE;
- }
- psAssert(plen == 0);
- res->certIdHashAlg = oi;
-
- if ((*p++ != ASN_OCTET_STRING) ||
- getAsnLength(&p, (int32)(end - p), &glen) < 0 ||
- (uint32)(end - p) < glen) {
- return PS_PARSE_FAIL;
- }
- res->certIdNameHash = p;
- p += glen;
-
- if ((*p++ != ASN_OCTET_STRING) ||
- getAsnLength(&p, (int32)(end - p), &glen) < 0 ||
- (uint32)(end - p) < glen) {
- return PS_PARSE_FAIL;
- }
- res->certIdKeyHash = p;
- p += glen;
-
- /* serialNumber CertificateSerialNumber
-
- CertificateSerialNumber ::= INTEGER
- */
- if ((*p != (ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE | 2)) &&
- (*p != ASN_INTEGER)) {
- psTraceCrypto("X.509 getSerialNum failed on first bytes\n");
- return PS_PARSE_FAIL;
- }
- p++;
+ issuerNameHash OCTET STRING, -- Hash of issuer's DN
+ issuerKeyHash OCTET STRING, -- Hash of issuer's public key
+ serialNumber CertificateSerialNumber }
+ */
+ if (getAsnSequence(&p, (int32) (end - p), &glen) < 0)
+ {
+ psTraceCrypto("Initial parseSingleResponse parse failure\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnAlgorithmIdentifier(&p, (int32) (end - p), &oi, &plen) < 0)
+ {
+ return PS_FAILURE;
+ }
+ psAssert(plen == 0);
+ res->certIdHashAlg = oi;
- if (getAsnLength(&p, (int32)(end - p), &glen) < 0 ||
- (uint32)(end - p) < glen) {
- psTraceCrypto("ASN getSerialNum failed\n");
- return PS_PARSE_FAIL;
- }
- res->certIdSerialLen = glen;
- res->certIdSerial = p;
- p += glen;
-
- /* CertStatus ::= CHOICE {
- good [0] IMPLICIT NULL,
- revoked [1] IMPLICIT RevokedInfo,
- unknown [2] IMPLICIT UnknownInfo }
- */
- memset(res->revocationTime, 0, sizeof(res->revocationTime));
- res->revocationReason = 0;
- if (*p == (ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE | 0)) {
- res->certStatus = 0;
- p += 2;
- } else if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
- res->certStatus = 1;
- psTraceCrypto("OCSP CertStatus is revoked.\n");
- /* RevokedInfo ::= SEQUENCE {
- revocationTime GeneralizedTime,
- revocationReason [0] EXPLICIT CRLReason OPTIONAL }
- */
- p += 1;
- if (getAsnLength(&p, (int32)(end - p), &glen) < 0) {
- psTraceCrypto("Initial parseSingleResponse parse failure\n");
- return PS_PARSE_FAIL;
- }
- /* subfunction for parsing RevokedInfo. */
- parseSingleResponseRevocationTimeAndReason(p, glen, res);
- p += glen;
- } else if (*p == (ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE | 2)) {
- res->certStatus = 2;
- p += 2; /* TOOD: Untested parse. Might be CONSTRUCTED encoding */
- /* UnknownInfo ::= NULL */
- } else {
- psTraceCrypto("OCSP CertStatus parse fail\n");
- return PS_PARSE_FAIL;
- }
-
- /* thisUpdate GeneralizedTime, */
- if ((end - p) < 1 || (*p != ASN_GENERALIZEDTIME)) {
- psTraceCrypto("Malformed thisUpdate OCSP\n");
- return PS_PARSE_FAIL;
- }
- p++;
- if (getAsnLength(&p, (uint32)(end - p), &glen) < 0 ||
- (uint32)(end - p) < glen) {
- return PS_PARSE_FAIL;
- }
- res->thisUpdateLen = glen;
- res->thisUpdate = p;
- p += glen;
+ if ((*p++ != ASN_OCTET_STRING) ||
+ getAsnLength(&p, (int32) (end - p), &glen) < 0 ||
+ (uint32) (end - p) < glen)
+ {
+ return PS_PARSE_FAIL;
+ }
+ res->certIdNameHash = p;
+ p += glen;
- /* nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, */
- res->nextUpdate = NULL;
- res->nextUpdateLen = 0;
- if ((uint32)(end - p) >= 2 &&
- *p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
- p++;
- if (getAsnLength(&p, (uint32)(end - p), &glen) < 0 ||
- (uint32)(end - p) < glen) {
- return PS_PARSE_FAIL;
- }
- if (*p == ASN_GENERALIZEDTIME && glen > 2) {
- res->nextUpdate = p + 2;
- res->nextUpdateLen = glen - 2;
- }
- p += glen;
- }
+ if ((*p++ != ASN_OCTET_STRING) ||
+ getAsnLength(&p, (int32) (end - p), &glen) < 0 ||
+ (uint32) (end - p) < glen)
+ {
+ return PS_PARSE_FAIL;
+ }
+ res->certIdKeyHash = p;
+ p += glen;
- /* singleExtensions [1] EXPLICIT Extensions OPTIONAL */
- if ((uint32)(end - p) >= 2 &&
- *p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
- p++;
- if (getAsnLength(&p, (uint32)(end - p), &glen) < 0 ||
- (uint32)(end - p) < glen) {
- return PS_PARSE_FAIL;
- }
- /* TODO */
- p += glen; /* SKIPPING */
- }
-
- *cp = (unsigned char*)p;
- return PS_SUCCESS;
+ /* serialNumber CertificateSerialNumber
+
+ CertificateSerialNumber ::= INTEGER
+ */
+ if ((*p != (ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE | 2)) &&
+ (*p != ASN_INTEGER))
+ {
+ psTraceCrypto("X.509 getSerialNum failed on first bytes\n");
+ return PS_PARSE_FAIL;
+ }
+ p++;
+
+ if (getAsnLength(&p, (int32) (end - p), &glen) < 0 ||
+ (uint32) (end - p) < glen)
+ {
+ psTraceCrypto("ASN getSerialNum failed\n");
+ return PS_PARSE_FAIL;
+ }
+ res->certIdSerialLen = glen;
+ res->certIdSerial = p;
+ p += glen;
+
+ /* CertStatus ::= CHOICE {
+ good [0] IMPLICIT NULL,
+ revoked [1] IMPLICIT RevokedInfo,
+ unknown [2] IMPLICIT UnknownInfo }
+ */
+ memset(res->revocationTime, 0, sizeof(res->revocationTime));
+ res->revocationReason = 0;
+ if (*p == (ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE | 0))
+ {
+ res->certStatus = 0;
+ p += 2;
+ }
+ else if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
+ {
+ res->certStatus = 1;
+ psTraceCrypto("OCSP CertStatus is revoked.\n");
+ /* RevokedInfo ::= SEQUENCE {
+ revocationTime GeneralizedTime,
+ revocationReason [0] EXPLICIT CRLReason OPTIONAL }
+ */
+ p += 1;
+ if (getAsnLength(&p, (int32) (end - p), &glen) < 0)
+ {
+ psTraceCrypto("Initial parseSingleResponse parse failure\n");
+ return PS_PARSE_FAIL;
+ }
+ /* subfunction for parsing RevokedInfo. */
+ parseSingleResponseRevocationTimeAndReason(p, glen, res);
+ p += glen;
+ }
+ else if (*p == (ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE | 2))
+ {
+ res->certStatus = 2;
+ p += 2; /* TOOD: Untested parse. Might be CONSTRUCTED encoding */
+ /* UnknownInfo ::= NULL */
+ }
+ else
+ {
+ psTraceCrypto("OCSP CertStatus parse fail\n");
+ return PS_PARSE_FAIL;
+ }
+
+ /* thisUpdate GeneralizedTime, */
+ if ((end - p) < 1 || (*p != ASN_GENERALIZEDTIME))
+ {
+ psTraceCrypto("Malformed thisUpdate OCSP\n");
+ return PS_PARSE_FAIL;
+ }
+ p++;
+ if (getAsnLength(&p, (uint32) (end - p), &glen) < 0 ||
+ (uint32) (end - p) < glen)
+ {
+ return PS_PARSE_FAIL;
+ }
+ res->thisUpdateLen = glen;
+ res->thisUpdate = p;
+ p += glen;
+
+ /* nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, */
+ res->nextUpdate = NULL;
+ res->nextUpdateLen = 0;
+ if ((uint32) (end - p) >= 2 &&
+ *p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
+ {
+ p++;
+ if (getAsnLength(&p, (uint32) (end - p), &glen) < 0 ||
+ (uint32) (end - p) < glen)
+ {
+ return PS_PARSE_FAIL;
+ }
+ if (*p == ASN_GENERALIZEDTIME && glen > 2)
+ {
+ res->nextUpdate = p + 2;
+ res->nextUpdateLen = glen - 2;
+ }
+ p += glen;
+ }
+
+ /* singleExtensions [1] EXPLICIT Extensions OPTIONAL */
+ if ((uint32) (end - p) >= 2 &&
+ *p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
+ {
+ p++;
+ if (getAsnLength(&p, (uint32) (end - p), &glen) < 0 ||
+ (uint32) (end - p) < glen)
+ {
+ return PS_PARSE_FAIL;
+ }
+ /* TODO */
+ p += glen; /* SKIPPING */
+ }
+
+ *cp = (unsigned char *) p;
+ return PS_SUCCESS;
}
-static int32_t parseBasicOCSPResponse(psPool_t *pool, uint32_t len,
- const unsigned char **cp, unsigned char *end,
- mOCSPResponse_t *res)
+static int32_t ocspParseBasicResponse(psPool_t *pool, uint32_t len,
+ const unsigned char **cp, unsigned char *end,
+ psOcspResponse_t *res)
{
- const unsigned char *p, *seqend, *startRes, *endRes;
- mOCSPSingleResponse_t *singleResponse;
- psSha1_t sha;
-#ifdef USE_SHA256
- psSha256_t sha2;
-#endif
-#ifdef USE_SHA384
- psSha384_t sha3;
-#endif
- uint16_t glen, plen;
- uint32_t blen;
- int32_t version, oid;
-
- /* id-pkix-ocsp-basic
-
- BasicOCSPResponse ::= SEQUENCE {
- tbsResponseData ResponseData,
- signatureAlgorithm AlgorithmIdentifier,
- signature BIT STRING,
- certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
- */
- p = *cp;
-
- if (getAsnSequence(&p, (uint32)(end - p), &glen) < 0) {
- psTraceCrypto("Initial parse error in parseBasicOCSPResponse\n");
- return PS_PARSE_FAIL;
- }
- /*
- ResponseData ::= SEQUENCE {
- version [0] EXPLICIT Version DEFAULT v1,
- responderID ResponderID,
- producedAt GeneralizedTime,
- responses SEQUENCE OF SingleResponse,
- responseExtensions [1] EXPLICIT Extensions OPTIONAL }
- */
- startRes = p; /* A response signature will be over ResponseData */
- if (getAsnSequence(&p, (uint32)(end - p), &glen) < 0) {
- psTraceCrypto("Early ResponseData parse error in parseOCSPResponse\n");
- return PS_PARSE_FAIL;
- }
- if (getExplicitVersion(&p, (uint32)(end - p), 0, &version) < 0) {
- psTraceCrypto("Version parse error in ResponseData\n");
- return PS_PARSE_FAIL;
- }
- if (version != 0) {
- psTraceIntCrypto("WARNING: Unknown OCSP ResponseData version %d\n",
- version);
- }
- /*
- ResponderID ::= CHOICE {
- byName [1] Name,
- byKey [2] KeyHash }
- */
- if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
- psTraceCrypto("TODO: Unsupported byName ResponderID in ResponseData\n");
- return PS_PARSE_FAIL;
- } else if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) {
- p++;
- if (getAsnLength32(&p, (uint32_t)(end - p), &blen, 0) < 0 ||
- (uint32_t)(end - p) < blen) {
- psTraceCrypto("Error parsing KeyHash in ResponseData\n");
- return PS_PARSE_FAIL;
- }
- /* KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key
+ const unsigned char *p, *seqend, *startRes, *endRes;
+ psOcspSingleResponse_t *singleResponse;
+ psSha1_t sha;
+
+# ifdef USE_SHA256
+ psSha256_t sha2;
+# endif
+# ifdef USE_SHA384
+ psSha384_t sha3;
+# endif
+ psSize_t glen, plen;
+ uint32_t blen;
+ int32_t version, oid;
+ int32_t cert_res;
+
+ /* id-pkix-ocsp-basic
+
+ BasicOCSPResponse ::= SEQUENCE {
+ tbsResponseData ResponseData,
+ signatureAlgorithm AlgorithmIdentifier,
+ signature BIT STRING,
+ certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ */
+ p = *cp;
+
+ if (getAsnSequence(&p, (uint32) (end - p), &glen) < 0)
+ {
+ psTraceCrypto("Initial parse error in ocspParseBasicResponse\n");
+ return PS_PARSE_FAIL;
+ }
+ /*
+ ResponseData ::= SEQUENCE {
+ version [0] EXPLICIT Version DEFAULT v1,
+ responderID ResponderID,
+ producedAt GeneralizedTime,
+ responses SEQUENCE OF SingleResponse,
+ responseExtensions [1] EXPLICIT Extensions OPTIONAL }
+ */
+ startRes = p; /* A response signature will be over ResponseData */
+ if (getAsnSequence(&p, (uint32) (end - p), &glen) < 0)
+ {
+ psTraceCrypto("Early ResponseData parse error in psOcspParseResponse\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getExplicitVersion(&p, (uint32) (end - p), 0, &version) < 0)
+ {
+ psTraceCrypto("Version parse error in ResponseData\n");
+ return PS_PARSE_FAIL;
+ }
+ res->version = version;
+ if (version != 0)
+ {
+ psTraceIntCrypto("WARNING: Unknown OCSP ResponseData version %d\n",
+ version);
+ return PS_VERSION_UNSUPPORTED;
+ }
+ /*
+ ResponderID ::= CHOICE {
+ byName [1] Name,
+ byKey [2] KeyHash }
+ */
+
+ if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
+ {
+ const unsigned char *p2;
+ p++;
+ if (getAsnLength32(&p, (uint32_t) (end - p), &blen, 0) < 0 ||
+ (uint32_t) (end - p) < blen || blen == 0)
+ {
+ psTraceCrypto("Error parsing Name in ResponseData\n");
+ return PS_PARSE_FAIL;
+ }
+ res->responderName = p;
+ res->responderKeyHash = NULL;
+ p2 = p;
+ p += blen;
+ /* Check contents of ASN Sequence containing Name. */
+ if ((*p2++ != (ASN_CONSTRUCTED | ASN_SEQUENCE)) ||
+ getAsnLength32(&p2, (int32) (end - p2), &blen, 0) < 0 ||
+ p != p2 + blen)
+ {
+ psTraceCrypto("Error parsing Name in ResponseData\n");
+ res->responderName = NULL;
+ return PS_PARSE_FAIL;
+ }
+ }
+ else if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2))
+ {
+ p++;
+ if (getAsnLength32(&p, (uint32_t) (end - p), &blen, 0) < 0 ||
+ (uint32_t) (end - p) < blen)
+ {
+ psTraceCrypto("Error parsing KeyHash in ResponseData\n");
+ return PS_PARSE_FAIL;
+ }
+ /* KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key
-- (i.e., the SHA-1 hash of the value of the
-- BIT STRING subjectPublicKey [excluding
-- the tag, length, and number of unused
-- bits] in the responder's certificate) */
- if ((*p++ != ASN_OCTET_STRING) ||
- getAsnLength(&p, (int32)(end - p), &glen) < 0 ||
- (uint32)(end - p) < glen) {
+ if ((*p++ != ASN_OCTET_STRING) ||
+ getAsnLength(&p, (int32) (end - p), &glen) < 0 ||
+ (uint32) (end - p) < glen ||
+ glen != SHA1_HASH_SIZE)
+ {
- psTraceCrypto("Couldn't parse KeyHash in ResponseData\n");
- return PS_FAILURE;
- }
- psAssert(glen == SHA1_HASH_SIZE);
- res->responderKeyHash = p;
- p += SHA1_HASH_SIZE;
- } else {
- psTraceCrypto("ResponderID parse error in ResponseData\n");
- return PS_PARSE_FAIL;
- }
-
- /* producedAt GeneralizedTime, */
- if ((end - p) < 1 || (*p != ASN_GENERALIZEDTIME)) {
- psTraceCrypto("Malformed thisUpdate CRL\n");
- return PS_PARSE_FAIL;
- }
- p++;
- if (getAsnLength(&p, (uint32)(end - p), &glen) < 0 ||
- (uint32)(end - p) < glen) {
- psTraceCrypto("Malformed producedAt in ResponseData\n");
- return PS_PARSE_FAIL;
- }
- /* Perform quick parsing on data. */
- if (psBrokenDownTimeImport(NULL, (const char *) p, glen, 0) < 0)
- return PS_PARSE_FAIL;
- res->timeProducedLen = glen;
- res->timeProduced = p;
- p += glen;
+ psTraceCrypto("Couldn't parse KeyHash in ResponseData\n");
+ return PS_FAILURE;
+ }
+ psAssert(glen == SHA1_HASH_SIZE);
+ res->responderName = NULL;
+ res->responderKeyHash = p;
+ p += SHA1_HASH_SIZE;
+ }
+ else
+ {
+ psTraceCrypto("ResponderID parse error in ResponseData\n");
+ return PS_PARSE_FAIL;
+ }
- /* responses SEQUENCE OF SingleResponse, */
- if (getAsnSequence(&p, (int32)(end - p), &glen) < 0) {
- psTraceCrypto("Initial SingleResponse parse failure\n");
- return PS_PARSE_FAIL;
- }
+ /* producedAt GeneralizedTime, */
+ if ((end - p) < 1 || (*p != ASN_GENERALIZEDTIME))
+ {
+ psTraceCrypto("Malformed thisUpdate CRL\n");
+ return PS_PARSE_FAIL;
+ }
+ p++;
+ if (getAsnLength(&p, (uint32) (end - p), &glen) < 0 ||
+ (uint32) (end - p) < glen)
+ {
+ psTraceCrypto("Malformed producedAt in ResponseData\n");
+ return PS_PARSE_FAIL;
+ }
+ /* Perform quick parsing on data. */
+ if (psBrokenDownTimeImport(NULL, (const char *) p, glen, 0) < 0)
+ {
+ return PS_PARSE_FAIL;
+ }
+ res->timeProducedLen = glen;
+ res->timeProduced = p;
+ p += glen;
- seqend = p + glen;
+ /* responses SEQUENCE OF SingleResponse, */
+ if (getAsnSequence(&p, (int32) (end - p), &glen) < 0)
+ {
+ psTraceCrypto("Initial SingleResponse parse failure\n");
+ return PS_PARSE_FAIL;
+ }
- plen = 0; /* for MAX_OCSP_RESPONSES control */
- while (p < seqend) {
- singleResponse = &res->singleResponse[plen];
- if (parseSingleResponse(glen, &p, seqend, singleResponse) < 0) {
- return PS_PARSE_FAIL;
- }
- plen++;
- if (p < seqend) {
- /* Additional responses */
- if (plen == MAX_OCSP_RESPONSES) {
- psTraceCrypto("ERROR: Multiple OCSP SingleResponse items. ");
- psTraceCrypto("Increase MAX_OCSP_RESPONSES to support\n");
- return PS_PARSE_FAIL;
- }
- }
- }
- /* responseExtensions [1] EXPLICIT Extensions OPTIONAL } */
- if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) {
- if (parse_nonce_ext(p, end - p, &res->nonce) != PS_SUCCESS)
- return PS_PARSE_FAIL;
- p++;
- if (getAsnLength(&p, (uint32)(end - p), &glen) < 0 ||
- (uint32)(end - p) < glen) {
- return PS_PARSE_FAIL;
- }
- /* TODO: */
- p += glen; /* SKIPPING */
- }
- endRes = p;
-
- /* ResponseData DONE. On to signature:
-
- signatureAlgorithm AlgorithmIdentifier
- signature BIT STRING,
-
- The value for signature SHALL be computed on the hash of the DER
- encoding of ResponseData. The responder MAY include certificates in
- the certs field of BasicOCSPResponse that help the OCSP client
- verify the responder's signature. If no certificates are included,
- then certs SHOULD be absent. */
- if (getAsnAlgorithmIdentifier(&p, (uint32)(end - p), &oid, &plen) < 0) {
- psTraceCrypto("Initial SingleResponse parse failure\n");
- return PS_PARSE_FAIL;
- }
- if (plen > 0) {
- psTraceCrypto("Algorithm parameters on ResponseData sigAlg\n");
- p += plen;
- }
- res->sigAlg = oid;
-
- switch (oid) {
- /* OSCP requires SHA1 so no wrapper here */
- case OID_SHA1_RSA_SIG:
-#ifdef USE_ECC
- case OID_SHA1_ECDSA_SIG:
-#endif
- res->hashLen = SHA1_HASH_SIZE;
- psSha1Init(&sha);
- psSha1Update(&sha, startRes, (int32)(endRes - startRes));
- psSha1Final(&sha, res->hashResult);
- break;
-#ifdef USE_SHA256
- case OID_SHA256_RSA_SIG:
-#ifdef USE_ECC
- case OID_SHA256_ECDSA_SIG:
-#endif
- res->hashLen = SHA256_HASH_SIZE;
- psSha256Init(&sha2);
- psSha256Update(&sha2, startRes, (int32)(endRes - startRes));
- psSha256Final(&sha2, res->hashResult);
- break;
-#endif
-#ifdef USE_SHA384
- case OID_SHA384_RSA_SIG:
-#ifdef USE_ECC
- case OID_SHA384_ECDSA_SIG:
-#endif
- res->hashLen = SHA384_HASH_SIZE;
- psSha384Init(&sha3);
- psSha384Update(&sha3, startRes, (int32)(endRes - startRes));
- psSha384Final(&sha3, res->hashResult);
- break;
-#endif
- default:
- psTraceCrypto("No support for sigAlg in OCSP ResponseData\n");
- return PS_UNSUPPORTED_FAIL;
- }
+ seqend = p + glen;
- if (*p++ != ASN_BIT_STRING) {
- psTraceCrypto("Error parsing signature in ResponseData\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnLength(&p, (int32)(end - p), &glen) < 0 ||
- (uint32)(end - p) < glen) {
- psTraceCrypto("Error parsing signature in ResponseData\n");
- return PS_PARSE_FAIL;
- }
- if (*p++ != 0) {
- psTraceCrypto("Error parsing ignore bits in ResponseData sig\n");
- return PS_PARSE_FAIL;
- }
- glen--; /* ignore bits above */
- res->sig = p;
- res->sigLen = glen;
- p += glen;
+ plen = 0; /* for MAX_OCSP_RESPONSES control */
+ while (p < seqend)
+ {
+ singleResponse = &res->singleResponse[plen];
+ if (parseSingleResponse(glen, &p, seqend, singleResponse) < 0)
+ {
+ return PS_PARSE_FAIL;
+ }
+ plen++;
+ if (p < seqend)
+ {
+ /* Additional responses */
+ if (plen == MAX_OCSP_RESPONSES)
+ {
+ psTraceCrypto("ERROR: Multiple OCSP SingleResponse items. ");
+ psTraceCrypto("Increase MAX_OCSP_RESPONSES to support\n");
+ return PS_PARSE_FAIL;
+ }
+ }
+ }
+ /* responseExtensions [1] EXPLICIT Extensions OPTIONAL } */
+ if (*p == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
+ {
+ if (parse_nonce_ext(p, end - p, &res->nonce) != PS_SUCCESS)
+ {
+ return PS_PARSE_FAIL;
+ }
+ p++;
+ if (getAsnLength(&p, (uint32) (end - p), &glen) < 0 ||
+ (uint32) (end - p) < glen)
+ {
+ return PS_PARSE_FAIL;
+ }
+ /* TODO: */
+ p += glen; /* SKIPPING */
+ }
+ endRes = p;
- /* certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } */
- if (end != p) {
- /* The responder MAY include certificates in the certs field of
- BasicOCSPResponse that help the OCSP client verify the responder's
- signature. */
- if (*p != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) {
- psTraceCrypto("Unexpected Certificage encoding in OCSPResponse\n");
- return PS_PARSE_FAIL;
- }
- p++;
- if (getAsnLength(&p, (uint32)(end - p), &glen) < 0 ||
- (uint32)(end - p) < glen) {
- return PS_PARSE_FAIL;
- }
- /* If here, this is the cert that issued the OCSPResponse. Will
- authenticate during validateOCSPResponse */
- if (getAsnSequence(&p, (uint32)(end - p), &glen) < 0) {
- psTraceCrypto("\n");
- return PS_PARSE_FAIL;
- }
- psAssert(glen == (end - p));
- /* reusing oid. will handle multiple certs if needed */
- oid = psX509ParseCert(pool, p, glen, &res->OCSPResponseCert, 0);
- if (oid < 0) {
- psX509FreeCert(res->OCSPResponseCert);
- return PS_PARSE_FAIL;
- }
- p += oid;
- }
- psAssert(p == end);
-
- *cp = (unsigned char*)p;
- return PS_SUCCESS;
+ /* ResponseData DONE. On to signature:
+
+ signatureAlgorithm AlgorithmIdentifier
+ signature BIT STRING,
+
+ The value for signature SHALL be computed on the hash of the DER
+ encoding of ResponseData. The responder MAY include certificates in
+ the certs field of BasicOCSPResponse that help the OCSP client
+ verify the responder's signature. If no certificates are included,
+ then certs SHOULD be absent. */
+ if (getAsnAlgorithmIdentifier(&p, (uint32) (end - p), &oid, &plen) < 0)
+ {
+ psTraceCrypto("Initial SingleResponse parse failure\n");
+ return PS_PARSE_FAIL;
+ }
+ if (plen > 0)
+ {
+ psTraceCrypto("Algorithm parameters on ResponseData sigAlg\n");
+ p += plen;
+ }
+ res->sigAlg = oid;
+
+ switch (oid)
+ {
+ /* OSCP requires SHA1 so no wrapper here */
+ case OID_SHA1_RSA_SIG:
+ case OID_SHA1_RSA_SIG2:
+# ifdef USE_ECC
+ case OID_SHA1_ECDSA_SIG:
+# endif
+ res->hashLen = SHA1_HASH_SIZE;
+ psSha1Init(&sha);
+ psSha1Update(&sha, startRes, (int32) (endRes - startRes));
+ psSha1Final(&sha, res->hashResult);
+ break;
+# ifdef USE_SHA256
+ case OID_SHA256_RSA_SIG:
+# ifdef USE_ECC
+ case OID_SHA256_ECDSA_SIG:
+# endif
+ res->hashLen = SHA256_HASH_SIZE;
+ psSha256Init(&sha2);
+ psSha256Update(&sha2, startRes, (int32) (endRes - startRes));
+ psSha256Final(&sha2, res->hashResult);
+ break;
+# endif
+# ifdef USE_SHA384
+ case OID_SHA384_RSA_SIG:
+# ifdef USE_ECC
+ case OID_SHA384_ECDSA_SIG:
+# endif
+ res->hashLen = SHA384_HASH_SIZE;
+ psSha384Init(&sha3);
+ psSha384Update(&sha3, startRes, (int32) (endRes - startRes));
+ psSha384Final(&sha3, res->hashResult);
+ break;
+# endif
+ default:
+ psTraceCrypto("No support for sigAlg in OCSP ResponseData\n");
+ return PS_UNSUPPORTED_FAIL;
+ }
+
+ if (*p++ != ASN_BIT_STRING)
+ {
+ psTraceCrypto("Error parsing signature in ResponseData\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnLength(&p, (int32) (end - p), &glen) < 0 ||
+ (uint32) (end - p) < glen)
+ {
+ psTraceCrypto("Error parsing signature in ResponseData\n");
+ return PS_PARSE_FAIL;
+ }
+ if (*p++ != 0)
+ {
+ psTraceCrypto("Error parsing ignore bits in ResponseData sig\n");
+ return PS_PARSE_FAIL;
+ }
+ glen--; /* ignore bits above */
+ res->sig = p;
+ res->sigLen = glen;
+ p += glen;
+
+ /* certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } */
+ if (end != p)
+ {
+ /* The responder MAY include certificates in the certs field of
+ BasicOCSPResponse that help the OCSP client verify the responder's
+ signature. */
+ if (*p != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0))
+ {
+ psTraceCrypto("Unexpected Certificage encoding in OCSPResponse\n");
+ return PS_PARSE_FAIL;
+ }
+ p++;
+ if (getAsnLength(&p, (uint32) (end - p), &glen) < 0 ||
+ (uint32) (end - p) < glen)
+ {
+ return PS_PARSE_FAIL;
+ }
+ /* If here, this is the cert that issued the OCSPResponse. Will
+ authenticate during psOcspResponseValidateOld */
+ if (getAsnSequence(&p, (uint32) (end - p), &glen) < 0)
+ {
+ psTraceCrypto("\n");
+ return PS_PARSE_FAIL;
+ }
+ psAssert(glen == (end - p));
+ /* will handle multiple certs if needed.
+ Store certificate for reference. */
+ cert_res = psX509ParseCert(pool, p, glen, &res->OCSPResponseCert,
+ CERT_STORE_UNPARSED_BUFFER);
+ if (cert_res < 0)
+ {
+ psX509FreeCert(res->OCSPResponseCert);
+ return PS_PARSE_FAIL;
+ }
+ p += cert_res;
+ }
+ psAssert(p == end);
+
+ *cp = (unsigned char *) p;
+ return PS_SUCCESS;
}
-int32_t parseOCSPResponse(psPool_t *pool, int32_t len, unsigned char **cp,
- unsigned char *end, mOCSPResponse_t *response)
+int32_t psOcspResponseGetStatus(int32_t rc)
{
- const unsigned char *p;
- int32_t status, oi;
- uint16_t glen;
- uint32_t blen;
-
- p = *cp;
- //psTraceBytes("OCSPResponse", p, len);
- /*
- OCSPResponse ::= SEQUENCE {
- responseStatus OCSPResponseStatus,
- responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
- */
- if (getAsnSequence(&p, (uint32)(end - p), &glen) < 0) {
- psTraceCrypto("Initial parse error in parseOCSPResponse\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnEnumerated(&p, (uint32)(end - p), &status) < 0) {
- psTraceCrypto("Enum parse error in parseOCSPResponse\n");
- return PS_PARSE_FAIL;
- }
- /*
- OCSPResponseStatus ::= ENUMERATED {
- successful (0), -- Response has valid confirmations
- malformedRequest (1), -- Illegal confirmation request
- internalError (2), -- Internal error in issuer
- tryLater (3), -- Try again later
+ /* Check if response code is within
+ PS_OCSP_MALFORMED_REQUEST ... PS_OCSP_UNAUTHORIZED range. */
+ if (rc >= PS_OCSP_MALFORMED_REQUEST && rc <= PS_OCSP_UNAUTHORIZED)
+ {
+ rc -= PS_OCSP_MALFORMED_REQUEST - 1;
+ /* Return code 4 is not used. */
+ if (rc != 4)
+ {
+ return rc;
+ }
+ }
+
+ return rc == PS_SUCCESS ? 0 /* successful */ : PS_FAILURE /* other error */;
+}
+
+int32_t psOcspParseResponse(psPool_t *pool, int32_t len, unsigned char **cp,
+ unsigned char *end, psOcspResponse_t *response)
+{
+ const unsigned char *p;
+ int32_t err;
+ int32_t status, oi;
+ psSize_t glen;
+ uint32_t blen;
+
+ p = *cp;
+ /* psTraceBytes("OCSPResponse", p, len); */
+ /*
+ OCSPResponse ::= SEQUENCE {
+ responseStatus OCSPResponseStatus,
+ responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
+ */
+ if (getAsnSequence(&p, (uint32) (end - p), &glen) < 0)
+ {
+ psTraceCrypto("Initial parse error in psOcspParseResponse\n");
+ return PS_PARSE_FAIL;
+ }
+ if (getAsnEnumerated(&p, (uint32) (end - p), &status) < 0)
+ {
+ psTraceCrypto("Enum parse error in psOcspParseResponse\n");
+ return PS_PARSE_FAIL;
+ }
+ /*
+ OCSPResponseStatus ::= ENUMERATED {
+ successful (0), -- Response has valid confirmations
+ malformedRequest (1), -- Illegal confirmation request
+ internalError (2), -- Internal error in issuer
+ tryLater (3), -- Try again later
-- (4) is not used
- sigRequired (5), -- Must sign the request
- unauthorized (6) -- Request unauthorized
- }
- */
- if (status != 0) {
- /* Something other than success. List right above here */
- psTraceCrypto("OCSPResponse contains no valid confirmations\n");
- return PS_PARSE_FAIL;
- }
-
- /* responseBytes [0] EXPLICIT ResponseBytes OPTIONAL, */
- if (*p == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) {
- p++;
- if (getAsnLength32(&p, (uint32_t)(end - p), &blen, 0) < 0 ||
- (uint32_t)(end - p) < blen) {
- psTraceCrypto("Error parsing UserKeyingMaterial\n");
- return PS_PARSE_FAIL;
- }
+ sigRequired (5), -- Must sign the request
+ unauthorized (6) -- Request unauthorized
+ }
+ */
+ if (status != 0)
+ {
+ /* Something other than success. List right above here */
+ psTraceCrypto("OCSPResponse contains no valid confirmations\n");
+ if (status <= 6 && status != 4)
+ {
+ /* Map status codes to return codes. */
+ return status + (PS_OCSP_MALFORMED_REQUEST - 1);
+ }
+ /* Status code is outside valid range. */
+ return PS_PARSE_FAIL;
+ }
- /* ResponseBytes ::= SEQUENCE {
- responseType OBJECT IDENTIFIER,
- response OCTET STRING }
- */
- if (getAsnSequence(&p, (uint32)(end - p), &glen) < 0) {
- psTraceCrypto("ResponseBytes parse error in parseOCSPResponse\n");
- return PS_PARSE_FAIL;
- }
- if (getAsnOID(&p, (uint32)(end - p), &oi, 1, &glen) < 0) {
- psTraceCrypto("responseType parse error in parseOCSPResponse\n");
- return PS_PARSE_FAIL;
- }
- if ((*p++ != ASN_OCTET_STRING) ||
- getAsnLength32(&p, (int32)(end - p), &blen, 0) < 0 ||
- (uint32)(end - p) < blen) {
+ /* responseBytes [0] EXPLICIT ResponseBytes OPTIONAL, */
+ if (*p == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
+ {
+ p++;
+ if (getAsnLength32(&p, (uint32_t) (end - p), &blen, 0) < 0 ||
+ (uint32_t) (end - p) < blen)
+ {
+ psTraceCrypto("Error parsing UserKeyingMaterial\n");
+ return PS_PARSE_FAIL;
+ }
- psTraceCrypto("Couldn't parse response in parseOCSPResponse\n");
- return PS_PARSE_FAIL;
- }
- if (oi == OID_BASIC_OCSP_RESPONSE) {
- /* id-pkix-ocsp-basic
-
- BasicOCSPResponse ::= SEQUENCE {
- tbsResponseData ResponseData,
- signatureAlgorithm AlgorithmIdentifier,
- signature BIT STRING,
- certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
- */
- memset(response, 0, sizeof(*response));
- if (parseBasicOCSPResponse(pool, blen, &p, end, response) < 0) {
- psTraceCrypto("parseBasicOCSPResponse failure\n");
- return PS_PARSE_FAIL;
- }
- } else if (oi == OID_OCSP) {
- /* id-pkix-ocsp */
- psTraceCrypto("unsupported id-pkix-ocsp in parseOCSPResponse\n");
- return PS_PARSE_FAIL;
- } else {
- psTraceCrypto("unsupported responseType in parseOCSPResponse\n");
- return PS_PARSE_FAIL;
- }
-
- }
- psAssert(end == p);
- *cp = (unsigned char*)p;
- return PS_SUCCESS;
+ /* ResponseBytes ::= SEQUENCE {
+ responseType OBJECT IDENTIFIER,
+ response OCTET STRING }
+ */
+ if (getAsnSequence(&p, (uint32) (end - p), &glen) < 0)
+ {
+ psTraceCrypto("ResponseBytes parse error in psOcspParseResponse\n");
+ return PS_PARSE_FAIL;
+ }
+ response->responseType = p;
+ if (getAsnOID(&p, (uint32) (end - p), &oi, 1, &glen) < 0)
+ {
+ response->responseType = NULL;
+ psTraceCrypto("responseType parse error in psOcspParseResponse\n");
+ return PS_PARSE_FAIL;
+ }
+ if ((*p++ != ASN_OCTET_STRING) ||
+ getAsnLength32(&p, (int32) (end - p), &blen, 0) < 0 ||
+ (uint32) (end - p) < blen)
+ {
+
+ psTraceCrypto("Couldn't parse response in psOcspParseResponse\n");
+ return PS_PARSE_FAIL;
+ }
+ if (oi == OID_BASIC_OCSP_RESPONSE)
+ {
+ /* id-pkix-ocsp-basic
+
+ BasicOCSPResponse ::= SEQUENCE {
+ tbsResponseData ResponseData,
+ signatureAlgorithm AlgorithmIdentifier,
+ signature BIT STRING,
+ certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ */
+ /* Clear response except keep response type.
+ Response type only remains valid as long as parsed response
+ is valid. */
+ const unsigned char *responseType = response->responseType;
+ memset(response, 0, sizeof(*response));
+ response->responseType = responseType;
+ err = ocspParseBasicResponse(pool, blen, &p, end, response);
+ if (err < 0)
+ {
+ psTraceCrypto("ocspParseBasicResponse failure\n");
+ return err;
+ }
+ }
+ else
+ {
+ psTraceCrypto("unsupported responseType in psOcspParseResponse\n");
+ return PS_MESSAGE_UNSUPPORTED;
+ }
+ }
+ psAssert(end == p);
+ *cp = (unsigned char *) p;
+ return PS_SUCCESS;
}
/* Check validity of OCSP response and obtain the date stamps from it.
@@ -5053,12 +6286,12 @@ int32_t parseOCSPResponse(psPool_t *pool, int32_t len, unsigned char **cp,
If time_now is not provided, the current time will be requested from
the oeprating system.
This function extracts data information from parsed OCSP response.
- Because the dates in mOCSPResponse_t are references to memory containing
+ Because the dates in psOcspResponse_t are references to memory containing
binary OCSP response, that memory must not have been released before calling
this function. time_linger is useful to deal with the fact that the
peer and this host may have tiny difference in their clocks.
- @param response Pointer to OCSP response structure (from parseOCSPResponse)
+ @param response Pointer to OCSP response structure (from psOcspParseResponse)
@param index The index of OCSP single response to handle (0 for the first).
@param timeNow A pointer to structure filled in with psGetBrokenDownGMTime(),
or gmtime(), structure initialized to all zero or NULL.
@@ -5077,493 +6310,641 @@ int32_t parseOCSPResponse(psPool_t *pool, int32_t len, unsigned char **cp,
@retval PS_PARSE_FAIL If error occurred parsing the data information in
the request.
*/
-int32_t checkOCSPResponseDates(mOCSPResponse_t *response,
- int index,
- psBrokenDownTime_t *timeNow,
- psBrokenDownTime_t *producedAt,
- psBrokenDownTime_t *thisUpdate,
- psBrokenDownTime_t *nextUpdate,
- int time_linger)
+int32_t psOcspResponseCheckDates(psOcspResponse_t *response,
+ int index,
+ psBrokenDownTime_t *timeNow,
+ psBrokenDownTime_t *producedAt,
+ psBrokenDownTime_t *thisUpdate,
+ psBrokenDownTime_t *nextUpdate,
+ int time_linger)
{
- psBrokenDownTime_t tmp, tmp2, tmp3, tmp4;
- unsigned char ok = 1;
- int32 err;
- mOCSPSingleResponse_t *subjectResponse;
- psBrokenDownTime_t timeNowLinger;
+ psBrokenDownTime_t tmp, tmp2, tmp3, tmp4;
+ unsigned char ok = 1;
+ int32 err;
+ psOcspSingleResponse_t *subjectResponse;
+ psBrokenDownTime_t timeNowLinger;
- if (index >= MAX_OCSP_RESPONSES)
- return PS_ARG_FAIL;
+ if (index >= MAX_OCSP_RESPONSES)
+ {
+ return PS_ARG_FAIL;
+ }
- if (timeNow == NULL) {
- memset(&tmp, 0, sizeof tmp);
- timeNow = &tmp;
- }
+ if (timeNow == NULL)
+ {
+ memset(&tmp, 0, sizeof tmp);
+ timeNow = &tmp;
+ }
- if (timeNow->tm_year == 0) {
- /* The structure appears not filled in, use psGetBrokenDownGMTime() to
- get the current time. */
- err = psGetBrokenDownGMTime(timeNow, 0);
- if (err != PS_SUCCESS)
- return PS_FAIL;
- }
- memcpy(&timeNowLinger, timeNow, sizeof timeNowLinger);
- err = psBrokenDownTimeAdd(&timeNowLinger, time_linger);
- if (err != PS_SUCCESS)
- return PS_FAIL;
+ if (timeNow->tm_year == 0)
+ {
+ /* The structure appears not filled in, use psGetBrokenDownGMTime() to
+ get the current time. */
+ err = psGetBrokenDownGMTime(timeNow, 0);
+ if (err != PS_SUCCESS)
+ {
+ return PS_FAIL;
+ }
+ }
+ memcpy(&timeNowLinger, timeNow, sizeof timeNowLinger);
+ err = psBrokenDownTimeAdd(&timeNowLinger, time_linger);
+ if (err != PS_SUCCESS)
+ {
+ return PS_FAIL;
+ }
- if (thisUpdate == NULL)
- thisUpdate = &tmp2;
+ if (thisUpdate == NULL)
+ {
+ thisUpdate = &tmp2;
+ }
- if (nextUpdate == NULL)
- nextUpdate = &tmp3;
+ if (nextUpdate == NULL)
+ {
+ nextUpdate = &tmp3;
+ }
- if (producedAt == NULL)
- producedAt = &tmp4;
+ if (producedAt == NULL)
+ {
+ producedAt = &tmp4;
+ }
- ok &= psBrokenDownTimeImport(producedAt,
- (const char *) response->timeProduced,
- response->timeProducedLen,
- 0) == PS_SUCCESS;
+ ok &= psBrokenDownTimeImport(producedAt,
+ (const char *) response->timeProduced,
+ response->timeProducedLen,
+ 0) == PS_SUCCESS;
- subjectResponse = &response->singleResponse[index];
+ subjectResponse = &response->singleResponse[index];
- if (subjectResponse->thisUpdate)
- ok &= psBrokenDownTimeImport(thisUpdate,
- (const char *) subjectResponse->thisUpdate,
- subjectResponse->thisUpdateLen,
- 0) == PS_SUCCESS;
- else
- ok = 0;
+ if (subjectResponse->thisUpdate)
+ {
+ ok &= psBrokenDownTimeImport(thisUpdate,
+ (const char *) subjectResponse->thisUpdate,
+ subjectResponse->thisUpdateLen,
+ 0) == PS_SUCCESS;
+ }
+ else
+ {
+ ok = 0;
+ }
- if (subjectResponse->nextUpdate != NULL) {
- /* Next update provided, OCSP is valid until that time. */
- ok &= psBrokenDownTimeImport(nextUpdate,
- (const char *) subjectResponse->nextUpdate,
- subjectResponse->nextUpdateLen,
- 0) == PS_SUCCESS;
- } else if (ok) {
- /* If there is no next update, the server supports
- continous updates and nextUpdate time is considered
- identical to the this update time. */
- ok &= psBrokenDownTimeImport(nextUpdate,
- (const char *) subjectResponse->thisUpdate,
- subjectResponse->thisUpdateLen,
- 0) == PS_SUCCESS;
- }
+ if (subjectResponse->nextUpdate != NULL)
+ {
+ /* Next update provided, OCSP is valid until that time. */
+ ok &= psBrokenDownTimeImport(nextUpdate,
+ (const char *) subjectResponse->nextUpdate,
+ subjectResponse->nextUpdateLen,
+ 0) == PS_SUCCESS;
+ }
+ else if (ok)
+ {
+ /* If there is no next update, the server supports
+ continous updates and nextUpdate time is considered
+ identical to the this update time. */
+ ok &= psBrokenDownTimeImport(nextUpdate,
+ (const char *) subjectResponse->thisUpdate,
+ subjectResponse->thisUpdateLen,
+ 0) == PS_SUCCESS;
+ }
- if (ok == 1) {
- /* Consider linger when comparing nextUpdateTime. */
- psBrokenDownTime_t nextUpdateTimeLinger;
- memcpy(&nextUpdateTimeLinger, nextUpdate, sizeof nextUpdateTimeLinger);
- err = psBrokenDownTimeAdd(&nextUpdateTimeLinger, time_linger);
- if (err != PS_SUCCESS)
- return err;
+ if (ok == 1)
+ {
+ /* Consider linger when comparing nextUpdateTime. */
+ psBrokenDownTime_t nextUpdateTimeLinger;
+ memcpy(&nextUpdateTimeLinger, nextUpdate, sizeof nextUpdateTimeLinger);
+ err = psBrokenDownTimeAdd(&nextUpdateTimeLinger, time_linger);
+ if (err != PS_SUCCESS)
+ {
+ return err;
+ }
- /* Now check that current time considering linger is between
- thisUpdate and nextUpdate. */
+ /* Now check that current time considering linger is between
+ thisUpdate and nextUpdate. */
- if (psBrokenDownTimeCmp(thisUpdate, &timeNowLinger) > 0) {
- /* thisUpdate is in future even considering linger => reject. */
- err = PS_TIMEOUT_FAIL;
- } else if (psBrokenDownTimeCmp(&nextUpdateTimeLinger, timeNow) < 0) {
- /* nextUpdate is in past even considering linger => reject. */
- err = PS_TIMEOUT_FAIL;
- } else {
- /* err has already been set to PS_SUCCESS */
- }
- } else {
- err = PS_PARSE_FAIL;
- }
- return err;
+ if (psBrokenDownTimeCmp(thisUpdate, &timeNowLinger) > 0)
+ {
+ /* thisUpdate is in future even considering linger => reject. */
+ err = PS_TIMEOUT_FAIL;
+ }
+ else if (psBrokenDownTimeCmp(&nextUpdateTimeLinger, timeNow) < 0)
+ {
+ /* nextUpdate is in past even considering linger => reject. */
+ err = PS_TIMEOUT_FAIL;
+ }
+ else
+ {
+ /* err has already been set to PS_SUCCESS */
+ }
+ }
+ else
+ {
+ err = PS_PARSE_FAIL;
+ }
+ return err;
}
/* Diff the current time against the OCSP timestamp and confirm it's not
longer than the user is willing to trust. */
-static int32_t checkOCSPtimestamp(mOCSPResponse_t *response, int index)
+static int32_t checkOCSPtimestamp(psOcspResponse_t *response, int index)
{
- return checkOCSPResponseDates(response, index, NULL, NULL, NULL, NULL,
- PS_OCSP_TIME_LINGER);
+ return psOcspResponseCheckDates(response, index, NULL, NULL, NULL, NULL,
+ PS_OCSP_TIME_LINGER);
}
/* Partial OCSP request parser: just locate nonceExtension if present. */
static int32_t parseOcspReq(const void *data, size_t datalen,
- psBuf_t *nonceExtension)
+ psBuf_t *nonceExtension)
{
- psParseBuf_t pb;
- psParseBuf_t ocspRequest;
- psParseBuf_t tbsRequest;
- psParseBuf_t extensions;
- psParseBuf_t extension;
- psParseBuf_t requestList;
- psParseBuf_t request;
- psParseBuf_t requestCert;
- psParseBuf_t requestCertContent;
- int rc;
+ psParseBuf_t pb;
+ psParseBuf_t ocspRequest;
+ psParseBuf_t tbsRequest;
+ psParseBuf_t extensions;
+ psParseBuf_t extension;
+ psParseBuf_t requestList;
+ psParseBuf_t request;
+ psParseBuf_t requestCert;
+ psParseBuf_t requestCertContent;
+ int rc;
- rc = psParseBufFromStaticData(&pb, data, datalen);
- if (rc != PS_SUCCESS)
- return rc;
- psParseBufReadSequenceSub(&pb, &ocspRequest);
- /* Ensure subbuffer is advanced and main buffer is not. */
- psParseBufReadSequenceSub(&ocspRequest, &tbsRequest);
- /* Ignore version number (v1 == 0) if present. */
- psParseBufTrySkipBytes(&tbsRequest, (const unsigned char *)
- "\xA0\x03\x02\x01\x00", 5);
- /* Skip requestorName if present. */
- psParseBufTrySkipTag(&tbsRequest, 0xA1);
- /* Skip requestList (must be present with at least one request). */
- psParseBufReadSequenceSub(&tbsRequest, &requestList);
- psParseBufReadSequenceSub(&requestList, &request);
- psParseBufReadSequenceSub(&request, &requestCert);
- psParseBufReadSequenceSub(&requestCert, &requestCertContent);
- psParseBufFinish(&requestCertContent);
- psParseBufFinish(&requestCert);
- psParseBufFinish(&request);
- psParseBufFinish(&requestList);
- if (psParseBufTryReadTagSub(&tbsRequest, &extensions, 0xA2)) {
- while(psParseBufTryReadSequenceSub(&extensions, &extension)) {
- psParseBuf_t sub;
- psParseBufReadSequenceSub(&extension, &sub);
- if (psParseBufTrySkipBytes(
- &sub,
- (const unsigned char *)
- "\x06\x09\x2b\x06\x01\x05"
- "\x05\x07\x30\x01\x02", 11)) {
- psParseBufReadTagRef(
- &sub, nonceExtension, 0x04);
- }
- psParseBufFinish(&sub);
- if (psParseBufFinish(&extension) != PS_SUCCESS)
- break;
- }
- psParseBufFinish(&extensions);
- }
- psParseBufFinish(&tbsRequest);
- return psParseBufFinish(&ocspRequest);
+ rc = psParseBufFromStaticData(&pb, data, datalen);
+ if (rc != PS_SUCCESS)
+ {
+ return rc;
+ }
+ psParseBufReadSequenceSub(&pb, &ocspRequest);
+ /* Ensure subbuffer is advanced and main buffer is not. */
+ psParseBufReadSequenceSub(&ocspRequest, &tbsRequest);
+ /* Ignore version number (v1 == 0) if present. */
+ psParseBufTrySkipBytes(&tbsRequest, (const unsigned char *)
+ "\xA0\x03\x02\x01\x00", 5);
+ /* Skip requestorName if present. */
+ psParseBufTrySkipTag(&tbsRequest, 0xA1);
+ /* Skip requestList (must be present with at least one request). */
+ psParseBufReadSequenceSub(&tbsRequest, &requestList);
+ psParseBufReadSequenceSub(&requestList, &request);
+ psParseBufReadSequenceSub(&request, &requestCert);
+ psParseBufReadSequenceSub(&requestCert, &requestCertContent);
+ psParseBufFinish(&requestCertContent);
+ psParseBufFinish(&requestCert);
+ psParseBufFinish(&request);
+ psParseBufFinish(&requestList);
+ if (psParseBufTryReadTagSub(&tbsRequest, &extensions, 0xA2))
+ {
+ while (psParseBufTryReadSequenceSub(&extensions, &extension))
+ {
+ psParseBuf_t sub;
+ psParseBufReadSequenceSub(&extension, &sub);
+ if (psParseBufTrySkipBytes(
+ &sub,
+ (const unsigned char *)
+ "\x06\x09\x2b\x06\x01\x05"
+ "\x05\x07\x30\x01\x02", 11))
+ {
+ psParseBufReadTagRef(
+ &sub, nonceExtension, 0x04);
+ }
+ psParseBufFinish(&sub);
+ if (psParseBufFinish(&extension) != PS_SUCCESS)
+ {
+ break;
+ }
+ }
+ psParseBufFinish(&extensions);
+ }
+ psParseBufFinish(&tbsRequest);
+ return psParseBufFinish(&ocspRequest);
}
-int32_t validateOCSPResponse_ex(psPool_t *pool, psX509Cert_t *trustedOCSP,
- psX509Cert_t *srvCerts, mOCSPResponse_t *response,
- psValidateOCSPResponseOptions_t *vOpts
- )
+static int32_t ocspMatchResponderCert(const psOcspResponse_t *response,
+ const psX509Cert_t *curr)
{
- static psValidateOCSPResponseOptions_t vOptsDefault;
- psX509Cert_t *curr, *issuer, *subject, *ocspResIssuer;
- mOCSPSingleResponse_t *subjectResponse;
- unsigned char sigOut[MAX_HASH_SIZE];
- int32 sigOutLen, sigType, index;
- psPool_t *pkiPool = NULL;
- bool knownFlag = false;
- bool revocationFlag = false;
- psBuf_t nonceExtReq = { NULL };
+ if (response->responderKeyHash != NULL)
+ {
+ /* Match certificate using key hash. */
+ if (memcmpct(response->responderKeyHash, curr->sha1KeyHash, 20) == 0)
+ {
+ return PS_SUCCESS;
+ }
+ }
+ else if (response->responderName != NULL)
+ {
+ uint32_t len;
+ /* Obtain the length of name tag including header.
+ Note: responderName has already been validated during parsing. */
+ const unsigned char *p = response->responderName + 1;
+ if (getAsnLength32(&p, 4, &len, 0) < 0)
+ return PS_FAILURE; /* Should not happen. */
- /* use default validation options if not specified. */
- if (vOpts == NULL) {
- vOpts = &vOptsDefault;
- }
+ len = (uint32_t) (p + len - response->responderName);
- /* Find interesting options from request. */
- if (vOpts->request) {
- int rc = parseOcspReq(vOpts->request, vOpts->requestLen,
- &nonceExtReq);
- if (rc != PS_SUCCESS)
- return PS_ARG_FAIL;
- }
+ /* Match certificate using subject name. */
+ if (curr->unparsedBin == NULL ||
+ curr->binLen < curr->subjectKeyDerOffsetIntoUnparsedBin + len)
+ {
+ return PS_FAILURE;
+ }
- /* Find the OCSP cert that signed the response. First place to look is
- within the OCSPResponse itself */
- issuer = NULL;
- if (response->OCSPResponseCert) {
- /* If there is a cert here it is something that has to be authenticated.
- We will either leave this case with a successful auth or failure */
- curr = response->OCSPResponseCert;
- while (curr != NULL) {
- /* The outer responderKeyHash should be matching one of the certs
- that was attached to the OCSPResonse itself */
- if (memcmp(response->responderKeyHash, curr->sha1KeyHash, 20) == 0){
- /* Found it... but now we have to authenticate it against
- our known list of CAs. issuer in the context of this
- function is the OCSPResponse issuer but here we are looking
- for the CA of THAT cert so it's 'subject' in this area */
- subject = curr;
- ocspResIssuer = trustedOCSP; /* preloaded sslKeys->CA */
- while (ocspResIssuer) {
- if (memcmp(ocspResIssuer->subject.hash,
- subject->issuer.hash, 20) == 0) {
-
- if (psX509AuthenticateCert(pool, subject, ocspResIssuer,
- &ocspResIssuer, NULL, NULL) == 0) {
- /* OK, we held the CA that issued the OCSPResponse
- so we'll now trust that cert that was provided
- in the OCSPResponse */
- ocspResIssuer = NULL;
- issuer = subject;
- } else {
- /* Auth failure */
- psTraceCrypto("Attached OCSP cert didn't auth\n");
- return PS_FAILURE;
- }
- } else {
- ocspResIssuer = ocspResIssuer->next;
- }
- }
- curr = NULL;
- } else {
- curr = curr->next;
- }
- }
- if (issuer == NULL) {
- psTraceCrypto("Found no CA to authenticate attached OCSP cert\n");
- return PS_FAILURE; /* no preloaded CA to auth cert in response */
- }
- }
-
- /* Issuer will be NULL if there was no certificate attached to the
- OCSP response. Now look to the user loaded CA files */
- if (issuer == NULL) {
- curr = trustedOCSP;
- while (curr != NULL) {
- /* Currently looking for the subjectKey extension to match the
- public key hash from the response */
- if (memcmp(response->responderKeyHash, curr->sha1KeyHash, 20) == 0){
- issuer = curr;
- curr = NULL;
- } else {
- curr = curr->next;
- }
- }
- }
-
- /* It is possible a certificate embedded in the server certificate
- chain was itself the OCSP responder */
- if (issuer == NULL) {
- /* Don't look at the first cert in the chain because that is the
- one we are trying to find the OCSP responder public key for */
- curr = srvCerts->next;
- while (curr != NULL) {
- /* Currently looking for the subjectKey extension to match the
- public key hash from the response */
- if (memcmp(response->responderKeyHash, curr->sha1KeyHash, 20) == 0){
- issuer = curr;
- curr = NULL;
- } else {
- curr = curr->next;
- }
- }
- }
-
- if (issuer == NULL) {
- psTraceCrypto("Unable to locate OCSP responder CA for validation\n");
- return PS_FAILURE;
- }
-
- /* Now check to see that the response is vouching for the subject cert
- that we are interested in. The subject will always be the first
- cert in the server CERTIFICATE chain */
- subject = srvCerts;
-
- /* Now look to match this cert within the singleResponse members.
-
- There are three components to a CertID that should be used to validate
- we are looking at the correct OCSP response for the subjecct cert.
-
- It appears the only "unique" portion of our subject cert that
- went into the signature of this response is the serial number.
- The "issuer" information of the subject cert also went into the
- signature but that isn't exactly unique. Seems a bit odd that the
- combo of the issuer and the serial number are the only thing that tie
- this subject cert back to the response but serial numbers are the basis
- for CRL as well so it must be good enough */
- index = 0;
- while (index < MAX_OCSP_RESPONSES) {
- subjectResponse = &response->singleResponse[index];
- if ((subject->serialNumberLen == subjectResponse->certIdSerialLen) &&
- (memcmp(subject->serialNumber, subjectResponse->certIdSerial,
- subject->serialNumberLen) == 0)) {
- break; /* got it */
- }
- index++;
- }
- if (index == MAX_OCSP_RESPONSES) {
- psTraceCrypto("Unable to locate our subject cert in OCSP response\n");
- return PS_FAILURE;
- }
- if (vOpts->index_p != NULL) {
- *(vOpts->index_p) = index; /* Write index of response. */
- }
-
- /* Obtain general revocation status. */
- if (subjectResponse->certStatus == 0) {
- knownFlag = true;
- revocationFlag = false;
- } else if (subjectResponse->certStatus == 1) {
- knownFlag = true;
- revocationFlag = true;
- /* certificate is revoked, but still check rest of the response. */
- }
-
- /* Is the response within the acceptable time window */
- if (checkOCSPtimestamp(response, index) != PS_SUCCESS) {
- psTraceCrypto("ERROR: OCSP response older than threshold\n");
- return PS_FAILURE;
- }
-
- /* Check if nonces match. */
- if (nonceExtReq.buf && vOpts->nonceMatch) {
- if (response->nonce.buf == NULL)
- /* No nonce in response. */
- *(vOpts->nonceMatch) = false;
- else
- /* Compare nonces. */
- *(vOpts->nonceMatch) = psBufEq(&nonceExtReq, &response->nonce);
- }
-
-#if 0 /* The issuer here is pointing to the cert that signed the OCSPRespose
- and that is not necessarily the parent of the subject cert we
- are looking at. If we want to include this test, we'd need to
- find the issuer of the subject and look at the KeyHash as
- an additional verification */
-
- /* Issuer portion of the validation - the subject cert issuer key and name
- hash should match what the subjectResponse reports
-
- POSSIBLE PROBLEMS: Only supporting a SHA1 hash here. The MatrixSSL
- parser will only use SHA1 for the DN and key hash. Just warning on
- this for now. The signature validation will catch any key mismatch */
- if (subjectResponse->certIdHashAlg != OID_SHA1_ALG) {
- psTraceCrypto("WARNING: Non-SHA1 OCSP CertID. Issuer check bypassed\n");
- } else {
- if (memcmp(subjectResponse->certIdKeyHash, issuer->sha1KeyHash, 20)
- != 0) {
- psTraceCrypto("Failed OCP issuer key hash validation\n");
- return PS_FAILURE;
- }
- /* Either subject->issuer or issuer->subject would work for testing */
- if (memcmp(subjectResponse->certIdNameHash, issuer->subject.hash, 20)
- != 0){
- psTraceCrypto("Failed OCP issuer name hash validation\n");
- return PS_FAILURE;
- }
- }
-#endif /* 0 */
-
- /* Finally do the sig validation */
- switch (response->sigAlg) {
-#ifdef USE_SHA256
- case OID_SHA256_RSA_SIG:
- sigOutLen = SHA256_HASH_SIZE;
- sigType = PS_RSA;
- break;
- case OID_SHA256_ECDSA_SIG:
- sigOutLen = SHA256_HASH_SIZE;
- sigType = PS_ECC;
- break;
-#endif
-#ifdef USE_SHA384
- case OID_SHA384_RSA_SIG:
- sigOutLen = SHA384_HASH_SIZE;
- sigType = PS_RSA;
- break;
- case OID_SHA384_ECDSA_SIG:
- sigOutLen = SHA384_HASH_SIZE;
- sigType = PS_ECC;
- break;
-#endif
- case OID_SHA1_RSA_SIG:
- sigOutLen = SHA1_HASH_SIZE;
- sigType = PS_RSA;
- break;
- case OID_SHA1_ECDSA_SIG:
- sigOutLen = SHA1_HASH_SIZE;
- sigType = PS_ECC;
- break;
- default:
- /* Should have been caught in parse phase */
- return PS_UNSUPPORTED_FAIL;
- }
-
- /* Finally test the signature */
- if (sigType == PS_RSA) {
- if (issuer->publicKey.type != PS_RSA) {
- return PS_FAILURE;
- }
- if (pubRsaDecryptSignedElement(pkiPool, &issuer->publicKey.key.rsa,
- (unsigned char*)response->sig, response->sigLen, sigOut,
- sigOutLen, NULL) < 0) {
- psTraceCrypto("Unable to decode signature in validateOCSPResponse\n");
- return PS_FAILURE;
- }
- if (memcmp(response->hashResult, sigOut, sigOutLen) != 0) {
- psTraceCrypto("OCSP RSA signature validation failed\n");
- return PS_FAILURE;
- }
- }
-#ifdef USE_ECC
- else {
- if (issuer->publicKey.type != PS_ECC) {
- return PS_FAILURE;
- }
- /* ECDSA signature */
- index = 0;
- if (psEccDsaVerify(pkiPool, &issuer->publicKey.key.ecc,
- response->hashResult, sigOutLen, (unsigned char*)response->sig,
- response->sigLen, &index, NULL) < 0) {
- psTraceCrypto("ECC OCSP sig validation");
- return PS_FAILURE;
- }
- if (index != 1) {
- psTraceCrypto("OCSP ECDSA signature validation failed\n");
- return PS_FAILURE;
- }
- }
-#endif
-
- if (vOpts->knownFlag)
- *(vOpts->knownFlag) = knownFlag;
-
- if (knownFlag == false) {
- /* The certificate is not known. */
- return PS_FAILURE;
- } else {
- if (vOpts->revocationFlag)
- *(vOpts->revocationFlag) = revocationFlag;
-
- if (vOpts->revocationTime) {
- (void)psBrokenDownTimeImport(
- vOpts->revocationTime,
- (const char *) subjectResponse->revocationTime,
- sizeof(subjectResponse->revocationTime), 0);
- }
-
- if (vOpts->revocationReason)
- *(vOpts->revocationReason) =
- subjectResponse->revocationReason;
-
- /* Function fails if certificate was revoked. */
- if (revocationFlag)
- return PS_CERT_AUTH_FAIL_REVOKED;
- }
-
- /* Was able to successfully confirm OCSP signature for our subject */
- return PS_SUCCESS;
+ if (memcmpct(curr->unparsedBin +
+ curr->subjectKeyDerOffsetIntoUnparsedBin,
+ response->responderName, len) == 0)
+ {
+ return PS_SUCCESS;
+ }
+ }
+ return PS_FAILURE;
}
-int32_t validateOCSPResponse(psPool_t *pool, psX509Cert_t *trustedOCSP,
- psX509Cert_t *srvCerts,
- mOCSPResponse_t *response) {
- return validateOCSPResponse_ex(pool, trustedOCSP, srvCerts, response, NULL);
+int32_t psOcspResponseValidate(psPool_t *pool, psX509Cert_t *trustedOCSP,
+ psX509Cert_t *srvCerts, psOcspResponse_t *response,
+ psValidateOCSPResponseOptions_t *vOpts
+ )
+{
+ static psValidateOCSPResponseOptions_t vOptsDefault;
+ psX509Cert_t *curr, *issuer, *subject, *ocspResIssuer;
+ psOcspSingleResponse_t *subjectResponse;
+ unsigned char sigOut[MAX_HASH_SIZE];
+ int32 sigOutLen, sigType, index;
+ psPool_t *pkiPool = NULL;
+
+ psBool_t knownFlag = PS_FALSE;
+ psBool_t revocationFlag = PS_FALSE;
+ psBuf_t nonceExtReq = { NULL };
+
+ /* use default validation options if not specified. */
+ if (vOpts == NULL)
+ {
+ vOpts = &vOptsDefault;
+ }
+
+ /* Find interesting options from request. */
+ if (vOpts->request)
+ {
+ int rc = parseOcspReq(vOpts->request, vOpts->requestLen,
+ &nonceExtReq);
+ if (rc != PS_SUCCESS)
+ {
+ return PS_ARG_FAIL;
+ }
+ }
+
+ /* Find the OCSP cert that signed the response. First place to look is
+ within the OCSPResponse itself */
+ issuer = NULL;
+ if (response->OCSPResponseCert)
+ {
+ /* If there is a cert here it is something that has to be authenticated.
+ We will either leave this case with a successful auth or failure */
+ curr = response->OCSPResponseCert;
+ while (curr != NULL)
+ {
+ /* The outer responderKeyHash should be matching one of the certs
+ that was attached to the OCSPResonse itself */
+ if (ocspMatchResponderCert(response, curr) == PS_SUCCESS)
+ {
+ /* Found it... but now we have to authenticate it against
+ our known list of CAs. issuer in the context of this
+ function is the OCSPResponse issuer but here we are looking
+ for the CA of THAT cert so it's 'subject' in this area */
+ subject = curr;
+ ocspResIssuer = trustedOCSP; /* preloaded sslKeys->CA */
+ while (ocspResIssuer)
+ {
+ if (memcmp(ocspResIssuer->subject.hash,
+ subject->issuer.hash, 20) == 0)
+ {
+
+ if (psX509AuthenticateCert(pool, subject, ocspResIssuer,
+ &ocspResIssuer, NULL, NULL) == 0)
+ {
+ /* OK, we held the CA that issued the OCSPResponse
+ so we'll now trust that cert that was provided
+ in the OCSPResponse */
+ ocspResIssuer = NULL;
+ issuer = subject;
+ }
+ else
+ {
+ /* Auth failure */
+ psTraceCrypto("Attached OCSP cert didn't auth\n");
+ return PS_FAILURE;
+ }
+ }
+ else
+ {
+ ocspResIssuer = ocspResIssuer->next;
+ }
+ }
+ curr = NULL;
+ }
+ else
+ {
+ curr = curr->next;
+ }
+ }
+ if (issuer == NULL)
+ {
+ psTraceCrypto("Found no CA to authenticate attached OCSP cert\n");
+ return PS_FAILURE; /* no preloaded CA to auth cert in response */
+ }
+ }
+
+ /* Issuer will be NULL if there was no certificate attached to the
+ OCSP response. Now look to the user loaded CA files */
+ if (issuer == NULL)
+ {
+ curr = trustedOCSP;
+ while (curr != NULL)
+ {
+ /* Currently looking for the subjectKey extension to match the
+ public key hash from the response */
+ if (ocspMatchResponderCert(response, curr) == PS_SUCCESS)
+ {
+ issuer = curr;
+ curr = NULL;
+ }
+ else
+ {
+ curr = curr->next;
+ }
+ }
+ }
+
+ /* It is possible a certificate embedded in the server certificate
+ chain was itself the OCSP responder */
+ if (issuer == NULL)
+ {
+ /* Don't look at the first cert in the chain because that is the
+ one we are trying to find the OCSP responder public key for */
+ curr = srvCerts->next;
+ while (curr != NULL)
+ {
+ /* Currently looking for the subjectKey extension to match the
+ public key hash from the response */
+ if (ocspMatchResponderCert(response, curr) == PS_SUCCESS)
+ {
+ issuer = curr;
+ curr = NULL;
+ }
+ else
+ {
+ curr = curr->next;
+ }
+ }
+ }
+
+ if (issuer == NULL)
+ {
+ psTraceCrypto("Unable to locate OCSP responder CA for validation\n");
+ return PS_FAILURE;
+ }
+
+ /* Now check to see that the response is vouching for the subject cert
+ that we are interested in. The subject will always be the first
+ cert in the server CERTIFICATE chain */
+ subject = srvCerts;
+
+ /* Now look to match this cert within the singleResponse members.
+
+ There are three components to a CertID that should be used to validate
+ we are looking at the correct OCSP response for the subjecct cert.
+
+ It appears the only "unique" portion of our subject cert that
+ went into the signature of this response is the serial number.
+ The "issuer" information of the subject cert also went into the
+ signature but that isn't exactly unique. Seems a bit odd that the
+ combo of the issuer and the serial number are the only thing that tie
+ this subject cert back to the response but serial numbers are the basis
+ for CRL as well so it must be good enough */
+ index = 0;
+ while (index < MAX_OCSP_RESPONSES)
+ {
+ subjectResponse = &response->singleResponse[index];
+ if ((subject->serialNumberLen == subjectResponse->certIdSerialLen) &&
+ (memcmp(subject->serialNumber, subjectResponse->certIdSerial,
+ subject->serialNumberLen) == 0))
+ {
+ break; /* got it */
+ }
+ index++;
+ }
+ if (index == MAX_OCSP_RESPONSES)
+ {
+ psTraceCrypto("Unable to locate our subject cert in OCSP response\n");
+ return PS_FAILURE;
+ }
+ if (vOpts->index_p != NULL)
+ {
+ *(vOpts->index_p) = index; /* Write index of response. */
+ }
+
+ /* Obtain general revocation status. */
+ if (subjectResponse->certStatus == 0)
+ {
+ knownFlag = PS_TRUE;
+ revocationFlag = PS_FALSE;
+ }
+ else if (subjectResponse->certStatus == 1)
+ {
+ knownFlag = PS_TRUE;
+ revocationFlag = PS_TRUE;
+ /* certificate is revoked, but still check rest of the response. */
+ }
+
+ /* Is the response within the acceptable time window */
+ if (checkOCSPtimestamp(response, index) != PS_SUCCESS)
+ {
+ psTraceCrypto("ERROR: OCSP response older than threshold\n");
+ return PS_FAILURE;
+ }
+
+ /* Check if nonces match. */
+ if (nonceExtReq.buf && vOpts->nonceMatch)
+ {
+ if (response->nonce.buf == NULL)
+ {
+ /* No nonce in response. */
+ *(vOpts->nonceMatch) = PS_FALSE;
+ }
+ else
+ {
+ /* Compare nonces. */
+ *(vOpts->nonceMatch) = psBufEq(&nonceExtReq, &response->nonce);
+ }
+ }
+
+# if 0
+ /* The issuer here is pointing to the cert that signed the OCSPRespose
+ and that is not necessarily the parent of the subject cert we
+ are looking at. If we want to include this test, we'd need to
+ find the issuer of the subject and look at the KeyHash as
+ an additional verification */
+
+ /* Issuer portion of the validation - the subject cert issuer key and name
+ hash should match what the subjectResponse reports
+
+ POSSIBLE PROBLEMS: Only supporting a SHA1 hash here. The MatrixSSL
+ parser will only use SHA1 for the DN and key hash. Just warning on
+ this for now. The signature validation will catch any key mismatch */
+ if (subjectResponse->certIdHashAlg != OID_SHA1_ALG)
+ {
+ psTraceCrypto("WARNING: Non-SHA1 OCSP CertID. Issuer check bypassed\n");
+ }
+ else
+ {
+ if (memcmp(subjectResponse->certIdKeyHash, issuer->sha1KeyHash, 20)
+ != 0)
+ {
+ psTraceCrypto("Failed OCP issuer key hash validation\n");
+ return PS_FAILURE;
+ }
+ /* Either subject->issuer or issuer->subject would work for testing */
+ if (memcmp(subjectResponse->certIdNameHash, issuer->subject.hash, 20)
+ != 0)
+ {
+ psTraceCrypto("Failed OCP issuer name hash validation\n");
+ return PS_FAILURE;
+ }
+ }
+# endif /* 0 */
+
+ /* Finally do the sig validation */
+ switch (response->sigAlg)
+ {
+# ifdef USE_SHA256
+ case OID_SHA256_RSA_SIG:
+ sigOutLen = SHA256_HASH_SIZE;
+ sigType = PS_RSA;
+ break;
+ case OID_SHA256_ECDSA_SIG:
+ sigOutLen = SHA256_HASH_SIZE;
+ sigType = PS_ECC;
+ break;
+# endif
+# ifdef USE_SHA384
+ case OID_SHA384_RSA_SIG:
+ sigOutLen = SHA384_HASH_SIZE;
+ sigType = PS_RSA;
+ break;
+ case OID_SHA384_ECDSA_SIG:
+ sigOutLen = SHA384_HASH_SIZE;
+ sigType = PS_ECC;
+ break;
+# endif
+ case OID_SHA1_RSA_SIG:
+ case OID_SHA1_RSA_SIG2:
+ sigOutLen = SHA1_HASH_SIZE;
+ sigType = PS_RSA;
+ break;
+ case OID_SHA1_ECDSA_SIG:
+ sigOutLen = SHA1_HASH_SIZE;
+ sigType = PS_ECC;
+ break;
+ default:
+ /* Should have been caught in parse phase */
+ return PS_UNSUPPORTED_FAIL;
+ }
+
+ /* Finally test the signature */
+ if (sigType == PS_RSA)
+ {
+ if (issuer->publicKey.type != PS_RSA)
+ {
+ return PS_FAILURE;
+ }
+ if (pubRsaDecryptSignedElement(pkiPool, &issuer->publicKey.key.rsa,
+ (unsigned char *) response->sig, response->sigLen, sigOut,
+ sigOutLen, NULL) < 0)
+ {
+ psTraceCrypto("Unable to decode signature in psOcspResponseValidateOld\n");
+ return PS_FAILURE;
+ }
+ if (memcmp(response->hashResult, sigOut, sigOutLen) != 0)
+ {
+ psTraceCrypto("OCSP RSA signature validation failed\n");
+ return PS_FAILURE;
+ }
+ }
+# ifdef USE_ECC
+ else
+ {
+ if (issuer->publicKey.type != PS_ECC)
+ {
+ return PS_FAILURE;
+ }
+ /* ECDSA signature */
+ index = 0;
+ if (psEccDsaVerify(pkiPool, &issuer->publicKey.key.ecc,
+ response->hashResult, sigOutLen, (unsigned char *) response->sig,
+ response->sigLen, &index, NULL) < 0)
+ {
+ psTraceCrypto("ECC OCSP sig validation");
+ return PS_FAILURE;
+ }
+ if (index != 1)
+ {
+ psTraceCrypto("OCSP ECDSA signature validation failed\n");
+ return PS_FAILURE;
+ }
+ }
+# endif
+
+ if (vOpts->knownFlag)
+ {
+ *(vOpts->knownFlag) = knownFlag;
+ }
+
+ if (knownFlag == PS_FALSE)
+ {
+ /* The certificate is not known. */
+ return PS_FAILURE;
+ }
+ else
+ {
+ if (vOpts->revocationFlag)
+ {
+ *(vOpts->revocationFlag) = revocationFlag;
+ }
+
+ if (vOpts->revocationTime)
+ {
+ (void) psBrokenDownTimeImport(
+ vOpts->revocationTime,
+ (const char *) subjectResponse->revocationTime,
+ sizeof(subjectResponse->revocationTime), 0);
+ }
+
+ if (vOpts->revocationReason)
+ {
+ *(vOpts->revocationReason) =
+ subjectResponse->revocationReason;
+ }
+
+ /* Function fails if certificate was revoked. */
+ if (revocationFlag)
+ {
+ return PS_CERT_AUTH_FAIL_REVOKED;
+ }
+ }
+
+ /* Was able to successfully confirm OCSP signature for our subject */
+ return PS_SUCCESS;
}
-void uninitOCSPResponse(mOCSPResponse_t *res) {
- psX509FreeCert(res->OCSPResponseCert);
- memset(res, 0, sizeof(*res));
+int32_t psOcspResponseValidateOld(psPool_t *pool, psX509Cert_t *trustedOCSP,
+ psX509Cert_t *srvCerts,
+ psOcspResponse_t *response)
+{
+ return psOcspResponseValidate(pool, trustedOCSP, srvCerts, response, NULL);
+}
+
+void psOcspResponseUninit(psOcspResponse_t *res)
+{
+ psX509FreeCert(res->OCSPResponseCert);
+ memset(res, 0, sizeof(*res));
}
-#endif /* USE_OCSP */
+# endif /* USE_OCSP */
-#endif /* USE_X509 */
+#endif /* USE_X509 */
/******************************************************************************/
-
diff --git a/crypto/keyformat/x509.h b/crypto/keyformat/x509.h
index 61d2478..cda303d 100644
--- a/crypto/keyformat/x509.h
+++ b/crypto/keyformat/x509.h
@@ -1,53 +1,54 @@
/**
- * @file x509.h
- * @version $Format:%h%d$
+ * @file x509.h
+ * @version $Format:%h%d$
*
- * X.509 header.
+ * X.509 header.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_X509
-#define _h_PS_X509
+# define _h_PS_X509
-#ifdef USE_X509
+# ifdef USE_X509
/******************************************************************************/
/* ClientCertificateType */
-enum {
- RSA_SIGN = 1,
- DSS_SIGN,
- RSA_FIXED_DH,
- DSS_FIXED_DH,
- ECDSA_SIGN = 64,
- RSA_FIXED_ECDH,
- ECDSA_FIXED_ECDH
+enum
+{
+ RSA_SIGN = 1,
+ DSS_SIGN,
+ RSA_FIXED_DH,
+ DSS_FIXED_DH,
+ ECDSA_SIGN = 64,
+ RSA_FIXED_ECDH,
+ ECDSA_FIXED_ECDH
};
/* The default value of allowed mismatch in times in X.509 messages and the
@@ -55,289 +56,310 @@ enum {
MatrixSSL behavior of ignoring hours, minutes and seconds in X.509 date
comparison. Note: There is different value for CRL (PS_CRL_TIME_LINGER) and OCSP
(PS_OCSP_TIME_LINGER). */
-#define PS_X509_TIME_LINGER (24 * 60 * 60)
+# define PS_X509_TIME_LINGER (24 * 60 * 60)
/* This is approximately equivalent to old MatrixSSL behavior of
only comparing date. */
-#define PS_CRL_TIME_LINGER (24 * 60 * 60)
+# define PS_CRL_TIME_LINGER (24 * 60 * 60)
/* Parsing flags */
-#define CERT_STORE_UNPARSED_BUFFER 0x1
-#define CERT_STORE_DN_BUFFER 0x2
+# define CERT_STORE_UNPARSED_BUFFER 0x1
+# define CERT_STORE_DN_BUFFER 0x2
-#ifdef USE_CERT_PARSE
+# ifdef USE_CERT_PARSE
/* Per specification, any critical extension in an X.509 cert should cause
- the connection to fail. SECURITY - Uncomment at your own risk */
+ the connection to fail. SECURITY - Uncomment at your own risk */
/* #define ALLOW_UNKNOWN_CRITICAL_EXTENSIONS */
/* Support for multiple organizational units */
-typedef struct x509OrgUnit {
- struct x509OrgUnit *next;
- char *name;
- short type;
- uint16_t len;
+typedef struct x509OrgUnit
+{
+ struct x509OrgUnit *next;
+ char *name;
+ short type;
+ psSize_t len;
} x509OrgUnit_t;
/* Support for multiple domainComponents */
-typedef struct x509DomainComponent {
- struct x509DomainComponent *next;
- char *name;
- short type;
- uint16_t len;
+typedef struct x509DomainComponent
+{
+ struct x509DomainComponent *next;
+ char *name;
+ short type;
+ psSize_t len;
} x509DomainComponent_t;
/* Number of null-bytes to terminate parsed string-type DN attributes with. */
-#define DN_NUM_TERMINATING_NULLS 2
+# define DN_NUM_TERMINATING_NULLS 2
/*
- DN attributes are used outside the X509 area for cert requests,
- which have been included in the RSA portions of the code
-*/
-typedef struct {
- /* MUST support according to RFC 5280: */
- char *country;
- char *organization;
- x509OrgUnit_t *orgUnit;
- char *dnQualifier;
- char *serialNumber;
- char *state;
- char *commonName;
- x509DomainComponent_t *domainComponent;
-#ifdef USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
- char *locality;
- char *title;
- char *surname;
- char *givenName;
- char *initials;
- char *pseudonym;
- char *generationQualifier;
-#endif /* USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
-#ifdef USE_EXTRA_DN_ATTRIBUTES
- char *streetAddress;
- char *postalAddress;
- char *telephoneNumber;
- char *uid;
- char *name;
- char *email;
-#endif /* USE_EXTRA_DN_ATTRIBUTES */
- char hash[MAX_HASH_SIZE];
- char *dnenc; /* CERT_STORE_DN_BUFFER */
- uint16_t dnencLen;
- /* MUST support according to RFC 5280: */
- short countryType;
- uint16_t countryLen;
- short stateType;
- uint16_t stateLen;
- short organizationType;
- uint16_t organizationLen;
- short dnQualifierType;
- uint16_t dnQualifierLen;
- short commonNameType;
- uint16_t commonNameLen;
- short serialNumberType;
- uint16_t serialNumberLen;
- short domainComponentType;
- uint16_t domainComponentLen;
-#ifdef USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
- short localityType;
- uint16_t localityLen;
- short titleType;
- uint16_t titleLen;
- short surnameType;
- uint16_t surnameLen;
- short givenNameType;
- uint16_t givenNameLen;
- short initialsType;
- uint16_t initialsLen;
- short pseudonymType;
- uint16_t pseudonymLen;
- short generationQualifierType;
- uint16_t generationQualifierLen;
-#endif /* USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
-#ifdef USE_EXTRA_DN_ATTRIBUTES
- short streetAddressType;
- uint16_t streetAddressLen;
- short postalAddressType;
- uint16_t postalAddressLen;
- short telephoneNumberType;
- uint16_t telephoneNumberLen;
- short uidType;
- uint16_t uidLen;
- short nameType;
- uint16_t nameLen;
- short emailType;
- uint16_t emailLen;
-#endif /* USE_EXTRA_DN_ATTRIBUTES */
+ DN attributes are used outside the X509 area for cert requests,
+ which have been included in the RSA portions of the code
+ */
+typedef struct
+{
+ /* MUST support according to RFC 5280: */
+ char *country;
+ char *organization;
+ x509OrgUnit_t *orgUnit;
+ char *dnQualifier;
+ char *serialNumber;
+ char *state;
+ char *commonName;
+ x509DomainComponent_t *domainComponent;
+# ifdef USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
+ char *locality;
+ char *title;
+ char *surname;
+ char *givenName;
+ char *initials;
+ char *pseudonym;
+ char *generationQualifier;
+# endif /* USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
+# ifdef USE_EXTRA_DN_ATTRIBUTES
+ char *streetAddress;
+ char *postalAddress;
+ char *telephoneNumber;
+ char *uid;
+ char *name;
+ char *email;
+# endif /* USE_EXTRA_DN_ATTRIBUTES */
+ char hash[MAX_HASH_SIZE];
+ char *dnenc; /* CERT_STORE_DN_BUFFER */
+ psSize_t dnencLen;
+ /* MUST support according to RFC 5280: */
+ short countryType;
+ psSize_t countryLen;
+ short stateType;
+ psSize_t stateLen;
+ short organizationType;
+ psSize_t organizationLen;
+ short dnQualifierType;
+ psSize_t dnQualifierLen;
+ short commonNameType;
+ psSize_t commonNameLen;
+ short serialNumberType;
+ psSize_t serialNumberLen;
+ short domainComponentType;
+ psSize_t domainComponentLen;
+# ifdef USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD
+ short localityType;
+ psSize_t localityLen;
+ short titleType;
+ psSize_t titleLen;
+ short surnameType;
+ psSize_t surnameLen;
+ short givenNameType;
+ psSize_t givenNameLen;
+ short initialsType;
+ psSize_t initialsLen;
+ short pseudonymType;
+ psSize_t pseudonymLen;
+ short generationQualifierType;
+ psSize_t generationQualifierLen;
+# endif /* USE_EXTRA_DN_ATTRIBUTES_RFC5280_SHOULD */
+# ifdef USE_EXTRA_DN_ATTRIBUTES
+ short streetAddressType;
+ psSize_t streetAddressLen;
+ short postalAddressType;
+ psSize_t postalAddressLen;
+ short telephoneNumberType;
+ psSize_t telephoneNumberLen;
+ short uidType;
+ psSize_t uidLen;
+ short nameType;
+ psSize_t nameLen;
+ short emailType;
+ psSize_t emailLen;
+# endif /* USE_EXTRA_DN_ATTRIBUTES */
} x509DNattributes_t;
-typedef enum {
- CA_FALSE = 0,
- CA_UNDEFINED = 127,
- CA_TRUE = 255
+typedef enum
+{
+ CA_FALSE = 0,
+ CA_UNDEFINED = 127,
+ CA_TRUE = 255
} x509bcCAValue_t;
-typedef struct {
- x509bcCAValue_t cA;
- int32 pathLenConstraint;
+typedef struct
+{
+ x509bcCAValue_t cA;
+ int32 pathLenConstraint;
} x509extBasicConstraints_t;
- typedef enum {
- GN_OTHER = 0, // OtherName
- GN_EMAIL, // IA5String
- GN_DNS, // IA5String
- GN_X400, // ORAddress
- GN_DIR, // Name
- GN_EDI, // EDIPartyName
- GN_URI, // IA5String
- GN_IP, // OCTET STRING
- GN_REGID // OBJECT IDENTIFIER
- } x509GeneralNameType_t;
+typedef enum
+{
+ GN_OTHER = 0, /* OtherName */
+ GN_EMAIL, /* IA5String */
+ GN_DNS, /* IA5String */
+ GN_X400, /* ORAddress */
+ GN_DIR, /* Name */
+ GN_EDI, /* EDIPartyName */
+ GN_URI, /* IA5String */
+ GN_IP, /* OCTET STRING */
+ GN_REGID /* OBJECT IDENTIFIER */
+} x509GeneralNameType_t;
-typedef struct psGeneralNameEntry {
- psPool_t *pool;
- x509GeneralNameType_t id;
- unsigned char name[16];
- unsigned char oid[32]; /* SubjectAltName OtherName */
- unsigned char *data;
- uint16_t oidLen;
- uint16_t dataLen;
- struct psGeneralNameEntry *next;
+typedef struct psGeneralNameEntry
+{
+ psPool_t *pool;
+ x509GeneralNameType_t id;
+ unsigned char name[16];
+ unsigned char oid[32]; /* SubjectAltName OtherName */
+ unsigned char *data;
+ psSize_t oidLen;
+ psSize_t dataLen;
+ struct psGeneralNameEntry *next;
} x509GeneralName_t;
-#define MAX_OID_LEN 16 /**< Maximum number of segments in OID */
+# define MAX_POLICY_ATTRIB_LEN 512
+# define MAX_NUM_QUAL_INFOS 10
+# define MAX_POLICIES 10
+# define MAX_UNOTICE_NUMBERS 5
-#define MAX_POLICY_ATTRIB_LEN 512
-#define MAX_NUM_QUAL_INFOS 10
-#define MAX_POLICIES 10
-#define MAX_UNOTICE_NUMBERS 5
-
-typedef struct {
- unsigned char *id;
- uint16_t len;
+typedef struct
+{
+ unsigned char *id;
+ psSize_t len;
} x509extSubjectKeyId_t;
-typedef struct {
- unsigned char *keyId;
- unsigned char *serialNum;
- x509DNattributes_t attribs;
- uint16_t keyLen;
- uint16_t serialNumLen;
+typedef struct
+{
+ unsigned char *keyId;
+ unsigned char *serialNum;
+ x509DNattributes_t attribs;
+ psSize_t keyLen;
+ psSize_t serialNumLen;
} x509extAuthKeyId_t;
-#if defined(USE_FULL_CERT_PARSE) || defined(USE_CERT_GEN)
-typedef struct {
- x509GeneralName_t *permitted;
- x509GeneralName_t *excluded;
+# if defined(USE_FULL_CERT_PARSE) || defined(USE_CERT_GEN)
+typedef struct
+{
+ x509GeneralName_t *permitted;
+ x509GeneralName_t *excluded;
} x509nameConstraints_t;
-typedef struct x509PolicyQualifierInfo_t {
- char *cps;
- char *unoticeOrganization;
- char *unoticeExplicitText;
- int32_t unoticeNumbers[MAX_UNOTICE_NUMBERS];
- uint16_t cpsLen;
- uint16_t unoticeOrganizationLen;
- uint16_t unoticeExplicitTextLen;
- uint16_t unoticeNumbersLen;
- int unoticeExplicitTextEncoding;
- int unoticeOrganizationEncoding;
- struct x509PolicyQualifierInfo_t *next;
+typedef struct x509PolicyQualifierInfo_t
+{
+ char *cps;
+ char *unoticeOrganization;
+ char *unoticeExplicitText;
+ int32_t unoticeNumbers[MAX_UNOTICE_NUMBERS];
+ psSize_t cpsLen;
+ psSize_t unoticeOrganizationLen;
+ psSize_t unoticeExplicitTextLen;
+ psSize_t unoticeNumbersLen;
+ int unoticeExplicitTextEncoding;
+ int unoticeOrganizationEncoding;
+ struct x509PolicyQualifierInfo_t *next;
} x509PolicyQualifierInfo_t;
-typedef struct x509PolicyInformation_t {
+typedef struct x509PolicyInformation_t
+{
uint32_t *policyOid;
- uint16_t policyOidLen;
- x509PolicyQualifierInfo_t *qualifiers;
- struct x509PolicyInformation_t *next;
+ psSize_t policyOidLen;
+ x509PolicyQualifierInfo_t *qualifiers;
+ struct x509PolicyInformation_t *next;
} x509PolicyInformation_t;
-typedef struct x509certificatePolicies_t {
- x509PolicyInformation_t *policy;
+typedef struct x509certificatePolicies_t
+{
+ x509PolicyInformation_t *policy;
} x509certificatePolicies_t;
-typedef struct x509policyConstraints_t {
- int32_t requireExplicitPolicy;
- int32_t inhibitPolicyMappings;
+typedef struct x509policyConstraints_t
+{
+ int32_t requireExplicitPolicy;
+ int32_t inhibitPolicyMappings;
} x509policyConstraints_t;
-typedef struct x509policyMappings_t {
- uint32_t *issuerDomainPolicy;
- uint32_t *subjectDomainPolicy;
- uint16_t issuerDomainPolicyLen;
- uint16_t subjectDomainPolicyLen;
- struct x509policyMappings_t *next;
+typedef struct x509policyMappings_t
+{
+ uint32_t *issuerDomainPolicy;
+ uint32_t *subjectDomainPolicy;
+ psSize_t issuerDomainPolicyLen;
+ psSize_t subjectDomainPolicyLen;
+ struct x509policyMappings_t *next;
} x509policyMappings_t;
-typedef struct x509authorityInfoAccess_t {
- char *ocsp;
- char *caIssuers;
- uint16_t ocspLen;
- uint16_t caIssuersLen;
- struct x509authorityInfoAccess_t *next;
+typedef struct x509authorityInfoAccess_t
+{
+ char *ocsp;
+ char *caIssuers;
+ psSize_t ocspLen;
+ psSize_t caIssuersLen;
+ struct x509authorityInfoAccess_t *next;
} x509authorityInfoAccess_t;
-#endif /* USE_FULL_CERT_PARSE || USE_CERT_GEN */
+typedef struct x509netscapeComment_t
+{
+ char *comment;
+ psSize_t commentLen;
+} x509netscapeComment_t;
+
+# endif /* USE_FULL_CERT_PARSE || USE_CERT_GEN */
/******************************************************************************/
/*
- OID parsing and lookup.
-*/
+ OID parsing and lookup.
+ */
/*
- X.509 Certificate Extension OIDs
- @see https://tools.ietf.org/html/rfc5280#section-4.2
+ X.509 Certificate Extension OIDs
+ @see https://tools.ietf.org/html/rfc5280#section-4.2
- id-ce OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 29 }
+ id-ce OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 29 }
- id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 }
- id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 }
- id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
- id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
- id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 }
- id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
- id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 }
- id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 }
- id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 }
- id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 }
- id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 }
- id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
- id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-ce 31 }
- id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 }
- id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 }
-*/
-#define id_ce 2,5,29
-enum {
- id_ce_authorityKeyIdentifier = 35,
- id_ce_subjectKeyIdentifier = 14,
- id_ce_keyUsage = 15,
- id_ce_certificatePolicies = 32,
- id_ce_policyMappings = 33,
- id_ce_subjectAltName = 17,
- id_ce_issuerAltName = 18,
- id_ce_subjectDirectoryAttributes = 9,
- id_ce_basicConstraints = 19,
- id_ce_cRLNumber = 20,
- id_ce_issuingDistributionPoint = 28,
- id_ce_nameConstraints = 30,
- id_ce_policyConstraints = 36,
- id_ce_extKeyUsage = 37,
- id_ce_cRLDistributionPoints = 31,
- id_ce_inhibitAnyPolicy = 54,
- id_ce_freshestCRL = 46,
+ id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 }
+ id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 }
+ id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
+ id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
+ id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 }
+ id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
+ id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 }
+ id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 }
+ id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 }
+ id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 }
+ id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 }
+ id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
+ id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= { id-ce 31 }
+ id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 }
+ id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 }
+ */
+# define id_ce 2, 5, 29
+enum
+{
+ id_ce_authorityKeyIdentifier = 35,
+ id_ce_subjectKeyIdentifier = 14,
+ id_ce_keyUsage = 15,
+ id_ce_certificatePolicies = 32,
+ id_ce_policyMappings = 33,
+ id_ce_subjectAltName = 17,
+ id_ce_issuerAltName = 18,
+ id_ce_subjectDirectoryAttributes = 9,
+ id_ce_basicConstraints = 19,
+ id_ce_cRLNumber = 20,
+ id_ce_issuingDistributionPoint = 28,
+ id_ce_nameConstraints = 30,
+ id_ce_policyConstraints = 36,
+ id_ce_extKeyUsage = 37,
+ id_ce_cRLDistributionPoints = 31,
+ id_ce_inhibitAnyPolicy = 54,
+ id_ce_freshestCRL = 46,
};
-/* id-pkix OBJECT IDENTIFIER ::= {
- iso(1) identified-organization(3) dod(6) internet(1)
- security(5) mechanisms(5) pkix(7) }
-*/
-#define id_pxix 1,3,6,1,5,5,7
+/* id-pkix OBJECT IDENTIFIER ::= {
+ iso(1) identified-organization(3) dod(6) internet(1)
+ security(5) mechanisms(5) pkix(7) }
+ */
+# define id_pxix 1, 3, 6, 1, 5, 5, 7
/* anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificate-policies 0 } */
-#define id_anyPolicy 2,5,29,32,0
+# define id_anyPolicy 2, 5, 29, 32, 0
/*
-The following key usage purposes are defined:
+ The following key usage purposes are defined:
anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }
@@ -371,42 +393,45 @@ The following key usage purposes are defined:
-- Signing OCSP responses
-- Key usage bits that may be consistent: digitalSignature
-- and/or nonRepudiation
-*/
-#define id_ce_eku id_ce,id_ce_extKeyUsage
-#define id_kp id_pxix,3
-enum {
- id_ce_eku_anyExtendedKeyUsage = 0,
- id_kp_serverAuth = 1,
- id_kp_clientAuth = 2,
- id_kp_codeSigning = 3,
- id_kp_emailProtection = 4,
- id_kp_timeStamping = 8,
- id_kp_OCSPSigning = 9,
+ */
+# define id_ce_eku id_ce, id_ce_extKeyUsage
+# define id_kp id_pxix, 3
+enum
+{
+ id_ce_eku_anyExtendedKeyUsage = 0,
+ id_kp_serverAuth = 1,
+ id_kp_clientAuth = 2,
+ id_kp_codeSigning = 3,
+ id_kp_emailProtection = 4,
+ id_kp_timeStamping = 8,
+ id_kp_OCSPSigning = 9,
};
/*
- id-ad id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
+ id-ad id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
- id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
+ id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
- id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
-*/
-#define id_ad id_pxix,48
-enum {
- id_ad_ocsp = 1,
- id_ad_caIssuers = 2
+ id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
+ */
+# define id_ad id_pxix, 48
+enum
+{
+ id_ad_ocsp = 1,
+ id_ad_caIssuers = 2
};
/*
- id-pe OBJECT IDENTIFIER ::= { id-pkix 1 }
+ id-pe OBJECT IDENTIFIER ::= { id-pkix 1 }
- id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
- id-pe-subjectInfoAccess OBJECT IDENTIFIER ::= { id-pe 11 }
-*/
-#define id_pe id_pxix,1
-enum {
- id_pe_authorityInfoAccess = 1,
- id_pe_subjectInfoAccess = 11,
+ id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
+ id-pe-subjectInfoAccess OBJECT IDENTIFIER ::= { id-pe 11 }
+ */
+# define id_pe id_pxix, 1
+enum
+{
+ id_pe_authorityInfoAccess = 1,
+ id_pe_subjectInfoAccess = 11,
};
/*
@@ -417,388 +442,573 @@ enum {
id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
-*/
-#define id_qt id_pxix,2
-enum {
- id_qt_cps = 1,
- id_qt_unotice = 2
+ */
+# define id_qt id_pxix, 2
+enum
+{
+ id_qt_cps = 1,
+ id_qt_unotice = 2
};
-#define OID_ENUM(A) oid_##A
-typedef enum {
- OID_ENUM(0) = 0,
- /* X.509 certificate extensions */
- OID_ENUM(id_ce_authorityKeyIdentifier),
- OID_ENUM(id_ce_subjectKeyIdentifier),
- OID_ENUM(id_ce_keyUsage),
- OID_ENUM(id_ce_certificatePolicies),
- OID_ENUM(id_ce_policyMappings),
- OID_ENUM(id_ce_subjectAltName),
- OID_ENUM(id_ce_issuerAltName),
- OID_ENUM(id_ce_subjectDirectoryAttributes),
- OID_ENUM(id_ce_basicConstraints),
- OID_ENUM(id_ce_nameConstraints),
- OID_ENUM(id_ce_policyConstraints),
- OID_ENUM(id_ce_extKeyUsage),
- OID_ENUM(id_ce_cRLDistributionPoints),
- OID_ENUM(id_ce_cRLNumber),
- OID_ENUM(id_ce_issuingDistributionPoint),
- OID_ENUM(id_ce_inhibitAnyPolicy),
- OID_ENUM(id_ce_freshestCRL),
- OID_ENUM(id_pe_authorityInfoAccess),
- OID_ENUM(id_pe_subjectInfoAccess),
- /* Extended Key Usage */
- OID_ENUM(id_ce_eku_anyExtendedKeyUsage),
- OID_ENUM(id_kp_serverAuth),
- OID_ENUM(id_kp_clientAuth),
- OID_ENUM(id_kp_codeSigning),
- OID_ENUM(id_kp_emailProtection),
- OID_ENUM(id_kp_timeStamping),
- OID_ENUM(id_kp_OCSPSigning),
- /* Internet policy qualifiers */
- OID_ENUM(id_qt_cps),
- OID_ENUM(id_qt_unotice),
- /* AccessDescriptions. */
- OID_ENUM(id_ad_caIssuers),
- OID_ENUM(id_ad_ocsp),
+# define id_netscape 2, 16, 840, 1, 113730
+enum
+{
+ id_netscape_comment = 13
+};
+
+# define OID_ENUM(A) oid_ ## A
+typedef enum
+{
+ OID_ENUM(0) = 0,
+ /* X.509 certificate extensions */
+ OID_ENUM(id_ce_authorityKeyIdentifier),
+ OID_ENUM(id_ce_subjectKeyIdentifier),
+ OID_ENUM(id_ce_keyUsage),
+ OID_ENUM(id_ce_certificatePolicies),
+ OID_ENUM(id_ce_policyMappings),
+ OID_ENUM(id_ce_subjectAltName),
+ OID_ENUM(id_ce_issuerAltName),
+ OID_ENUM(id_ce_subjectDirectoryAttributes),
+ OID_ENUM(id_ce_basicConstraints),
+ OID_ENUM(id_ce_nameConstraints),
+ OID_ENUM(id_ce_policyConstraints),
+ OID_ENUM(id_ce_extKeyUsage),
+ OID_ENUM(id_ce_cRLDistributionPoints),
+ OID_ENUM(id_ce_cRLNumber),
+ OID_ENUM(id_ce_issuingDistributionPoint),
+ OID_ENUM(id_ce_inhibitAnyPolicy),
+ OID_ENUM(id_ce_freshestCRL),
+ OID_ENUM(id_pe_authorityInfoAccess),
+ OID_ENUM(id_pe_subjectInfoAccess),
+ OID_ENUM(id_netscape_comment),
+ /* Extended Key Usage */
+ OID_ENUM(id_ce_eku_anyExtendedKeyUsage),
+ OID_ENUM(id_kp_serverAuth),
+ OID_ENUM(id_kp_clientAuth),
+ OID_ENUM(id_kp_codeSigning),
+ OID_ENUM(id_kp_emailProtection),
+ OID_ENUM(id_kp_timeStamping),
+ OID_ENUM(id_kp_OCSPSigning),
+ /* Internet policy qualifiers */
+ OID_ENUM(id_qt_cps),
+ OID_ENUM(id_qt_unotice),
+ /* AccessDescriptions. */
+ OID_ENUM(id_ad_caIssuers),
+ OID_ENUM(id_ad_ocsp),
} oid_e;
/* Make the flag value, given the enum above */
-#define EXT_CRIT_FLAG(A) (unsigned int)(1 << (A))
+# define EXT_CRIT_FLAG(A) (unsigned int) (1 << (A))
/* Flags for known keyUsage (first byte) */
-#define KEY_USAGE_DIGITAL_SIGNATURE 0x0080
-#define KEY_USAGE_NON_REPUDIATION 0x0040
-#define KEY_USAGE_KEY_ENCIPHERMENT 0x0020
-#define KEY_USAGE_DATA_ENCIPHERMENT 0x0010
-#define KEY_USAGE_KEY_AGREEMENT 0x0008
-#define KEY_USAGE_KEY_CERT_SIGN 0x0004
-#define KEY_USAGE_CRL_SIGN 0x0002
-#define KEY_USAGE_ENCIPHER_ONLY 0x0001
+# define KEY_USAGE_DIGITAL_SIGNATURE 0x0080
+# define KEY_USAGE_NON_REPUDIATION 0x0040
+# define KEY_USAGE_KEY_ENCIPHERMENT 0x0020
+# define KEY_USAGE_DATA_ENCIPHERMENT 0x0010
+# define KEY_USAGE_KEY_AGREEMENT 0x0008
+# define KEY_USAGE_KEY_CERT_SIGN 0x0004
+# define KEY_USAGE_CRL_SIGN 0x0002
+# define KEY_USAGE_ENCIPHER_ONLY 0x0001
/* Flags for known keyUsage (second, optional byte) */
-#define KEY_USAGE_DECIPHER_ONLY 0x8000
+# define KEY_USAGE_DECIPHER_ONLY 0x8000
/* Flags for known extendedKeyUsage */
-#define EXT_KEY_USAGE_ANY (1 << 0)
-#define EXT_KEY_USAGE_TLS_SERVER_AUTH (1 << 1)
-#define EXT_KEY_USAGE_TLS_CLIENT_AUTH (1 << 2)
-#define EXT_KEY_USAGE_CODE_SIGNING (1 << 3)
-#define EXT_KEY_USAGE_EMAIL_PROTECTION (1 << 4)
-#define EXT_KEY_USAGE_TIME_STAMPING (1 << 8)
-#define EXT_KEY_USAGE_OCSP_SIGNING (1 << 9)
+# define EXT_KEY_USAGE_ANY (1 << 0)
+# define EXT_KEY_USAGE_TLS_SERVER_AUTH (1 << 1)
+# define EXT_KEY_USAGE_TLS_CLIENT_AUTH (1 << 2)
+# define EXT_KEY_USAGE_CODE_SIGNING (1 << 3)
+# define EXT_KEY_USAGE_EMAIL_PROTECTION (1 << 4)
+# define EXT_KEY_USAGE_TIME_STAMPING (1 << 8)
+# define EXT_KEY_USAGE_OCSP_SIGNING (1 << 9)
/******************************************************************************/
/* Holds the known extensions we support */
-typedef struct {
- psPool_t *pool;
- x509extBasicConstraints_t bc;
- x509GeneralName_t *san;
- x509GeneralName_t *issuerAltName;
- uint32 critFlags; /* EXT_CRIT_FLAG(EXT_KEY_USE) */
- uint32 keyUsageFlags; /* KEY_USAGE_ */
- uint32 ekuFlags; /* EXT_KEY_USAGE_ */
- x509extSubjectKeyId_t sk;
- x509extAuthKeyId_t ak;
-#if defined(USE_FULL_CERT_PARSE) || defined(USE_CERT_GEN)
- x509nameConstraints_t nameConstraints;
- x509certificatePolicies_t certificatePolicy;
- x509policyConstraints_t policyConstraints;
- x509policyMappings_t *policyMappings;
- x509authorityInfoAccess_t *authorityInfoAccess;
-#endif /* USE_FULL_CERT_PARSE || USE_CERT_GEN */
-#ifdef USE_CRL
- x509GeneralName_t *crlDist;
- unsigned char *crlNum;
- int32 crlNumLen;
-#endif /* USE_CRL */
+typedef struct
+{
+ psPool_t *pool;
+ x509extBasicConstraints_t bc;
+ x509GeneralName_t *san;
+ x509GeneralName_t *issuerAltName;
+ uint32 critFlags; /* EXT_CRIT_FLAG(EXT_KEY_USE) */
+ uint32 keyUsageFlags; /* KEY_USAGE_ */
+ uint32 ekuFlags; /* EXT_KEY_USAGE_ */
+ x509extSubjectKeyId_t sk;
+ x509extAuthKeyId_t ak;
+# if defined(USE_FULL_CERT_PARSE) || defined(USE_CERT_GEN)
+ x509nameConstraints_t nameConstraints;
+ x509certificatePolicies_t certificatePolicy;
+ x509policyConstraints_t policyConstraints;
+ x509policyMappings_t *policyMappings;
+ x509authorityInfoAccess_t *authorityInfoAccess;
+ x509netscapeComment_t *netscapeComment;
+# endif /* USE_FULL_CERT_PARSE || USE_CERT_GEN */
+# ifdef USE_CRL
+ x509GeneralName_t *crlDist;
+ unsigned char *crlNum;
+ int32 crlNumLen;
+# endif /* USE_CRL */
} x509v3extensions_t;
-#endif /* USE_CERT_PARSE */
+# endif /* USE_CERT_PARSE */
-#ifdef USE_CRL
-typedef struct x509revoked {
- unsigned char *serial;
- uint16_t serialLen;
- struct x509revoked *next;
+# ifdef USE_CRL
+typedef struct x509revoked
+{
+ unsigned char *serial;
+ psSize_t serialLen;
+ psBrokenDownTime_t revocationDateBDT;
+ struct x509revoked *next;
} x509revoked_t;
-typedef struct psCRL {
- psPool_t *pool;
- int32_t authenticated; /* Has this CRL been authenticated */
- unsigned char sigHash[MAX_HASH_SIZE];
- int32_t sigHashLen;
- int32 nextUpdateType;
- char *nextUpdate; /* Only concerned about expiration */
- int32_t sigAlg; /* OID_SHA1_RSA_SIG */
- unsigned char *sig;
- uint16_t sigLen;
- uint16_t expired;
- x509DNattributes_t issuer;
- x509v3extensions_t extensions;
- x509revoked_t *revoked;
- struct psCRL *next;
+typedef struct psCRL
+{
+ psPool_t *pool;
+ int32_t authenticated; /* Has this CRL been authenticated */
+ unsigned char sigHash[MAX_HASH_SIZE];
+ psSize_t sigHashLen;
+ psBrokenDownTime_t thisUpdateBDT;
+ psBrokenDownTime_t nextUpdateBDT;
+ int32 nextUpdateType;
+ char *nextUpdate; /* Only concerned about expiration */
+ int32_t sigAlg; /* eg OID_SHA1_RSA_SIG */
+ unsigned char *sig;
+ psSize_t sigLen;
+ uint16_t expired;
+ x509DNattributes_t issuer;
+ x509v3extensions_t extensions;
+ x509revoked_t *revoked;
+ struct psCRL *next;
} psX509Crl_t;
-#endif
+# endif
+typedef enum
+{
+ PS_X509_PARSE_SUCCESS = 0,
+ /* Below are parse failures */
+ PS_X509_PARSE_FAIL, /* Unspecified parse failure, enable USE_CRYPTO_TRACE */
+ PS_X509_WEAK_KEY, /* RSA/DSA/ECC key size < MIN_*_BITS */
+ PS_X509_UNSUPPORTED_VERSION, /* Version unsupported */
+ PS_X509_UNSUPPORTED_ECC_CURVE, /* Cert named curve not found in eccCurve list */
+ PS_X509_UNSUPPORTED_SIG_ALG, /* Unsupported cert algorithm: 1670,32859,32953,517 */
+ PS_X509_UNSUPPORTED_KEY_ALG, /* Unsupported public key algorithm in cert parse: 32969,515 */
+ PS_X509_UNSUPPORTED_EXT, /* Unknown extension */
+ PS_X509_DATE, /* Validity date check failed */
+ PS_X509_MISSING_NAME, /* Error. Cert has no name information */
+ PS_X509_MISSING_RSA, /* Couldn't get RSA pub key from cert */
+ PS_X509_ALG_ID, /* Couldn't parse algorithm identifier for certAlgorithm */
+ PS_X509_ISSUER_DN, /* Couldn't parse issuer DN attributes */
+ PS_X509_SIGNATURE, /* Couldn't parse signature */
+ PS_X509_SUBJECT_DN, /* Couldn't parse subject DN attributes */
+ PS_X509_EOF, /* Expecting end of cert */
+ PS_X509_SIG_MISMATCH, /* Parse error: mismatched signature type */
+} parse_status_e;
-
-typedef struct psCert {
- psPool_t *pool;
- int32 sigAlgorithm; /* Certificate sig alg OID */
- int32 certAlgorithm; /* TBSCertificate sig alg OID */
- unsigned char *signature;
- uint16_t signatureLen;
-#ifdef USE_PKCS1_PSS
- int32 pssHash; /* RSAPSS sig hash OID */
- int32 maskGen; /* RSAPSS maskgen OID */
- int32 maskHash; /* hash OID for MGF1 */
- uint16_t saltLen; /* RSAPSS salt len param */
-#endif /* USE_PKCS1_PSS */
-#ifdef USE_CERT_PARSE
- psPubKey_t publicKey;
- int32 version;
- unsigned char *serialNumber;
- uint16_t serialNumberLen;
- x509DNattributes_t issuer;
- x509DNattributes_t subject;
- int32 notBeforeTimeType;
- int32 notAfterTimeType;
- char *notBefore;
- char *notAfter;
- int32 pubKeyAlgorithm; /* public key algorithm OID */
- unsigned char *uniqueIssuerId;
- unsigned char *uniqueSubjectId;
- uint16_t uniqueIssuerIdLen;
- uint16_t uniqueSubjectIdLen;
- x509v3extensions_t extensions;
- int32 authStatus; /* See psX509AuthenticateCert doc */
- uint32 authFailFlags; /* Flags for extension check failures */
-#ifdef USE_CRL /* Use for OCSP later as well? */
- int32 revokedStatus;
-#endif
- unsigned char sigHash[MAX_HASH_SIZE];
-#endif /* USE_CERT_PARSE */
-#ifdef USE_OCSP
- unsigned char sha1KeyHash[SHA1_HASH_SIZE];
-#endif
-#ifdef ENABLE_CA_CERT_HASH
- /** @note this is used only by MatrixSSL for Trusted CA Indication extension */
- unsigned char sha1CertHash[SHA1_HASH_SIZE];
-#endif
- unsigned char *unparsedBin; /* see psX509ParseCertFile */
- uint16_t binLen;
- uint16_t publicKeyDerOffsetIntoUnparsedBin;
- uint16_t publicKeyDerLen;
- struct psCert *next;
+typedef struct psCert
+{
+ psPool_t *pool;
+ parse_status_e parseStatus;
+ int32 sigAlgorithm; /* Certificate sig alg OID */
+ int32 certAlgorithm; /* TBSCertificate sig alg OID */
+ unsigned char *signature;
+ psSize_t signatureLen;
+# ifdef USE_PKCS1_PSS
+ int32 pssHash; /* RSAPSS sig hash OID */
+ int32 maskGen; /* RSAPSS maskgen OID */
+ int32 maskHash; /* hash OID for MGF1 */
+ psSize_t saltLen; /* RSAPSS salt len param */
+# endif /* USE_PKCS1_PSS */
+# ifdef USE_CERT_PARSE
+ psPubKey_t publicKey;
+ int32 version;
+ unsigned char *serialNumber;
+ psSize_t serialNumberLen;
+ x509DNattributes_t issuer;
+ x509DNattributes_t subject;
+ int32 notBeforeTimeType;
+ int32 notAfterTimeType;
+ char *notBefore;
+ char *notAfter;
+ int32 pubKeyAlgorithm; /* public key algorithm OID */
+ unsigned char *uniqueIssuerId;
+ unsigned char *uniqueSubjectId;
+ psSize_t uniqueIssuerIdLen;
+ psSize_t uniqueSubjectIdLen;
+ x509v3extensions_t extensions;
+ int32 authStatus; /* See psX509AuthenticateCert doc */
+ uint32 authFailFlags; /* Flags for extension check failures */
+# ifdef USE_CRL /* Use for OCSP later as well? */
+ int32 revokedStatus;
+# endif
+ unsigned char sigHash[MAX_HASH_SIZE];
+# endif /* USE_CERT_PARSE */
+# ifdef USE_OCSP
+ unsigned char sha1KeyHash[SHA1_HASH_SIZE];
+# endif
+# ifdef ENABLE_CA_CERT_HASH
+ /** @note this is used only by MatrixSSL for Trusted CA Indication extension */
+ unsigned char sha1CertHash[SHA1_HASH_SIZE];
+# endif
+ unsigned char *unparsedBin; /* see psX509ParseCertFile */
+ psSize_t binLen;
+ uint16_t publicKeyDerOffsetIntoUnparsedBin;
+ psSize_t publicKeyDerLen;
+ uint16_t subjectKeyDerOffsetIntoUnparsedBin;
+ struct psCert *next;
} psX509Cert_t;
-
-extern int32_t psX509GetSignature(psPool_t *pool, const unsigned char **pp,
- uint16_t len, unsigned char **sig, uint16_t *sigLen);
-#ifdef USE_CERT_PARSE
+extern int32_t psX509GetSignature(psPool_t *pool,const unsigned char **pp,
+ psSize_t len, unsigned char **sig, psSize_t *sigLen);
+# ifdef USE_CERT_PARSE
extern int32_t psX509GetDNAttributes(psPool_t *pool, const unsigned char **pp,
- uint16_t len, x509DNattributes_t *attribs, uint32_t flags);
+ psSize_t len, x509DNattributes_t *attribs, uint32_t flags);
extern void psX509FreeDNStruct(x509DNattributes_t *dn, psPool_t *allocPool);
extern int32_t getSerialNum(psPool_t *pool, const unsigned char **pp,
- uint16_t len, unsigned char **sn, uint16_t *snLen);
+ psSize_t len, unsigned char **sn, psSize_t *snLen);
extern int32_t getExplicitExtensions(psPool_t *pool, const unsigned char **pp,
- uint16_t inlen, int32_t expVal, x509v3extensions_t *extensions,
- uint8_t known);
+ psSize_t inlen, int32_t expVal, x509v3extensions_t *extensions,
+ uint8_t known);
extern void x509FreeExtensions(x509v3extensions_t *extensions);
extern int32_t psX509ValidateGeneralName(const char *n);
+/** Get the number of organizationalUnits in a distinguished name (DN). */
+extern int32_t psX509GetNumOrganizationalUnits(const x509DNattributes_t *DN);
+
/** Get the number of domainComponents in a distinguished name (DN). */
extern int32_t psX509GetNumDomainComponents(const x509DNattributes_t *DN);
+/** Get a pointer to an organizationalUnit.
+
+ Caller must NOT free the returned x509OrgUnit_t.
+
+ @param[in] DN The DN struct from which to fetch the organizationalUnit.
+ Note that freeing the DN will invalidate the returned x509OrgUnit_t.
+ @param[in] index The index of the organizationalUnit in the order they
+ appear in the DER encoding.
+ */
+extern x509OrgUnit_t *psX509GetOrganizationalUnit(
+ const x509DNattributes_t *DN,
+ int32_t index);
+
/** Get a pointer to a domain component.
- @param[in] DN The DN struct from which to fetch the domainComponent.
- Callet must NOT free this.
- @param[in] index The index of the domainComponent in the order they
- appear in the DER encoding.
-*/
-extern x509DomainComponent_t* psX509GetDomainComponent(const x509DNattributes_t *DN,
- int32_t index);
+ Caller must NOT free the returned x509DomainComponent_t.
+
+ @param[in] DN The DN struct from which to fetch the domainComponent.
+ Note that freeing the DN will invalidate the returned
+ x509DomainComponent_t.
+ @param[in] index The index of the domainComponent in the order they
+ appear in the DER encoding.
+ */
+extern x509DomainComponent_t *psX509GetDomainComponent(
+ const x509DNattributes_t *DN,
+ int32_t index);
/** Get the concatenation of all domainComponents in a DN as a C string.
- This function returns the concanated domainComponents as a string terminated
- with DN_NUM_TERMINATING_NULLS NULL characters. The output string will
- contain the components in the reverse order compared to the order in which
- they were encoded in the certificate. Usually, this will result in the
- usual print order, i.e. top-level component (.com, .org, ...) last.
+ This function returns the concanated domainComponents as a string terminated
+ with DN_NUM_TERMINATING_NULLS NULL characters. The output string will
+ contain the components in the reverse order compared to the order in which
+ they were encoded in the certificate. Usually, this will result in the
+ usual print order, i.e. top-level component (.com, .org, ...) last.
- @param[in] DN The DN struct from which to fetch the domainComponent.
- @param[out] out_str The concanated domainComponents as a string. This
- function will malloc a string of suitable length. The caller is responsible
- for freeing it.
- @param[out] out_str_len Length of the returned string.
-*/
-extern int32_t psX509GetConcatenatedDomainComponent(const x509DNattributes_t *DN,
- char **out_str,
- size_t *out_str_len);
-#endif /* USE_CERT_PARSE */
+ @param[in] DN The DN struct from which to fetch the domainComponent.
+ @param[out] out_str The concanated domainComponents as a string. This
+ function will malloc a string of suitable length. The caller is responsible
+ for freeing it.
+ @param[out] out_str_len Length of the returned string.
+ */
+extern int32_t psX509GetConcatenatedDomainComponent(
+ const x509DNattributes_t *DN,
+ char **out_str,
+ size_t *out_str_len);
+# endif /* USE_CERT_PARSE */
-#ifdef USE_OCSP
-#include
-#include
+# ifdef USE_FULL_CERT_PARSE
+/** Create a concatenated string containing all the supported fields of a DN
+ component.
+
+ This function creates a oneline string from a DN, using a format similar
+ to OpenSSL's X509_NAME_oneline(). Only the fields supported by the
+ current configuration are printed. Example:
+ "C=US, ST=State, DC=com, DC=insidesecure, DC=test/street=street/title=Dr,
+ GN=GivenName, SN=Surname/name=GivenName Surname."
+
+ @param[in] DN The DN struct from which to build the oneline string.
+ @param[out] out_str Pointer to the memory address where the resulting string
+ will be allocated and copied to. Caller is responsible for freeing.
+ @param[out] out_str_len Length of the resulting string.
+ */
+extern int32_t psX509GetOnelineDN(const x509DNattributes_t *DN,
+ char **out_str,
+ size_t *out_str_len);
+# endif /* USE_FULL_CERT_PARSE */
+
+# ifdef USE_OCSP
+# include
+# include
/* The default value of allowed mismatch in times in OCSP messages and the local
clock. */
-#define PS_OCSP_TIME_LINGER (120)
+# define PS_OCSP_TIME_LINGER (120)
/* The OCSP structure members point directly into an OCSPResponse stream.
- They are validated immediately after the parse so if a change request
- requires these fields to persist, this will all have to change */
-typedef struct {
- uint16_t certIdHashAlg; /* hashAlgorithm in CertID */
- const unsigned char *certIdNameHash;
- const unsigned char *certIdKeyHash;
- const unsigned char *certIdSerial;
- short certIdSerialLen;
- short certStatus;
- unsigned char revocationTime[15];
- unsigned char revocationReason;
- const unsigned char *thisUpdate;
- short thisUpdateLen;
- const unsigned char *nextUpdate;
- short nextUpdateLen;
-} mOCSPSingleResponse_t;
+ They are validated immediately after the parse so if a change request
+ requires these fields to persist, this will all have to change */
+typedef struct
+{
+ uint16_t certIdHashAlg; /* hashAlgorithm in CertID */
+ const unsigned char *certIdNameHash;
+ const unsigned char *certIdKeyHash;
+ const unsigned char *certIdSerial;
+ short certIdSerialLen;
+ short certStatus;
+ unsigned char revocationTime[15];
+ unsigned char revocationReason;
+ const unsigned char *thisUpdate;
+ short thisUpdateLen;
+ const unsigned char *nextUpdate;
+ short nextUpdateLen;
+} psOcspSingleResponse_t;
-#define MAX_OCSP_RESPONSES 3
+# define MAX_OCSP_RESPONSES 3
-typedef struct {
- const unsigned char *responderKeyHash;
- const unsigned char *timeProduced;
- short timeProducedLen;
- mOCSPSingleResponse_t singleResponse[MAX_OCSP_RESPONSES];
- uint16_t sigAlg;
- const unsigned char *sig;
- uint16_t sigLen;
- unsigned char hashResult[MAX_HASH_SIZE];
- uint16_t hashLen;
- psX509Cert_t *OCSPResponseCert; /* Allocated to hsPool */
- psBuf_t nonce; /* Pointer to response. */
-} mOCSPResponse_t;
+typedef struct
+{
+ const unsigned char *responderName;
+ const unsigned char *responderKeyHash;
+ const unsigned char *timeProduced;
+ short timeProducedLen;
+ psOcspSingleResponse_t singleResponse[MAX_OCSP_RESPONSES];
+ uint16_t sigAlg;
+ const unsigned char *sig;
+ psSize_t sigLen;
+ unsigned char hashResult[MAX_HASH_SIZE];
+ psSize_t hashLen;
+ psX509Cert_t *OCSPResponseCert; /* Allocated to hsPool */
+ psBuf_t nonce; /* Pointer to response. */
+ int version; /* Response version (see
+ PS_VERSION_UNSUPPORTED). */
+ const unsigned char *responseType; /* Response type (OID tag). */
+} psOcspResponse_t;
-typedef enum {
- PS_CRLREASON_UNSPECIFIED = 0,
- PS_CRLREASON_KEY_COMPROMISE = 1,
- PS_CRLREASON_CA_COMPROMISE = 2,
- PS_CRLREASON_AFFILIATION_CHANGED = 3,
- PS_CRLREASON_SUPERSEDED = 4,
- PS_CRLREASON_CESSATION_OF_OPERATION = 5,
- PS_CRLREASON_CERTIFICATE_HOLD = 6,
- /* value 7 is not used according to RFC 5280. */
- PS_CRLREASON_REMOVE_FROM_CRL = 8,
- PS_CRLREASON_PRIVILEGE_WITHDRAWN = 9,
- PS_CRLREASON_AA_COMPROMISE = 10
+typedef enum
+{
+ PS_CRLREASON_UNSPECIFIED = 0,
+ PS_CRLREASON_KEY_COMPROMISE = 1,
+ PS_CRLREASON_CA_COMPROMISE = 2,
+ PS_CRLREASON_AFFILIATION_CHANGED = 3,
+ PS_CRLREASON_SUPERSEDED = 4,
+ PS_CRLREASON_CESSATION_OF_OPERATION = 5,
+ PS_CRLREASON_CERTIFICATE_HOLD = 6,
+ /* value 7 is not used according to RFC 5280. */
+ PS_CRLREASON_REMOVE_FROM_CRL = 8,
+ PS_CRLREASON_PRIVILEGE_WITHDRAWN = 9,
+ PS_CRLREASON_AA_COMPROMISE = 10
} x509CrlReason_t;
-typedef struct {
- /* Will be set to 1 if status is known, 0 if not. */
- bool *knownFlag;
- /* Will be set to 1 if revoked, 0 if ok. */
- bool *revocationFlag;
- /* If response included nonce or both request and response were
- without nonce, then set this flag. Requires request+requestLen to
- be provided. */
- bool *nonceMatch;
- /* Will indicate revocation time (note: timezone = UTC). */
- psBrokenDownTime_t *revocationTime;
- /* Will indicate revocation reason. */
- x509CrlReason_t *revocationReason;
- /* The request for comparing nonce if nonce extension is used. */
- const void *request;
- size_t requestLen;
- /* The location for use response index. */
- int32 *index_p;
+typedef struct
+{
+ /* Will be set to 1 if status is known, 0 if not. */
+ psBool_t *knownFlag;
+ /* Will be set to 1 if revoked, 0 if ok. */
+ psBool_t *revocationFlag;
+ /* If response included nonce or both request and response were
+ without nonce, then set this flag. Requires request+requestLen to
+ be provided. */
+ psBool_t *nonceMatch;
+ /* Will indicate revocation time (note: timezone = UTC). */
+ psBrokenDownTime_t *revocationTime;
+ /* Will indicate revocation reason. */
+ x509CrlReason_t *revocationReason;
+ /* The request for comparing nonce if nonce extension is used. */
+ const void *request;
+ size_t requestLen;
+ /* The location for use response index. */
+ int32 *index_p;
} psValidateOCSPResponseOptions_t;
/* Parse OCSP response received.
- The result shall be unitialized with uninitOCSPResponse(). */
-extern int32_t parseOCSPResponse(psPool_t *pool, int32_t len,
- unsigned char **cp, unsigned char *end,
- mOCSPResponse_t *response);
+ The result shall be unitialized with psOcspResponseUninit(). */
+extern int32_t psOcspParseResponse(psPool_t *pool, int32_t len,
+ unsigned char **cp, unsigned char *end,
+ psOcspResponse_t *response);
+
+/* Convert OCSP response status code into integer representing status. */
+extern int32_t psOcspResponseGetStatus(int32_t rc);
/* Get dates from OCSP response, to e.g. check how long server wants the
response to remain valid. */
-extern int32_t checkOCSPResponseDates(mOCSPResponse_t *response,
- int index,
- psBrokenDownTime_t *time_now,
- psBrokenDownTime_t *producedAt,
- psBrokenDownTime_t *thisUpdate,
- psBrokenDownTime_t *nextUpdate,
- int time_linger);
+extern int32_t psOcspResponseCheckDates(psOcspResponse_t *response,
+ int index,
+ psBrokenDownTime_t *time_now,
+ psBrokenDownTime_t *producedAt,
+ psBrokenDownTime_t *thisUpdate,
+ psBrokenDownTime_t *nextUpdate,
+ int time_linger);
-/* Validate OCSP response (find status of specific certificate) */
-extern int32_t validateOCSPResponse(psPool_t *pool, psX509Cert_t *trustedOCSP,
- psX509Cert_t *srvCerts,
- mOCSPResponse_t *response);
+/** Validate OCSP response (find status of specific certificate)
-/* Validation with additional parameter to obtain more details, like
- revocation time and reason. */
-extern int32_t validateOCSPResponse_ex(psPool_t *pool,
- psX509Cert_t *trustedOCSP,
- psX509Cert_t *srvCerts,
- mOCSPResponse_t *response,
- psValidateOCSPResponseOptions_t *vOpts);
+ Validate the given OCSP response and determine the revocation
+ status of a certificate.
+
+ To validate the OCSP response, the the function will go through
+ points 1-5 in section 3.2 of RFC 6960.
+
+ To verify the response signature, the function first looks for the
+ certificate of the signer of the OCSP response.
+ Three places are searched for the signer certificate:
+ - The OCSP response itself (according to RFC 6960: "The responder MAY
+ include certificates in the certs field of BasicOCSPResponse that
+ help the OCSP client verify the responder's signature").
+ - The trustedOCSP list of CA certificates.
+ - The srvCerts server certificate chain.
+ If the signer's certificate is found in the OCSP response, the function
+ will authenticate the certificate against the trustedOCSP CA list.
+ If the signer's certificate is found in the trustedOCSP list or in the
+ (already authenticated) server certificate chain, no further authentication
+ is performed.
+ Once the signer's certificate has been found and authenticated, the
+ function will attempt to verify the response signature using the public
+ key from that certificate. Both RSA and ECDSA signatures are supported.
+
+ The function will try match the server certificate (pointed to by srvCerts)
+ against each certificate in the singleResponse sequence in the OCSP response.
+
+ To validate the response timestamp, the function will call
+ psOcspResponseCheckDates. A configurable amount of clock skew between
+ server and client (PS_OCSP_TIME_LINGER) is allowed. For details, see
+ the Developer Guide and the header documentation for psOcspResponseCheckDates.
+
+ @param[in] pool Pointer to the psPool_t structure.
+ @param[in] trustedOCSP Pointer to a linked list of trusted CA certificates
+ @param[in] srvCerts Pointer to the server certificate chain. The certificate
+ whose revocation status is to be checked should be the leaf (i.e. first)
+ certificate of this chain.
+ @param[in] response Pointer to the parsed OCSP response to validate.
+ @retval[out] PS_SUCCESS: the OCSP response was validated successfully.
+ PS_FAILURE: unable to validate the OCSP response, or the OCSP response
+ contained no revocation information for this certificate (srvCerts).
+ PS_CERT_AUTH_FAIL_REVOKED: the OCSP response indicates the server certificate
+ has been revoked.
+ */
+extern int32_t psOcspResponseValidateOld(psPool_t *pool,
+ psX509Cert_t *trustedOCSP,
+ psX509Cert_t *srvCerts,
+ psOcspResponse_t *response);
+
+/** Validate OCSP response with additional parameter to obtain more
+ details, like revocation time and reason.
+
+ See the documentation for psOcspResponseValidateOld for a description of the
+ parameters and return codes. Here, only the effect of the additional
+ parameters (vOpts) is described.
+
+ It is possible to get more information on the OCSP response by assigning
+ a non-NULL pointer to the following vOpts:
+ - The psBool_t pointed by vOpts->knownFlag will be set to true (1) if OCSP
+ response contained no revocation information for this certificate (srvCerts).
+ - The psBool_t pointed by vOpts->revocationFlag will be set true (1) if the
+ certificate has been revoked, and to 0 otherwise.
+ - The psBrokenDownTime_t pointed by vOpts->revocationTime will be filled
+ in to contain the revocation time.
+ - The x509CrlReason_t pointed by vOpts->revocationReason will be filled
+ to contain the revocation reason. See the "Revocation status and reason"
+ section in the Developer Guide for details.
+ - The psBool_t pointed to by vOpts->nonceMatch will be set to true (1) if the
+ same nonce was found in the OCSP request and response. For this,
+ the caller must provide the OCSP request and its length in vOpts->request
+ and vOpts->requestLen, respectively. Note that when the OCSP response
+ is valid and the certificate is not revoked, this function will return
+ PS_SUCCESS even in the case of nonce mismatch.
+ */
+extern int32_t psOcspResponseValidate(psPool_t *pool,
+ psX509Cert_t *trustedOCSP,
+ psX509Cert_t *srvCerts,
+ psOcspResponse_t *response,
+ psValidateOCSPResponseOptions_t *vOpts);
/* Construct OCSP request used in OCSP protocol to obtain OCSP response.
The request obtained typically needs to be sent to OCSP responder using
HTTP protocol to obtain corresponding OCSP response.
After finished with the request, it shall be freed using psFree(). */
-extern int32_t matrixSslWriteOCSPRequest(psPool_t *pool, psX509Cert_t *cert,
- psX509Cert_t *certIssuer, unsigned char **request,
- uint32_t *requestLen, int32_t flags);
+extern int32_t psOcspRequestWriteOld(psPool_t *pool, psX509Cert_t *cert,
+ psX509Cert_t *certIssuer, unsigned char **request,
+ uint32_t *requestLen, int32_t flags);
/* Uninitialize OCSP response. */
-void uninitOCSPResponse(mOCSPResponse_t *res);
+void psOcspResponseUninit(psOcspResponse_t *res);
-typedef struct {
- int32_t flags;
- psBuf_t *requesterId; /* Optional requestor id. */
- const psBuf_t *requestExtensions; /* Optional request extensions. */
-} matrixSslWriteOCSPRequestInfo_t;
+typedef struct
+{
+ int32_t flags;
+ psBuf_t *requesterId; /* Optional requestor id. */
+ const psBuf_t *requestExtensions; /* Optional request extensions. */
+ int ocspRequestVersion; /* Default = 0 (v1). */
+ int32_t sign_oid; /* Signing oid. */
+ psPubKey_t *sign_key; /* Signing key. */
+ psX509Cert_t *sign_cert; /* Certificate for the signing key. */
+} psOcspRequestWriteInfo_t;
-/* Set Requester ID for matrixSslWriteOCSPRequestInfo_t structure.
- It shall be freed using matrixSslWriteOCSPRequestInfoFreeRequestorId.
+# define MATRIXSSL_WRITE_OCSP_REQUEST_FLAG_NONCE 1 /* Use nonce. */
+# define MATRIXSSL_WRITE_OCSP_REQUEST_FLAG_CERT_LIST 2 /* Multiple requests. */
+# define MATRIXSSL_WRITE_OCSP_REQUEST_SIGN 4 /* Need signing. */
+# define MATRIXSSL_WRITE_OCSP_REQUEST_SIGN_CERT_LIST 8 /* Signing with
+ certificate list. */
+
+/* Set Signing Info to psOcspRequestWriteInfo_t structure. */
+extern int32_t psOcspRequestWriteInfoSetSigning(
+ psOcspRequestWriteInfo_t *info_p,
+ int32_t sign_oid, /* designate algorithm to use for signing. */
+ psPubKey_t *priv_key,
+ psX509Cert_t *cert,
+ int is_cert_chain);
+
+/* Set Requester ID for psOcspRequestWriteInfo_t structure.
+ It shall be freed using psOcspRequestWriteInfoFreeRequestorId.
The data expected varies according to the general name, for instance, for
IPv4 address, the data shall be array of 4 bytes containing the octets.
However, for the most types the data shall be a string, and for this reason
parameters are called str and strLen.
For GN_DIR, the octet sequence can be created with psWriteCertDNAttributes()
function. */
-extern int32_t matrixSslWriteOCSPRequestInfoSetRequestorId(
- psPool_t *pool,
- matrixSslWriteOCSPRequestInfo_t *info,
- const char *str, size_t strLen, x509GeneralNameType_t type);
+extern int32_t psOcspRequestWriteInfoSetRequestorId(
+ psPool_t *pool,
+ psOcspRequestWriteInfo_t *info,
+ const char *str, size_t strLen, x509GeneralNameType_t type);
-/* Free previously set Requester ID from matrixSslWriteOCSPRequestInfo_t
+/* Free previously set Requester ID from psOcspRequestWriteInfo_t
structure. */
-extern void matrixSslWriteOCSPRequestInfoFreeRequestorId(
- psPool_t *pool, matrixSslWriteOCSPRequestInfo_t *info);
+extern void psOcspRequestWriteInfoFreeRequestorId(
+ psPool_t *pool, psOcspRequestWriteInfo_t *info);
-#define MATRIXSSL_WRITE_OCSP_REQUEST_FLAG_NONCE 1 /* Use nonce. */
-#define MATRIXSSL_WRITE_OCSP_REQUEST_FLAG_CERT_LIST 2 /* Multiple requests. */
-
-/* Extended version of matrixSslWriteOCSPRequest: allows use of
+/* Extended version of psOcspRequestWriteOld: allows use of
requestor name and nonce extension. */
-extern int32_t matrixSslWriteOCSPRequestExt(
- psPool_t *pool, psX509Cert_t *cert,
- psX509Cert_t *certIssuer, unsigned char **request,
- uint32_t *requestLen,
- matrixSslWriteOCSPRequestInfo_t *info);
+extern int32_t psOcspRequestWrite(
+ psPool_t *pool, psX509Cert_t *cert,
+ psX509Cert_t *certIssuer, unsigned char **request,
+ uint32_t *requestLen,
+ psOcspRequestWriteInfo_t *info);
-#endif
+# define MATRIXSSL_OCSP_VERSION_V1 0
+
+/* Override version of OCSP request.
+ If this function is not called, the lowest OCSP request version with all
+ requested features is used. Currently, this version is
+ MATRIXSSL_OCSP_VERSION_V1 (0).
+ */
+extern void psOcspRequestWriteVersion(
+ int version,
+ psOcspRequestWriteInfo_t *info);
+
+# endif
/******************************************************************************/
/******************************************************************************/
-#endif /* USE_X509 */
+# endif /* USE_X509 */
-#endif /* _h_PS_X509 */
+#endif /* _h_PS_X509 */
/******************************************************************************/
diff --git a/crypto/layer/layer.h b/crypto/layer/layer.h
index 2e8c2a4..04f9b77 100644
--- a/crypto/layer/layer.h
+++ b/crypto/layer/layer.h
@@ -1,337 +1,337 @@
/**
- * @file layer.h
- * @version $Format:%h%d$
+ * @file layer.h
+ * @version $Format:%h%d$
*
- * Header file to determine crypto algorithm provider.
+ * Header file to determine crypto algorithm provider.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PS_CRYPTOLAYER
-#define _h_PS_CRYPTOLAYER
+# define _h_PS_CRYPTOLAYER
/**
- Layer implementations of configured crypto APIs.
- First we define MATRIX as the crypto provider for each enabled algorithm
- that was enabled above and then we can override with other providers.
-*/
-#if (defined(USE_AES_CBC) || defined(USE_AES_GCM) || \
- defined(USE_AES_WRAP) || defined(USE_AES_CMAC) || \
- defined(USE_AES_CTR))
- #define USE_MATRIX_AES_BLOCK
- #define USE_AES_BLOCK
- #define USE_AES
-#endif
+ Layer implementations of configured crypto APIs.
+ First we define MATRIX as the crypto provider for each enabled algorithm
+ that was enabled above and then we can override with other providers.
+ */
+# if (defined(USE_AES_CBC) || defined(USE_AES_GCM) || \
+ defined(USE_AES_WRAP) || defined(USE_AES_CMAC) || \
+ defined(USE_AES_CTR))
+# define USE_MATRIX_AES_BLOCK
+# define USE_AES_BLOCK
+# define USE_AES
+# endif
-#define USE_MATRIX_RAW_KEY /* Default, unless changed by lower layers */
+# define USE_MATRIX_RAW_KEY /* Default, unless changed by lower layers */
-#if defined(USE_AES_CBC)
- #define USE_MATRIX_AES_CBC
-#endif
-#if defined(USE_AES_GCM)
- #define USE_MATRIX_AES_GCM
-#endif
-#if defined(USE_AES_CMAC)
- #define USE_MATRIX_AES_CMAC
-#endif
-#if defined(USE_AES_WRAP)
- #define USE_MATRIX_AES_WRAP
-#endif
-#if defined(USE_AES_CTR)
- #define USE_MATRIX_AES_CTR
-#endif
+# if defined(USE_AES_CBC)
+# define USE_MATRIX_AES_CBC
+# endif
+# if defined(USE_AES_GCM)
+# define USE_MATRIX_AES_GCM
+# endif
+# if defined(USE_AES_CMAC)
+# define USE_MATRIX_AES_CMAC
+# endif
+# if defined(USE_AES_WRAP)
+# define USE_MATRIX_AES_WRAP
+# endif
+# if defined(USE_AES_CTR)
+# define USE_MATRIX_AES_CTR
+# endif
-#ifdef USE_CHACHA20_POLY1305
- #ifndef USE_LIBSODIUM_CRYPTO
- #error "libsodium required for chacha20_poly1305"
- #endif
-#endif
+# ifdef USE_CHACHA20_POLY1305
+# ifndef USE_LIBSODIUM_CRYPTO
+# error "libsodium required for chacha20_poly1305"
+# endif
+# endif
-#ifdef USE_ARC4
- #define USE_MATRIX_ARC4
-#endif
-#ifdef USE_RC2
- #define USE_MATRIX_RC2
-#endif
-#ifdef USE_3DES
- #define USE_MATRIX_3DES
-#endif
-#ifdef USE_SEED
- #define USE_MATRIX_SEED
-#endif
-#ifdef USE_IDEA
- #define USE_MATRIX_IDEA
-#endif
+# ifdef USE_ARC4
+# define USE_MATRIX_ARC4
+# endif
+# ifdef USE_RC2
+# define USE_MATRIX_RC2
+# endif
+# ifdef USE_3DES
+# define USE_MATRIX_3DES
+# endif
+# ifdef USE_SEED
+# define USE_MATRIX_SEED
+# endif
+# ifdef USE_IDEA
+# define USE_MATRIX_IDEA
+# endif
-#if defined(USE_SHA256)
- #define USE_MATRIX_SHA256
-#endif
-#if defined(USE_HMAC_SHA256)
- #define USE_MATRIX_HMAC_SHA256
-#endif
+# if defined(USE_SHA256)
+# define USE_MATRIX_SHA256
+# endif
+# if defined(USE_HMAC_SHA256)
+# define USE_MATRIX_HMAC_SHA256
+# endif
-#if defined(USE_SHA384)
- #define USE_MATRIX_SHA384
-#endif
-#if defined(USE_HMAC_SHA384)
- #define USE_MATRIX_HMAC_SHA384
-#endif
+# if defined(USE_SHA384)
+# define USE_MATRIX_SHA384
+# endif
+# if defined(USE_HMAC_SHA384)
+# define USE_MATRIX_HMAC_SHA384
+# endif
-#if defined(USE_SHA512)
- #define USE_MATRIX_SHA512
-#endif
+# if defined(USE_SHA512)
+# define USE_MATRIX_SHA512
+# endif
-#if defined(USE_SHA1)
- #define USE_MATRIX_SHA1
-#endif
-#if defined(USE_HMAC_SHA1)
- #define USE_MATRIX_HMAC_SHA1
-#endif
-#if defined(USE_MD5SHA1)
- #define USE_MATRIX_MD5SHA1
-#endif
+# if defined(USE_SHA1)
+# define USE_MATRIX_SHA1
+# endif
+# if defined(USE_HMAC_SHA1)
+# define USE_MATRIX_HMAC_SHA1
+# endif
+# if defined(USE_MD5SHA1)
+# define USE_MATRIX_MD5SHA1
+# endif
-#if defined(USE_MD5)
- #define USE_MATRIX_MD5
-#endif
-#if defined(USE_HMAC_MD5)
- #define USE_MATRIX_HMAC_MD5
-#endif
+# if defined(USE_MD5)
+# define USE_MATRIX_MD5
+# endif
+# if defined(USE_HMAC_MD5)
+# define USE_MATRIX_HMAC_MD5
+# endif
-#if defined(USE_MD4)
- #define USE_MATRIX_MD4
-#endif
+# if defined(USE_MD4)
+# define USE_MATRIX_MD4
+# endif
-#if defined(USE_MD2)
- #define USE_MATRIX_MD2
-#endif
+# if defined(USE_MD2)
+# define USE_MATRIX_MD2
+# endif
-#if defined(USE_RSA)
- #define USE_MATRIX_RSA
-#endif
+# if defined(USE_RSA)
+# define USE_MATRIX_RSA
+# endif
-#if defined(USE_ECC)
- #define USE_MATRIX_ECC
-#endif
+# if defined(USE_ECC)
+# define USE_MATRIX_ECC
+# endif
-#if defined(USE_DH)
- #define USE_MATRIX_DH
-#endif
+# if defined(USE_DH)
+# define USE_MATRIX_DH
+# endif
-#if defined(USE_PRNG)
- #define USE_MATRIX_PRNG
-#endif
+# if defined(USE_PRNG)
+# define USE_MATRIX_PRNG
+# endif
-#ifdef USE_LIBSODIUM_CRYPTO
+# ifdef USE_LIBSODIUM_CRYPTO
/******************************************************************************/
/**
- Use libsodium cryptography primitives (link with libsodium.a).
-*/
- #ifdef USE_CHACHA20_POLY1305
-// #undef USE_MATRIX_CHACHA20_POLY1305 /* @note, not defined in matrix crypto */
- #define USE_LIBSODIUM_CHACHA20_POLY1305
- #endif
-
- #ifdef USE_MATRIX_AES_GCM
- #undef USE_MATRIX_AES_GCM
- #define USE_LIBSODIUM_AES_GCM
- #endif
+ Use libsodium cryptography primitives (link with libsodium.a).
+ */
+# ifdef USE_CHACHA20_POLY1305
+/* #undef USE_MATRIX_CHACHA20_POLY1305 / * @note, not defined in matrix crypto * / */
+# define USE_LIBSODIUM_CHACHA20_POLY1305
+# endif
- #ifdef USE_MATRIX_SHA256
- #undef USE_MATRIX_SHA256
- #define USE_LIBSODIUM_SHA256
- #endif
+# ifdef USE_MATRIX_AES_GCM
+# undef USE_MATRIX_AES_GCM
+# define USE_LIBSODIUM_AES_GCM
+# endif
- #ifdef USE_MATRIX_SHA384
- #undef USE_MATRIX_SHA384
- #define USE_LIBSODIUM_SHA384
- #endif
+# ifdef USE_MATRIX_SHA256
+# undef USE_MATRIX_SHA256
+# define USE_LIBSODIUM_SHA256
+# endif
- #ifdef USE_MATRIX_SHA512
- #undef USE_MATRIX_SHA512
- #define USE_LIBSODIUM_SHA512
- #endif
+# ifdef USE_MATRIX_SHA384
+# undef USE_MATRIX_SHA384
+# define USE_LIBSODIUM_SHA384
+# endif
- #ifdef USE_MATRIX_HMAC_SHA256
- #undef USE_MATRIX_HMAC_SHA256
- #define USE_LIBSODIUM_HMAC_SHA256
- #endif
+# ifdef USE_MATRIX_SHA512
+# undef USE_MATRIX_SHA512
+# define USE_LIBSODIUM_SHA512
+# endif
-#endif /* USE_LIBSODIUM_CRYPTO */
+# ifdef USE_MATRIX_HMAC_SHA256
+# undef USE_MATRIX_HMAC_SHA256
+# define USE_LIBSODIUM_HMAC_SHA256
+# endif
+
+# endif /* USE_LIBSODIUM_CRYPTO */
/* Common for CL CRYPTO and FIPS CRYPTO */
-#ifdef USE_OPENSSL_CRYPTO
+# ifdef USE_OPENSSL_CRYPTO
/******************************************************************************/
/**
- Use OpenSSL cryptography primitives (link with libcrypto.a).
- This can take advantage of hardware which has a specifically optimized
- libcrypto library, for example Cavium Octeon.
-*/
- #ifdef USE_MATRIX_AES_CBC
- #undef USE_MATRIX_AES_CBC
- #define USE_OPENSSL_AES_CBC
- #endif
- #ifdef USE_MATRIX_MD5
- #undef USE_MATRIX_MD5
- #define USE_OPENSSL_MD5
- #endif
- #ifdef USE_MATRIX_SHA1
- #undef USE_MATRIX_SHA1
- #define USE_OPENSSL_SHA1
- #endif
- #ifdef USE_MATRIX_MD5SHA1
- #undef USE_MATRIX_MD5SHA1
- #define USE_OPENSSL_MD5SHA1
- #endif
- #ifdef USE_MATRIX_SHA256
- #undef USE_MATRIX_SHA256
- #define USE_OPENSSL_SHA256
- #endif
- #ifdef USE_MATRIX_SHA384
- #undef USE_MATRIX_SHA384
- #define USE_OPENSSL_SHA384
- #endif
- #ifdef USE_MATRIX_SHA512
- #undef USE_MATRIX_SHA512
- #define USE_OPENSSL_SHA512
- #endif
- #ifdef USE_MATRIX_HMAC_MD5
- #undef USE_MATRIX_HMAC_MD5
- #define USE_OPENSSL_HMAC_MD5
- #endif
- #ifdef USE_MATRIX_HMAC_SHA1
- #undef USE_MATRIX_HMAC_SHA1
- #define USE_OPENSSL_HMAC_SHA1
- #endif
- #ifdef USE_MATRIX_HMAC_SHA256
- #undef USE_MATRIX_HMAC_SHA256
- #define USE_OPENSSL_HMAC_SHA256
- #endif
- #ifdef USE_MATRIX_HMAC_SHA384
- #undef USE_MATRIX_HMAC_SHA384
- #define USE_OPENSSL_HMAC_SHA384
- #endif
- #ifdef USE_MATRIX_RSA
- #undef USE_MATRIX_RSA
- #define USE_OPENSSL_RSA
- #endif
-#endif /* USE_OPENSSL_CRYPTO */
+ Use OpenSSL cryptography primitives (link with libcrypto.a).
+ This can take advantage of hardware which has a specifically optimized
+ libcrypto library, for example Cavium Octeon.
+ */
+# ifdef USE_MATRIX_AES_CBC
+# undef USE_MATRIX_AES_CBC
+# define USE_OPENSSL_AES_CBC
+# endif
+# ifdef USE_MATRIX_MD5
+# undef USE_MATRIX_MD5
+# define USE_OPENSSL_MD5
+# endif
+# ifdef USE_MATRIX_SHA1
+# undef USE_MATRIX_SHA1
+# define USE_OPENSSL_SHA1
+# endif
+# ifdef USE_MATRIX_MD5SHA1
+# undef USE_MATRIX_MD5SHA1
+# define USE_OPENSSL_MD5SHA1
+# endif
+# ifdef USE_MATRIX_SHA256
+# undef USE_MATRIX_SHA256
+# define USE_OPENSSL_SHA256
+# endif
+# ifdef USE_MATRIX_SHA384
+# undef USE_MATRIX_SHA384
+# define USE_OPENSSL_SHA384
+# endif
+# ifdef USE_MATRIX_SHA512
+# undef USE_MATRIX_SHA512
+# define USE_OPENSSL_SHA512
+# endif
+# ifdef USE_MATRIX_HMAC_MD5
+# undef USE_MATRIX_HMAC_MD5
+# define USE_OPENSSL_HMAC_MD5
+# endif
+# ifdef USE_MATRIX_HMAC_SHA1
+# undef USE_MATRIX_HMAC_SHA1
+# define USE_OPENSSL_HMAC_SHA1
+# endif
+# ifdef USE_MATRIX_HMAC_SHA256
+# undef USE_MATRIX_HMAC_SHA256
+# define USE_OPENSSL_HMAC_SHA256
+# endif
+# ifdef USE_MATRIX_HMAC_SHA384
+# undef USE_MATRIX_HMAC_SHA384
+# define USE_OPENSSL_HMAC_SHA384
+# endif
+# ifdef USE_MATRIX_RSA
+# undef USE_MATRIX_RSA
+# define USE_OPENSSL_RSA
+# endif
+# endif /* USE_OPENSSL_CRYPTO */
-#if defined(__AES__) && !defined(USE_FIPS_CRYPTO)
+# if defined(__AES__) && !defined(USE_FIPS_CRYPTO)
/******************************************************************************/
/**
- This is defined if the -maes compiler flag is used on Intel platforms.
- @see https://en.wikipedia.org/wiki/AES_instruction_set
-*/
- #ifdef USE_MATRIX_AES_BLOCK
- #undef USE_MATRIX_AES_BLOCK
- #define USE_AESNI_AES_BLOCK
- #endif
- #ifdef USE_MATRIX_AES_CBC
- #undef USE_MATRIX_AES_CBC
- #define USE_AESNI_AES_CBC
- #endif
- #ifdef USE_MATRIX_AES_GCM
- #undef USE_MATRIX_AES_GCM
- #define USE_AESNI_AES_GCM
- #endif
- #if defined(USE_AESNI_AES_BLOCK) || defined(USE_AESNI_AES_CBC) || \
- defined(USE_AESNI_AES_GCM)
- #define USE_AESNI_CRYPTO
- #endif
-#endif /* __AES__ */
+ This is defined if the -maes compiler flag is used on Intel platforms.
+ @see https://en.wikipedia.org/wiki/AES_instruction_set
+ */
+# ifdef USE_MATRIX_AES_BLOCK
+# undef USE_MATRIX_AES_BLOCK
+# define USE_AESNI_AES_BLOCK
+# endif
+# ifdef USE_MATRIX_AES_CBC
+# undef USE_MATRIX_AES_CBC
+# define USE_AESNI_AES_CBC
+# endif
+# ifdef USE_MATRIX_AES_GCM
+# undef USE_MATRIX_AES_GCM
+# define USE_AESNI_AES_GCM
+# endif
+# if defined(USE_AESNI_AES_BLOCK) || defined(USE_AESNI_AES_CBC) || \
+ defined(USE_AESNI_AES_GCM)
+# define USE_AESNI_CRYPTO
+# endif
+# endif /* __AES__ */
/******************************************************************************/
/*
- Enable algorithm optimizations based on the compiler optimization settings.
- GCC compatible compilers will define:
- __OPTIMIZE__ for all -O1 and above (include -Os)
- __OPTIMIZE_SIZE__ in addition to __OPTIMIZE__ for -Os
+ Enable algorithm optimizations based on the compiler optimization settings.
+ GCC compatible compilers will define:
+ __OPTIMIZE__ for all -O1 and above (include -Os)
+ __OPTIMIZE_SIZE__ in addition to __OPTIMIZE__ for -Os
- Both code size and RAM usage are affected by these defines.
+ Both code size and RAM usage are affected by these defines.
- By default below, these will be enabled on an optimized build that is
- not optimized for size. Eg. for -O[1-3,fast], but not for -Os
+ By default below, these will be enabled on an optimized build that is
+ not optimized for size. Eg. for -O[1-3,fast], but not for -Os
- For a specific platform, it is best to tune these by hand to get the
- right balance of speed and size.
-*/
-#if defined(__OPTIMIZE__)
- #if !defined(__OPTIMIZE_SIZE__)
+ For a specific platform, it is best to tune these by hand to get the
+ right balance of speed and size.
+ */
+# if defined(__OPTIMIZE__)
+# if !defined(__OPTIMIZE_SIZE__)
/*
- Improve block cipher performance, but produce larger code.
- Platforms vary, but ciphers will generally see a 5%-10% performance
- boost at the cost of 10-20 kilobytes (per algorithm).
-*/
- #ifdef USE_MATRIX_AES_BLOCK
- #define PS_AES_IMPROVE_PERF_INCREASE_CODESIZE
- #endif
- #ifdef USE_MATRIX_3DES
- #define PS_3DES_IMPROVE_PERF_INCREASE_CODESIZE
- #endif
+ Improve block cipher performance, but produce larger code.
+ Platforms vary, but ciphers will generally see a 5%-10% performance
+ boost at the cost of 10-20 kilobytes (per algorithm).
+ */
+# ifdef USE_MATRIX_AES_BLOCK
+# define PS_AES_IMPROVE_PERF_INCREASE_CODESIZE
+# endif
+# ifdef USE_MATRIX_3DES
+# define PS_3DES_IMPROVE_PERF_INCREASE_CODESIZE
+# endif
/*
- Improve hashing performance, but produce larger code.
- Platforms vary, but digests will generally see a 5%-10% performance
- boost at the cost of 1-10 kilobytes (per algorithm).
-*/
- #ifdef USE_MATRIX_MD5
- #define PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE
- #endif
- #ifdef USE_MATRIX_SHA1
- #define PS_SHA1_IMPROVE_PERF_INCREASE_CODESIZE
- #endif
+ Improve hashing performance, but produce larger code.
+ Platforms vary, but digests will generally see a 5%-10% performance
+ boost at the cost of 1-10 kilobytes (per algorithm).
+ */
+# ifdef USE_MATRIX_MD5
+# define PS_MD5_IMPROVE_PERF_INCREASE_CODESIZE
+# endif
+# ifdef USE_MATRIX_SHA1
+# define PS_SHA1_IMPROVE_PERF_INCREASE_CODESIZE
+# endif
/*
- Optimize public/private key operations for speed.
- Optimizations for 1024/2048 bit key size multiplication and squaring math.
- The library size can increase significantly if enabled.
-*/
- #if defined(USE_MATRIX_RSA) || defined(USE_MATRIX_ECC) || defined(USE_MATRIX_DH)
- #define PS_PUBKEY_OPTIMIZE_FOR_FASTER_SPEED
- #endif
- #if defined(USE_MATRIX_RSA) || defined(USE_MATRIX_DH)
- #define USE_1024_KEY_SPEED_OPTIMIZATIONS
- #define USE_2048_KEY_SPEED_OPTIMIZATIONS
- #endif
+ Optimize public/private key operations for speed.
+ Optimizations for 1024/2048 bit key size multiplication and squaring math.
+ The library size can increase significantly if enabled.
+ */
+# if defined(USE_MATRIX_RSA) || defined(USE_MATRIX_ECC) || defined(USE_MATRIX_DH)
+# define PS_PUBKEY_OPTIMIZE_FOR_FASTER_SPEED
+# endif
+# if defined(USE_MATRIX_RSA) || defined(USE_MATRIX_DH)
+# define USE_1024_KEY_SPEED_OPTIMIZATIONS
+# define USE_2048_KEY_SPEED_OPTIMIZATIONS
+# endif
- #else /* OPTIMIZE_SIZE */
+# else /* OPTIMIZE_SIZE */
/*
- Optimize public/private key operations for smaller ram usage.
- The memory savings for optimizing for ram is around 50%
-*/
- #if defined(USE_MATRIX_RSA) || defined(USE_MATRIX_ECC) || defined(USE_MATRIX_DH)
- #define PS_PUBKEY_OPTIMIZE_FOR_SMALLER_RAM
- #endif
+ Optimize public/private key operations for smaller ram usage.
+ The memory savings for optimizing for ram is around 50%
+ */
+# if defined(USE_MATRIX_RSA) || defined(USE_MATRIX_ECC) || defined(USE_MATRIX_DH)
+# define PS_PUBKEY_OPTIMIZE_FOR_SMALLER_RAM
+# endif
- #endif /* OPTIMIZE_SIZE */
-#endif /* OPTIMIZE */
+# endif /* OPTIMIZE_SIZE */
+# endif /* OPTIMIZE */
-#endif /* _h_PS_CRYPTOLAYER */
+#endif /* _h_PS_CRYPTOLAYER */
/******************************************************************************/
diff --git a/crypto/layer/matrix.c b/crypto/layer/matrix.c
index 0f17ee0..b09fc75 100644
--- a/crypto/layer/matrix.c
+++ b/crypto/layer/matrix.c
@@ -1,88 +1,92 @@
/**
- * @file matrix.c
- * @version $Format:%h%d$
+ * @file matrix.c
+ * @version $Format:%h%d$
*
- * Matrix Crypto Initialization and utility layer.
+ * Matrix Crypto Initialization and utility layer.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
/******************************************************************************/
/**
- Open (initialize) the Crypto module.
+ Open (initialize) the Crypto module.
- The config param should always be passed as:
- PSCRYPTO_CONFIG
-*/
+ The config param should always be passed as:
+ PSCRYPTO_CONFIG
+ */
static char g_config[32] = "N";
int32_t psCryptoOpen(const char *config)
{
- uint32_t clen;
-
- if (*g_config == 'Y') {
- return PS_SUCCESS; /* Function has been called previously */
- }
- /* 'config' is cryptoconfig + coreconfig */
- strncpy(g_config, PSCRYPTO_CONFIG, sizeof(g_config) - 1);
- clen = strlen(PSCRYPTO_CONFIG) - strlen(PSCORE_CONFIG);
- if (strncmp(g_config, config, clen) != 0) {
- psErrorStr( "Crypto config mismatch.\n" \
- "Library: " PSCRYPTO_CONFIG\
- "\nCurrent: %s\n", config);
- return -1;
- }
- if (psCoreOpen(config + clen) < 0) {
- psError("pscore open failure\n");
- return PS_FAILURE;
- }
+ uint32_t clen;
+
+ if (*g_config == 'Y')
+ {
+ return PS_SUCCESS; /* Function has been called previously */
+ }
+ /* 'config' is cryptoconfig + coreconfig */
+ strncpy(g_config, PSCRYPTO_CONFIG, sizeof(g_config) - 1);
+ clen = strlen(PSCRYPTO_CONFIG) - strlen(PSCORE_CONFIG);
+ if (strncmp(g_config, config, clen) != 0)
+ {
+ psErrorStr( "Crypto config mismatch.\n" \
+ "Library: " PSCRYPTO_CONFIG \
+ "\nCurrent: %s\n", config);
+ return -1;
+ }
+ if (psCoreOpen(config + clen) < 0)
+ {
+ psError("pscore open failure\n");
+ return PS_FAILURE;
+ }
#ifdef USE_FLPS_BINDING
- flps_binding();
+ flps_binding();
#endif /* USE_FLPS_BINDING */
- psOpenPrng();
+ psOpenPrng();
#ifdef USE_CRL
- psCrlOpen();
+ psCrlOpen();
#endif
- return 0;
+ return 0;
}
void psCryptoClose(void)
{
- if (*g_config == 'Y') {
- *g_config = 'N';
- psClosePrng();
- psCoreClose();
+ if (*g_config == 'Y')
+ {
+ *g_config = 'N';
+ psClosePrng();
+ psCoreClose();
#ifdef USE_CRL
- psCrlClose();
+ psCrlClose();
#endif
- }
+ }
}
/******************************************************************************/
diff --git a/crypto/math/pstm.c b/crypto/math/pstm.c
index 34d62e2..f630548 100644
--- a/crypto/math/pstm.c
+++ b/crypto/math/pstm.c
@@ -1,41 +1,42 @@
/**
- * @file pstm.c
- * @version $Format:%h%d$
+ * @file pstm.c
+ * @version $Format:%h%d$
*
- * Multiprecision number implementation.
+ * Multiprecision number implementation.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
/* This pstm mathematics library is
based on libraries by Tom St Denis. */
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
+#include "pstmnt.h"
#include /* toupper() */
@@ -45,2300 +46,2712 @@ static int32_t pstm_mul_2d(const pstm_int *a, int16_t b, pstm_int *c);
/******************************************************************************/
/**
- Initialize a pstm_int and allocate working memory for a given initial size.
+ Initialize a pstm_int and allocate working memory for a given initial size.
- @param[in] pool Memory pool to use for allocation.
- @param[in,out] a Allocated pstm_int to initialize.
- @param[in] size Number of digits to pre-allocate for integer. Typically
- a digit is 32 or 64 bits.
+ @param[in] pool Memory pool to use for allocation.
+ @param[in,out] a Allocated pstm_int to initialize.
+ @param[in] size Number of digits to pre-allocate for integer. Typically
+ a digit is 32 or 64 bits.
- @return < 0 on failure, >=0 on success.
+ @return < 0 on failure, >=0 on success.
*/
-int32_t pstm_init_size(psPool_t *pool, pstm_int *a, uint16_t size)
+int32_t pstm_init_size(psPool_t *pool, pstm_int *a, psSize_t size)
{
- uint16_t x;
+ uint16_t x;
- if (size > PSTM_MAX_SIZE) {
- return PSTM_MEM;
- }
- a->dp = psMalloc(pool, sizeof(pstm_digit) * size);
- if (a->dp == NULL) {
- return PSTM_MEM;
- }
- a->pool = pool; /* Pool to use when growing or shrinking digits */
- a->used = 0; /* Zero of the digits are currently used */
- a->alloc = size; /* How many digits are pre-allocated */
- a->sign = PSTM_ZPOS; /* Number is positive */
- /* zero the digits */
- for (x = 0; x < size; x++) {
- a->dp[x] = 0;
- }
- return PSTM_OKAY;
+ if (size > PSTM_MAX_SIZE)
+ {
+ return PSTM_MEM;
+ }
+ a->dp = psMalloc(pool, sizeof(pstm_digit) * size);
+ if (a->dp == NULL)
+ {
+ return PSTM_MEM;
+ }
+ a->pool = pool; /* Pool to use when growing or shrinking digits */
+ a->used = 0; /* Zero of the digits are currently used */
+ a->alloc = size; /* How many digits are pre-allocated */
+ a->sign = PSTM_ZPOS; /* Number is positive */
+ /* zero the digits */
+ for (x = 0; x < size; x++)
+ {
+ a->dp[x] = 0;
+ }
+ return PSTM_OKAY;
}
/******************************************************************************/
/*
- Init a new pstm_int with a default size.
-*/
+ Init a new pstm_int with a default size.
+ */
int32_t pstm_init(psPool_t *pool, pstm_int *a)
{
- return pstm_init_size(pool, a, (MIN_RSA_BITS / DIGIT_BIT) * 3);
+ return pstm_init_size(pool, a, (MIN_RSA_BITS / DIGIT_BIT) * 3);
}
/******************************************************************************/
/**
- Grow a pstm_int to the give size in digits.
+ Grow a pstm_int to the give size in digits.
- @param[in,out] a Allocated and initialized pstm_int to grow.
- @param[in] size Number of digits to grow to. This is not the the number
- of digits to grow _by_. 'size' <= current size is ignored, so this
- api cannot be used to shrink the integer.
+ @param[in,out] a Allocated and initialized pstm_int to grow.
+ @param[in] size Number of digits to grow to. This is not the the number
+ of digits to grow _by_. 'size' <= current size is ignored, so this
+ api cannot be used to shrink the integer.
*/
-int32_t pstm_grow(pstm_int * a, uint16_t size)
+int32_t pstm_grow(pstm_int *a, psSize_t size)
{
- uint16_t i;
- pstm_digit *tmp;
+ uint16_t i;
+ pstm_digit *tmp;
- if (size > PSTM_MAX_SIZE) {
- return PSTM_MEM;
- }
- /* If the alloc size is smaller alloc more ram. */
- if (a->alloc < size) {
+ if (size > PSTM_MAX_SIZE)
+ {
+ return PSTM_MEM;
+ }
+ /* If the alloc size is smaller alloc more ram. */
+ if (a->alloc < size)
+ {
/*
- Reallocate the array a->dp
- We store the return in a temporary variable in case the operation
- failed we don't want to overwrite the dp member of a.
-*/
- tmp = psRealloc(a->dp, sizeof (pstm_digit) * size, a->pool);
- if (tmp == NULL) {
- /* reallocation failed but "a" is still valid [can be freed] */
- return PSTM_MEM;
- }
- /* reallocation succeeded so set a->dp */
- a->dp = tmp;
- i = a->alloc;
- a->alloc = size;
- /* zero excess digits */
- for (; i < a->alloc; i++) {
- a->dp[i] = 0;
- }
- }
- return PSTM_OKAY;
+ Reallocate the array a->dp
+ We store the return in a temporary variable in case the operation
+ failed we don't want to overwrite the dp member of a.
+ */
+ tmp = psRealloc(a->dp, sizeof(pstm_digit) * size, a->pool);
+ if (tmp == NULL)
+ {
+ /* reallocation failed but "a" is still valid [can be freed] */
+ return PSTM_MEM;
+ }
+ /* reallocation succeeded so set a->dp */
+ a->dp = tmp;
+ i = a->alloc;
+ a->alloc = size;
+ /* zero excess digits */
+ for (; i < a->alloc; i++)
+ {
+ a->dp[i] = 0;
+ }
+ }
+ return PSTM_OKAY;
}
/******************************************************************************/
/*
- copy, b = a (b must be pre-allocated)
+ copy, b = a (b must be pre-allocated)
*/
-int32_t pstm_copy(const pstm_int * a, pstm_int * b)
+int32_t pstm_copy(const pstm_int *a, pstm_int *b)
{
- int32_t res, n;
+ int32_t res, n;
- /* If dst == src do nothing */
- if (a == b) {
- return PSTM_OKAY;
- }
- /* Grow dest */
- if (b->alloc < a->used) {
- if ((res = pstm_grow(b, a->used)) != PSTM_OKAY) {
- return res;
- }
- }
- /* Zero b and copy the parameters over */
- {
- /* pointer aliases */
- register pstm_digit *tmpa, *tmpb;
+ /* If dst == src do nothing */
+ if (a == b)
+ {
+ return PSTM_OKAY;
+ }
+ /* Grow dest */
+ if (b->alloc < a->used)
+ {
+ if ((res = pstm_grow(b, a->used)) != PSTM_OKAY)
+ {
+ return res;
+ }
+ }
+ /* Zero b and copy the parameters over */
+ {
+ /* pointer aliases */
+ register pstm_digit *tmpa, *tmpb;
- /* source */
- tmpa = a->dp;
- /* destination */
- tmpb = b->dp;
+ /* source */
+ tmpa = a->dp;
+ /* destination */
+ tmpb = b->dp;
- /* copy all the digits */
- for (n = 0; n < a->used; n++) {
- *tmpb++ = *tmpa++;
- }
- /* clear high digits */
- for (; n < b->used; n++) {
- *tmpb++ = 0;
- }
- }
- /* copy used count and sign */
- b->used = a->used;
- b->sign = a->sign;
- return PSTM_OKAY;
+ /* copy all the digits */
+ for (n = 0; n < a->used; n++)
+ {
+ *tmpb++ = *tmpa++;
+ }
+ /* clear high digits */
+ for (; n < b->used; n++)
+ {
+ *tmpb++ = 0;
+ }
+ }
+ /* copy used count and sign */
+ b->used = a->used;
+ b->sign = a->sign;
+ return PSTM_OKAY;
}
/******************************************************************************/
/**
- b = |a|.
- Copy 'a' to 'b' and make positive.
-*/
+ b = |a|.
+ Copy 'a' to 'b' and make positive.
+ */
int32_t pstm_abs(const pstm_int *a, pstm_int *b)
{
- if (pstm_copy(a, b) != PSTM_OKAY) {
- return PSTM_MEM;
- }
- b->sign = 0;
- return PSTM_OKAY;
+ if (pstm_copy(a, b) != PSTM_OKAY)
+ {
+ return PSTM_MEM;
+ }
+ b->sign = 0;
+ return PSTM_OKAY;
}
/******************************************************************************/
/**
- Trim unused digits.
+ Trim unused digits.
- This is used to ensure that leading zero digits are trimed and the
- leading "used" digit will be non-zero. Typically very fast. Also fixes
- the sign if there are no more leading digits
-*/
+ This is used to ensure that leading zero digits are trimed and the
+ leading "used" digit will be non-zero. Typically very fast. Also fixes
+ the sign if there are no more leading digits
+ */
void pstm_clamp(pstm_int *a)
{
- /* decrease used while the most significant digit is zero. */
- while (a->used > 0 && a->dp[a->used - 1] == 0) {
- --(a->used);
- }
- /* reset the sign flag if used == 0 */
- if (a->used == 0) {
- a->sign = PSTM_ZPOS;
- }
+ /* decrease used while the most significant digit is zero. */
+ while (a->used > 0 && a->dp[a->used - 1] == 0)
+ {
+ --(a->used);
+ }
+ /* reset the sign flag if used == 0 */
+ if (a->used == 0)
+ {
+ a->sign = PSTM_ZPOS;
+ }
}
/******************************************************************************/
/**
- Clear a big integer, and free associated working memory.
+ Clear a big integer, and free associated working memory.
*/
void pstm_clear(pstm_int *a)
{
- int32 i;
+ int32 i;
- /* only do anything if a hasn't been freed previously */
- if (a != NULL && a->dp != NULL) {
- /* first zero the digits */
- for (i = 0; i < a->used; i++) {
- a->dp[i] = 0;
- }
- psFree (a->dp, a->pool);
- /* reset members to make debugging easier */
- a->dp = NULL;
- a->alloc = a->used = 0;
- a->sign = PSTM_ZPOS;
- }
+ /* only do anything if a hasn't been freed previously */
+ if (a != NULL && a->dp != NULL)
+ {
+ /* first zero the digits */
+ for (i = 0; i < a->used; i++)
+ {
+ a->dp[i] = 0;
+ }
+ psFree(a->dp, a->pool);
+ /* reset members to make debugging easier */
+ a->dp = NULL;
+ a->alloc = a->used = 0;
+ a->sign = PSTM_ZPOS;
+ }
}
/******************************************************************************/
/**
- Clears mp0 - mp7, stopping at the first NULL mp value.
- @example pstm_clear_multi(a, b, c, d, NULL, NULL, NULL, NULL);
+ Clears mp0 - mp7, stopping at the first NULL mp value.
+ @example pstm_clear_multi(a, b, c, d, NULL, NULL, NULL, NULL);
*/
void pstm_clear_multi(pstm_int *mp0, pstm_int *mp1, pstm_int *mp2,
- pstm_int *mp3, pstm_int *mp4, pstm_int *mp5,
- pstm_int *mp6, pstm_int *mp7)
+ pstm_int *mp3, pstm_int *mp4, pstm_int *mp5,
+ pstm_int *mp6, pstm_int *mp7)
{
- if (mp0) {
- pstm_clear(mp0);
- if (mp1) {
- pstm_clear(mp1);
- if (mp2) {
- pstm_clear(mp2);
- if (mp3) {
- pstm_clear(mp3);
- if (mp4) {
- pstm_clear(mp4);
- if (mp5) {
- pstm_clear(mp5);
- if (mp6) {
- pstm_clear(mp6);
- if (mp7) {
- pstm_clear(mp7);
- }
- }
- }
- }
- }
- }
- }
- }
+ if (mp0)
+ {
+ pstm_clear(mp0);
+ if (mp1)
+ {
+ pstm_clear(mp1);
+ if (mp2)
+ {
+ pstm_clear(mp2);
+ if (mp3)
+ {
+ pstm_clear(mp3);
+ if (mp4)
+ {
+ pstm_clear(mp4);
+ if (mp5)
+ {
+ pstm_clear(mp5);
+ if (mp6)
+ {
+ pstm_clear(mp6);
+ if (mp7)
+ {
+ pstm_clear(mp7);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
/******************************************************************************/
/**
- Set to zero.
+ Set to zero.
*/
-void pstm_zero(pstm_int * a)
+void pstm_zero(pstm_int *a)
{
- uint16_t n;
- pstm_digit *tmp;
+ uint16_t n;
+ pstm_digit *tmp;
- a->sign = PSTM_ZPOS;
- a->used = 0;
+ a->sign = PSTM_ZPOS;
+ a->used = 0;
- tmp = a->dp;
- for (n = 0; n < a->alloc; n++) {
- *tmp++ = 0;
- }
+ tmp = a->dp;
+ for (n = 0; n < a->alloc; n++)
+ {
+ *tmp++ = 0;
+ }
}
/******************************************************************************/
/*
- Compare maginitude of two ints (unsigned).
+ Compare maginitude of two ints (unsigned).
*/
int32_t pstm_cmp_mag(const pstm_int *a, const pstm_int *b)
{
- uint16_t n;
- const pstm_digit *tmpa, *tmpb;
+ uint16_t n;
+ const pstm_digit *tmpa, *tmpb;
- /* compare based on # of non-zero digits */
- if (a->used > b->used) {
- return PSTM_GT;
- } else if (a->used < b->used) {
- return PSTM_LT;
- }
- /* alias for a */
- tmpa = a->dp + (a->used - 1);
- /* alias for b */
- tmpb = b->dp + (a->used - 1);
- /* compare based on digits */
- for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
- if (*tmpa > *tmpb) {
- return PSTM_GT;
- } else if (*tmpa < *tmpb) {
- return PSTM_LT;
- }
- }
- return PSTM_EQ;
+ /* compare based on # of non-zero digits */
+ if (a->used > b->used)
+ {
+ return PSTM_GT;
+ }
+ else if (a->used < b->used)
+ {
+ return PSTM_LT;
+ }
+ /* alias for a */
+ tmpa = a->dp + (a->used - 1);
+ /* alias for b */
+ tmpb = b->dp + (a->used - 1);
+ /* compare based on digits */
+ for (n = 0; n < a->used; ++n, --tmpa, --tmpb)
+ {
+ if (*tmpa > *tmpb)
+ {
+ return PSTM_GT;
+ }
+ else if (*tmpa < *tmpb)
+ {
+ return PSTM_LT;
+ }
+ }
+ return PSTM_EQ;
}
/******************************************************************************/
/*
- Compare two ints (signed)
+ Compare two ints (signed)
*/
int32_t pstm_cmp(const pstm_int *a, const pstm_int *b)
{
- /* compare based on sign */
- if (a->sign != b->sign) {
- if (a->sign == PSTM_NEG) {
- return PSTM_LT;
- } else {
- return PSTM_GT;
- }
- }
- /* compare digits */
- if (a->sign == PSTM_NEG) {
- /* if negative compare opposite direction */
- return pstm_cmp_mag(b, a);
- } else {
- return pstm_cmp_mag(a, b);
- }
+ /* compare based on sign */
+ if (a->sign != b->sign)
+ {
+ if (a->sign == PSTM_NEG)
+ {
+ return PSTM_LT;
+ }
+ else
+ {
+ return PSTM_GT;
+ }
+ }
+ /* compare digits */
+ if (a->sign == PSTM_NEG)
+ {
+ /* if negative compare opposite direction */
+ return pstm_cmp_mag(b, a);
+ }
+ else
+ {
+ return pstm_cmp_mag(a, b);
+ }
}
/******************************************************************************/
/*
- compare against a single digit
-*/
+ compare against a single digit
+ */
int32_t pstm_cmp_d(const pstm_int *a, pstm_digit b)
{
- /* compare based on sign */
- if ((b && a->used == 0) || a->sign == PSTM_NEG) {
- return PSTM_LT;
- }
- /* compare based on magnitude */
- if (a->used > 1) {
- return PSTM_GT;
- }
- /* compare the only digit of a to b */
- if (a->dp[0] > b) {
- return PSTM_GT;
- } else if (a->dp[0] < b) {
- return PSTM_LT;
- } else {
- return PSTM_EQ;
- }
+ /* compare based on sign */
+ if ((b && a->used == 0) || a->sign == PSTM_NEG)
+ {
+ return PSTM_LT;
+ }
+ /* compare based on magnitude */
+ if (a->used > 1)
+ {
+ return PSTM_GT;
+ }
+ /* compare the only digit of a to b */
+ if (a->dp[0] > b)
+ {
+ return PSTM_GT;
+ }
+ else if (a->dp[0] < b)
+ {
+ return PSTM_LT;
+ }
+ else
+ {
+ return PSTM_EQ;
+ }
}
/******************************************************************************/
/*
- pstm_ints can be initialized more precisely when they will populated
- using pstm_read_unsigned_bin since the length of the byte stream is known
-*/
-int32_t pstm_init_for_read_unsigned_bin(psPool_t *pool, pstm_int *a, uint16_t len)
+ pstm_ints can be initialized more precisely when they will populated
+ using pstm_read_unsigned_bin since the length of the byte stream is known
+ */
+int32_t pstm_init_for_read_unsigned_bin(psPool_t *pool, pstm_int *a, psSize_t len)
{
- uint16_t size;
+ psSize_t size;
+
/*
- Need to set this based on how many words max it will take to store the bin.
- The magic + 2:
- 1 to round up for the remainder of this integer math
- 1 for the initial carry of '1' bits that fall between DIGIT_BIT and 8
-*/
- size = (((len / sizeof(pstm_digit)) * (sizeof(pstm_digit) * CHAR_BIT))
- / DIGIT_BIT) + 2;
- return pstm_init_size(pool, a, size);
+ Need to set this based on how many words max it will take to store the bin.
+ The magic + 2:
+ 1 to round up for the remainder of this integer math
+ 1 for the initial carry of '1' bits that fall between DIGIT_BIT and 8
+ */
+ size = (((len / sizeof(pstm_digit)) * (sizeof(pstm_digit) * CHAR_BIT))
+ / DIGIT_BIT) + 2;
+ return pstm_init_size(pool, a, size);
}
/******************************************************************************/
/**
- Reads a unsigned char array into pstm_int format.
+ Reads a unsigned char array into pstm_int format.
- @param[in,out] a The allocated and initialized pstm_int
- @param[in] b Pointer to a byte array of length 'c'.
- @param[in] c Length in bytes of 'b'.
+ @param[in,out] a The allocated and initialized pstm_int
+ @param[in] b Pointer to a byte array of length 'c'.
+ @param[in] c Length in bytes of 'b'.
- @pre User should have called pstm_init_for_read_unsigned_bin first.
- @note There is some grow logic here if the default pstm_init was used but we
- don't really want to hit it.
-*/
-int32_t pstm_read_unsigned_bin(pstm_int *a, const unsigned char *buf, uint16_t len)
+ @pre User should have called pstm_init_for_read_unsigned_bin first.
+ @note There is some grow logic here if the default pstm_init was used but we
+ don't really want to hit it.
+ */
+int32_t pstm_read_unsigned_bin(pstm_int *a, const unsigned char *buf, psSize_t len)
{
- /* zero the int */
- pstm_zero (a);
+ /* zero the int */
+ pstm_zero(a);
/*
- If we know the endianness of this architecture, and we're using
- 32-bit pstm_digits, we can optimize this
- TODO Can optimize 64 bit case as well.
-*/
-#if (defined(ENDIAN_LITTLE) || defined(ENDIAN_BIG)) && !defined(PSTM_64BIT)
- /* But not for both simultaneously */
-#if defined(ENDIAN_LITTLE) && defined(ENDIAN_BIG)
-#error Both ENDIAN_LITTLE and ENDIAN_BIG defined.
-#endif
- {
- unsigned char *pd;
- int16_t slen;
- if ((unsigned)len > (PSTM_MAX_SIZE * sizeof(pstm_digit))) {
- uint16_t excess = len - (PSTM_MAX_SIZE * sizeof(pstm_digit));
- len -= excess;
- buf += excess;
- }
- a->used = (len + sizeof(pstm_digit) - 1) / sizeof(pstm_digit);
- if (a->alloc < a->used) {
- if (pstm_grow(a, a->used) != PSTM_OKAY) {
- return PSTM_MEM;
- }
- }
- pd = (unsigned char *)a->dp;
- /* read the bytes in */
- /* these loops need len to go negative */
- slen = (int16_t)len;
-#ifdef ENDIAN_BIG
- {
- /* Use Duff's device to unroll the loop. */
- uint16_t idx = (slen - 1) & ~3;
- switch (slen % 4) {
- case 0: do { pd[idx+0] = *buf++;
- case 3: pd[idx+1] = *buf++;
- case 2: pd[idx+2] = *buf++;
- case 1: pd[idx+3] = *buf++;
- idx -= 4;
- } while ((slen -= 4) > 0);
- }
- }
-#else
- for (slen -= 1; slen >= 0; slen -= 1) {
- pd[slen] = *buf++;
- }
-#endif
- }
-#else
- /* Big enough based on the len? */
- a->used = (((len / sizeof(pstm_digit)) * (sizeof(pstm_digit) * CHAR_BIT))
- / DIGIT_BIT) + 2;
+ If we know the endianness of this architecture, and we're using
+ 32-bit pstm_digits, we can optimize this
+ TODO Can optimize 64 bit case as well.
+ */
+# if (defined(ENDIAN_LITTLE) || defined(ENDIAN_BIG)) && !defined(PSTM_64BIT)
+ /* But not for both simultaneously */
+# if defined(ENDIAN_LITTLE) && defined(ENDIAN_BIG)
+# error Both ENDIAN_LITTLE and ENDIAN_BIG defined.
+# endif
+ {
+ unsigned char *pd;
+ int16_t slen;
+ if ((unsigned) len > (PSTM_MAX_SIZE * sizeof(pstm_digit)))
+ {
+ uint16_t excess = len - (PSTM_MAX_SIZE * sizeof(pstm_digit));
+ len -= excess;
+ buf += excess;
+ }
+ a->used = (len + sizeof(pstm_digit) - 1) / sizeof(pstm_digit);
+ if (a->alloc < a->used)
+ {
+ if (pstm_grow(a, a->used) != PSTM_OKAY)
+ {
+ return PSTM_MEM;
+ }
+ }
+ pd = (unsigned char *) a->dp;
+ /* read the bytes in */
+ /* these loops need len to go negative */
+ slen = (int16_t) len;
+# ifdef ENDIAN_BIG
+ {
+ /* Use Duff's device to unroll the loop. */
+ uint16_t idx = (slen - 1) & ~3;
+ switch (slen % 4)
+ {
+ case 0: do
+ {
+ pd[idx + 0] = *buf++;
+ case 3: pd[idx + 1] = *buf++;
+ case 2: pd[idx + 2] = *buf++;
+ case 1: pd[idx + 3] = *buf++;
+ idx -= 4;
+ }
+ while ((slen -= 4) > 0);
+ }
+ }
+# else
+ for (slen -= 1; slen >= 0; slen -= 1)
+ {
+ pd[slen] = *buf++;
+ }
+# endif
+ }
+# else
+ /* Big enough based on the len? */
+ a->used = (((len / sizeof(pstm_digit)) * (sizeof(pstm_digit) * CHAR_BIT))
+ / DIGIT_BIT) + 2;
- if (a->alloc < a->used) {
- if (pstm_grow(a, a->used) != PSTM_OKAY) {
- return PSTM_MEM;
- }
- }
- /* read the bytes in */
- for (; len > 0; len--) {
- if (pstm_mul_2d (a, 8, a) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- a->dp[0] |= *buf++;
- a->used += 1;
- }
-#endif
+ if (a->alloc < a->used)
+ {
+ if (pstm_grow(a, a->used) != PSTM_OKAY)
+ {
+ return PSTM_MEM;
+ }
+ }
+ /* read the bytes in */
+ for (; len > 0; len--)
+ {
+ if (pstm_mul_2d(a, 8, a) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ a->dp[0] |= *buf++;
+ a->used += 1;
+ }
+# endif
- pstm_clamp (a);
- return PS_SUCCESS;
+ pstm_clamp(a);
+ return PS_SUCCESS;
}
/******************************************************************************/
/**
- Read a pstm_int from an ASN.1 formatted buffer.
-*/
-int32_t pstm_read_asn(psPool_t *pool, const unsigned char **pp, uint16_t len,
- pstm_int *a)
+ Read a pstm_int from an ASN.1 formatted buffer.
+ */
+int32_t pstm_read_asn(psPool_t *pool, const unsigned char **pp, psSize_t len,
+ pstm_int *a)
{
- const unsigned char *p = *pp;
- uint16_t vlen;
+ const unsigned char *p = *pp;
+ psSize_t vlen;
- if (len < 1 || *(p++) != ASN_INTEGER ||
- getAsnLength(&p, len - 1, &vlen) < 0 || (len - 1) < vlen) {
- return PS_PARSE_FAIL;
- }
- /* Make a smart size since we know the length */
- if (pstm_init_for_read_unsigned_bin(pool, a, vlen) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- if (pstm_read_unsigned_bin(a, p, vlen) != 0) {
- pstm_clear(a);
- psTraceCrypto("pstm_read_asn failed\n");
- return PS_PARSE_FAIL;
- }
- *pp = p + vlen;
- return PS_SUCCESS;
+ if (len < 1 || *(p++) != ASN_INTEGER ||
+ getAsnLength(&p, len - 1, &vlen) < 0 || (len - 1) < vlen)
+ {
+ return PS_PARSE_FAIL;
+ }
+ /* Make a smart size since we know the length */
+ if (pstm_init_for_read_unsigned_bin(pool, a, vlen) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ if (pstm_read_unsigned_bin(a, p, vlen) != 0)
+ {
+ pstm_clear(a);
+ psTraceCrypto("pstm_read_asn failed\n");
+ return PS_PARSE_FAIL;
+ }
+ *pp = p + vlen;
+ return PS_SUCCESS;
}
-#if defined USE_ECC || defined USE_DH || defined USE_CERT_GEN
+# if defined USE_ECC || defined USE_DH || defined USE_CERT_GEN
/******************************************************************************/
/**
- Add a digit to an int.
- c = a + b;
- @param[in] pool Memory pool
- @param[in] a Big integer operand
- @param[in] b Big digit operand
- @param[out] c Big integer result
- @return < 0 on failure
-*/
+ Add a digit to an int.
+ c = a + b;
+ @param[in] pool Memory pool
+ @param[in] a Big integer operand
+ @param[in] b Big digit operand
+ @param[out] c Big integer result
+ @return < 0 on failure
+ */
int32_t pstm_add_d(psPool_t *pool, const pstm_int *a, pstm_digit b, pstm_int *c)
{
- pstm_int tmp;
- int32_t res;
+ pstm_int tmp;
+ int32_t res;
- if (pstm_init_size(pool, &tmp, sizeof(pstm_digit)) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- pstm_set(&tmp, b);
- res = pstm_add(a, &tmp, c);
- pstm_clear(&tmp);
- return res;
+ if (pstm_init_size(pool, &tmp, sizeof(pstm_digit)) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ pstm_set(&tmp, b);
+ res = pstm_add(a, &tmp, c);
+ pstm_clear(&tmp);
+ return res;
}
-#endif /* defined USE_ECC || defined USE_DH || defined USE_CERT_GEN */
-#ifdef USE_ECC
+# endif /* defined USE_ECC || defined USE_DH || defined USE_CERT_GEN */
+# ifdef USE_ECC
/* chars used in radix (base) conversions */
const static unsigned char pstm_s_rmap[64] =
- "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
/**
- Read in data to a big integer from a given radix (base).
- Typically the radix is 16 to read in hex data.
- To read in binary data, use pstm_read_unsigned_bin().
+ Read in data to a big integer from a given radix (base).
+ Typically the radix is 16 to read in hex data.
+ To read in binary data, use pstm_read_unsigned_bin().
- @param[in] pool Memory pool
- @param[out] a Big integer to load data into.
- @param[in] buf ASCII buffer containing 'len' bytes of data to read.
- @param[in] len Number of bytes to read from 'buf'.
- @param[in] radix Base of data in each byte of buf. Typically 16.
- @return < 0 on failure
-*/
+ @param[in] pool Memory pool
+ @param[out] a Big integer to load data into.
+ @param[in] buf ASCII buffer containing 'len' bytes of data to read.
+ @param[in] len Number of bytes to read from 'buf'.
+ @param[in] radix Base of data in each byte of buf. Typically 16.
+ @return < 0 on failure
+ */
int32_t pstm_read_radix(psPool_t *pool, pstm_int *a,
- const char *buf, uint16_t len, uint8_t radix)
+ const char *buf, psSize_t len, uint8_t radix)
{
- int32_t y, neg;
- unsigned char ch;
+ int32_t y, neg;
+ unsigned char ch;
- /* make sure the radix is ok */
- if (radix < 2 || radix > 64) {
- return PS_ARG_FAIL;
- }
+ /* make sure the radix is ok */
+ if (radix < 2 || radix > 64)
+ {
+ return PS_ARG_FAIL;
+ }
- /* if the leading digit is a minus set the sign to negative. */
- if (*buf == '-') {
- ++buf; len--;
- neg = PSTM_NEG;
- } else {
- neg = PSTM_ZPOS;
- }
+ /* if the leading digit is a minus set the sign to negative. */
+ if (*buf == '-')
+ {
+ ++buf; len--;
+ neg = PSTM_NEG;
+ }
+ else
+ {
+ neg = PSTM_ZPOS;
+ }
- /* set the integer to the default of zero */
- pstm_zero(a);
+ /* set the integer to the default of zero */
+ pstm_zero(a);
- /* process each digit of the string */
- while (len > 0) {
- /*
- if the radix < 36 the conversion is case insensitive this allows
- numbers like 1AB and 1ab to represent the same value [e.g. in hex].
- */
- ch = ((radix < 36) ?
- (unsigned char)toupper((unsigned char)*buf) :
- (unsigned char)*buf);
- for (y = 0; y < 64; y++) {
- if (ch == pstm_s_rmap[y]) {
- break;
- }
- }
+ /* process each digit of the string */
+ while (len > 0)
+ {
+ /*
+ if the radix < 36 the conversion is case insensitive this allows
+ numbers like 1AB and 1ab to represent the same value [e.g. in hex].
+ */
+ ch = ((radix < 36) ?
+ (unsigned char) toupper((unsigned char) *buf) :
+ (unsigned char) *buf);
+ for (y = 0; y < 64; y++)
+ {
+ if (ch == pstm_s_rmap[y])
+ {
+ break;
+ }
+ }
- /*
- if the char was found in the map and is less than the given
- radix, add it to the number, otherwise exit the loop.
- */
- if (y < radix) {
- pstm_mul_d (a, (pstm_digit) radix, a);
- pstm_add_d (pool, a, (pstm_digit) y, a);
- } else {
- break;
- }
- ++buf; len--;
- }
+ /*
+ if the char was found in the map and is less than the given
+ radix, add it to the number, otherwise exit the loop.
+ */
+ if (y < radix)
+ {
+ pstm_mul_d(a, (pstm_digit) radix, a);
+ pstm_add_d(pool, a, (pstm_digit) y, a);
+ }
+ else
+ {
+ break;
+ }
+ ++buf; len--;
+ }
- /* set the sign only if a != 0 */
- if (pstm_iszero(a) != PS_TRUE) {
- a->sign = neg;
- }
- return PS_SUCCESS;
+ /* set the sign only if a != 0 */
+ if (pstm_iszero(a) != PS_TRUE)
+ {
+ a->sign = neg;
+ }
+ return PS_SUCCESS;
}
-#endif /* USE_ECC */
+# endif /* USE_ECC */
/******************************************************************************/
-uint16_t pstm_count_bits(const pstm_int * a)
+uint16_t pstm_count_bits(const pstm_int *a)
{
- int16 r;
- pstm_digit q;
+ int16 r;
+ pstm_digit q;
- if (a->used == 0) {
- return 0;
- }
+ if (a->used == 0)
+ {
+ return 0;
+ }
- /* get number of digits and add that */
- r = (a->used - 1) * DIGIT_BIT;
+ /* get number of digits and add that */
+ r = (a->used - 1) * DIGIT_BIT;
- /* take the last digit and count the bits in it */
- q = a->dp[a->used - 1];
- while (q > ((pstm_digit) 0)) {
- ++r;
- q >>= ((pstm_digit) 1);
- }
- return r;
+ /* take the last digit and count the bits in it */
+ q = a->dp[a->used - 1];
+ while (q > ((pstm_digit) 0))
+ {
+ ++r;
+ q >>= ((pstm_digit) 1);
+ }
+ return r;
}
/******************************************************************************/
uint16_t pstm_unsigned_bin_size(const pstm_int *a)
{
- uint16_t size = pstm_count_bits (a);
- return (size / 8 + ((size & 7) != 0 ? 1 : 0));
+ psSize_t size = pstm_count_bits(a);
+
+ return size / 8 + ((size & 7) != 0 ? 1 : 0);
}
/******************************************************************************/
/**
- a = b, where b is a single digit.
-*/
+ a = b, where b is a single digit.
+ */
void pstm_set(pstm_int *a, pstm_digit b)
{
- pstm_zero(a);
- a->dp[0] = b;
- a->used = a->dp[0] ? 1 : 0;
+ pstm_zero(a);
+ a->dp[0] = b;
+ a->used = a->dp[0] ? 1 : 0;
}
/******************************************************************************/
/**
- Right shift 'a' by 'b' digits.
- @note This is not a bit shift.
-*/
+ Right shift 'a' by 'b' digits.
+ @note This is not a bit shift.
+ */
void pstm_rshd(pstm_int *a, uint16_t b)
{
- uint16_t y;
+ uint16_t y;
- /* too many digits just zero and return */
- if (b >= a->used) {
- pstm_zero(a);
- return;
- }
- /* shift */
- for (y = 0; y < a->used - b; y++) {
- a->dp[y] = a->dp[y + b];
- }
- /* zero the rest */
- for (; y < a->used; y++) {
- a->dp[y] = 0;
- }
- /* decrement count */
- a->used -= b;
- pstm_clamp(a);
+ /* too many digits just zero and return */
+ if (b >= a->used)
+ {
+ pstm_zero(a);
+ return;
+ }
+ /* shift */
+ for (y = 0; y < a->used - b; y++)
+ {
+ a->dp[y] = a->dp[y + b];
+ }
+ /* zero the rest */
+ for (; y < a->used; y++)
+ {
+ a->dp[y] = 0;
+ }
+ /* decrement count */
+ a->used -= b;
+ pstm_clamp(a);
}
/******************************************************************************/
/**
- Left shift 'a' by 'b' digits.
- This will grow 'a', and possibly cause a reallocation of memory.
- @note This is not a bit shift.
-*/
+ Left shift 'a' by 'b' digits.
+ This will grow 'a', and possibly cause a reallocation of memory.
+ @note This is not a bit shift.
+ */
int32_t pstm_lshd(pstm_int *a, uint16_t b)
{
- uint16_t x;
- int32_t res;
+ uint16_t x;
+ int32_t res;
- /* If its less than zero return. */
- if (b <= 0) {
- return PSTM_OKAY;
- }
- /* Grow to fit the new digits. */
- if (a->alloc < a->used + b) {
- if ((res = pstm_grow(a, a->used + b)) != PSTM_OKAY) {
- return res;
- }
- }
+ /* If its less than zero return. */
+ if (b <= 0)
+ {
+ return PSTM_OKAY;
+ }
+ /* Grow to fit the new digits. */
+ if (a->alloc < a->used + b)
+ {
+ if ((res = pstm_grow(a, a->used + b)) != PSTM_OKAY)
+ {
+ return res;
+ }
+ }
- {
- register pstm_digit *top, *bottom;
- /* Increment the used by the shift amount then copy upwards. */
- a->used += b;
- /* top */
- top = a->dp + a->used - 1;
- /* base */
- bottom = a->dp + a->used - 1 - b;
+ {
+ register pstm_digit *top, *bottom;
+ /* Increment the used by the shift amount then copy upwards. */
+ a->used += b;
+ /* top */
+ top = a->dp + a->used - 1;
+ /* base */
+ bottom = a->dp + a->used - 1 - b;
/*
- This is implemented using a sliding window except the window goes the
- other way around. Copying from the bottom to the top.
+ This is implemented using a sliding window except the window goes the
+ other way around. Copying from the bottom to the top.
*/
- for (x = a->used - 1; x >= b; x--) {
- *top-- = *bottom--;
- }
- /* zero the lower digits */
- top = a->dp;
- for (x = 0; x < b; x++) {
- *top++ = 0;
- }
- }
- return PSTM_OKAY;
+ for (x = a->used - 1; x >= b; x--)
+ {
+ *top-- = *bottom--;
+ }
+ /* zero the lower digits */
+ top = a->dp;
+ for (x = 0; x < b; x++)
+ {
+ *top++ = 0;
+ }
+ }
+ return PSTM_OKAY;
}
/******************************************************************************/
/**
- a = 2**b.
-*/
+ a = 2**b.
+ */
int32_t pstm_2expt(pstm_int *a, int16_t b)
{
- uint16_t z;
+ uint16_t z;
- /* zero a as per default */
- pstm_zero (a);
+ /* zero a as per default */
+ pstm_zero(a);
- if (b < 0) {
- return PSTM_OKAY;
- }
+ if (b < 0)
+ {
+ return PSTM_OKAY;
+ }
- z = b / DIGIT_BIT;
- if (z >= PSTM_MAX_SIZE) {
- return PS_LIMIT_FAIL;
- }
+ z = b / DIGIT_BIT;
+ if (z >= PSTM_MAX_SIZE)
+ {
+ return PS_LIMIT_FAIL;
+ }
- /* set the used count of where the bit will go */
- a->used = z + 1;
+ /* set the used count of where the bit will go */
+ a->used = z + 1;
- if (a->used > a->alloc) {
- if (pstm_grow(a, a->used) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- }
+ if (a->used > a->alloc)
+ {
+ if (pstm_grow(a, a->used) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ }
- /* put the single bit in its place */
- a->dp[z] = ((pstm_digit)1) << (b % DIGIT_BIT);
- return PSTM_OKAY;
+ /* put the single bit in its place */
+ a->dp[z] = ((pstm_digit) 1) << (b % DIGIT_BIT);
+ return PSTM_OKAY;
}
/******************************************************************************/
/**
- b = a * 2.
- Implements multiplication as a left shift of all digits of 1 bit.
-*/
-int32_t pstm_mul_2(const pstm_int *a, pstm_int * b)
+ b = a * 2.
+ Implements multiplication as a left shift of all digits of 1 bit.
+ */
+int32_t pstm_mul_2(const pstm_int *a, pstm_int *b)
{
- int32 res;
- int16 x, oldused;
+ int32 res;
+ int16 x, oldused;
- /* grow to accomodate result */
- if (b->alloc < a->used + 1) {
- if ((res = pstm_grow (b, a->used + 1)) != PSTM_OKAY) {
- return res;
- }
- }
- oldused = b->used;
- b->used = a->used;
+ /* grow to accomodate result */
+ if (b->alloc < a->used + 1)
+ {
+ if ((res = pstm_grow(b, a->used + 1)) != PSTM_OKAY)
+ {
+ return res;
+ }
+ }
+ oldused = b->used;
+ b->used = a->used;
- {
- register pstm_digit r, rr, *tmpa, *tmpb;
+ {
+ register pstm_digit r, rr, *tmpa, *tmpb;
- /* alias for source */
- tmpa = a->dp;
+ /* alias for source */
+ tmpa = a->dp;
- /* alias for dest */
- tmpb = b->dp;
+ /* alias for dest */
+ tmpb = b->dp;
- /* carry */
- r = 0;
- for (x = 0; x < a->used; x++) {
+ /* carry */
+ r = 0;
+ for (x = 0; x < a->used; x++)
+ {
/*
- get what will be the *next* carry bit from the
- MSB of the current digit
-*/
- rr = *tmpa >> ((pstm_digit)(DIGIT_BIT - 1));
- /* now shift up this digit, add in the carry [from the previous] */
- *tmpb++ = ((*tmpa++ << ((pstm_digit)1)) | r);
+ get what will be the *next* carry bit from the
+ MSB of the current digit
+ */
+ rr = *tmpa >> ((pstm_digit) (DIGIT_BIT - 1));
+ /* now shift up this digit, add in the carry [from the previous] */
+ *tmpb++ = ((*tmpa++ << ((pstm_digit) 1)) | r);
/*
- copy the carry that would be from the source
- digit into the next iteration
-*/
- r = rr;
- }
+ copy the carry that would be from the source
+ digit into the next iteration
+ */
+ r = rr;
+ }
- /* new leading digit? */
- if (r != 0 && b->used != (PSTM_MAX_SIZE-1)) {
- /* add a MSB which is always 1 at this point */
- *tmpb = 1;
- ++(b->used);
- }
- /* now zero any excess digits on the destination that we didn't write to */
- tmpb = b->dp + b->used;
- for (x = b->used; x < oldused; x++) {
- *tmpb++ = 0;
- }
- }
- b->sign = a->sign;
- return PSTM_OKAY;
+ /* new leading digit? */
+ if (r != 0 && b->used != (PSTM_MAX_SIZE - 1))
+ {
+ /* add a MSB which is always 1 at this point */
+ *tmpb = 1;
+ ++(b->used);
+ }
+ /* now zero any excess digits on the destination that we didn't write to */
+ tmpb = b->dp + b->used;
+ for (x = b->used; x < oldused; x++)
+ {
+ *tmpb++ = 0;
+ }
+ }
+ b->sign = a->sign;
+ return PSTM_OKAY;
}
/******************************************************************************/
/**
- unsigned subtraction ||a|| must be >= ||b|| ALWAYS.
- c = a - b.
-*/
-int32_t s_pstm_sub(const pstm_int *a, const pstm_int *b, pstm_int *c)
+ unsigned subtraction ||a|| must be >= ||b|| ALWAYS.
+ c = a - b.
+ */
+int32_t pstm_sub_s(const pstm_int *a, const pstm_int *b, pstm_int *c)
{
- int16 oldbused, oldused;
- int32 x;
- pstm_word t;
+ int16 oldbused, oldused;
+ int32 x;
+ pstm_word t;
- if (b->used > a->used) {
- return PS_LIMIT_FAIL;
- }
- if (c->alloc < a->used) {
- if ((x = pstm_grow(c, a->used)) != PSTM_OKAY) {
- return x;
- }
- }
- oldused = c->used;
- oldbused = b->used;
- c->used = a->used;
- t = 0;
- for (x = 0; x < oldbused; x++) {
- t = ((pstm_word)a->dp[x]) - (((pstm_word)b->dp[x]) + t);
- c->dp[x] = (pstm_digit)t;
- t = (t >> DIGIT_BIT) & 1;
- }
- for (; x < a->used; x++) {
- t = ((pstm_word)a->dp[x]) - t;
- c->dp[x] = (pstm_digit)t;
- t = (t >> DIGIT_BIT);
- }
- for (; x < oldused; x++) {
- c->dp[x] = 0;
- }
- pstm_clamp(c);
- return PSTM_OKAY;
+ if (b->used > a->used)
+ {
+ return PS_LIMIT_FAIL;
+ }
+ if (c->alloc < a->used)
+ {
+ if ((x = pstm_grow(c, a->used)) != PSTM_OKAY)
+ {
+ return x;
+ }
+ }
+ oldused = c->used;
+ oldbused = b->used;
+ c->used = a->used;
+ t = 0;
+ for (x = 0; x < oldbused; x++)
+ {
+ t = ((pstm_word) a->dp[x]) - (((pstm_word) b->dp[x]) + t);
+ c->dp[x] = (pstm_digit) t;
+ t = (t >> DIGIT_BIT) & 1;
+ }
+ for (; x < a->used; x++)
+ {
+ t = ((pstm_word) a->dp[x]) - t;
+ c->dp[x] = (pstm_digit) t;
+ t = (t >> DIGIT_BIT);
+ }
+ for (; x < oldused; x++)
+ {
+ c->dp[x] = 0;
+ }
+ pstm_clamp(c);
+ return PSTM_OKAY;
}
/******************************************************************************/
/**
- Unsigned addition of two big integers.
- c = a + b;
- @param[in] pool Memory pool
- @param[in] a Big integer operand
- @param[in] b Big integer operand
- @param[out] c Big integer result
- @return < 0 on failure
-*/
+ Unsigned addition of two big integers.
+ c = a + b;
+ @param[in] pool Memory pool
+ @param[in] a Big integer operand
+ @param[in] b Big integer operand
+ @param[out] c Big integer result
+ @return < 0 on failure
+ */
static int32_t s_pstm_add(const pstm_int *a, const pstm_int *b, pstm_int *c)
{
- int16 x, y, oldused;
- register pstm_word t, adp, bdp;
+ int16 x, y, oldused;
+ register pstm_word t, adp, bdp;
- y = a->used;
- if (b->used > y) {
- y = b->used;
- }
- oldused = c->used;
- c->used = y;
+ y = a->used;
+ if (b->used > y)
+ {
+ y = b->used;
+ }
+ oldused = c->used;
+ c->used = y;
- if (c->used > c->alloc) {
- if (pstm_grow(c, c->used) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- }
+ if (c->used > c->alloc)
+ {
+ if (pstm_grow(c, c->used) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ }
- t = 0;
- for (x = 0; x < y; x++) {
- if (a->used <= x) {
- adp = 0;
- } else {
- adp = (pstm_word)a->dp[x];
- }
- if (b->used <= x) {
- bdp = 0;
- } else {
- bdp = (pstm_word)b->dp[x];
- }
- t += (adp) + (bdp);
- c->dp[x] = (pstm_digit)t;
- t >>= DIGIT_BIT;
- }
- if (t != 0 && x < PSTM_MAX_SIZE) {
- if (c->used == c->alloc) {
- if (pstm_grow(c, c->alloc + 1) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- }
- c->dp[c->used++] = (pstm_digit)t;
- ++x;
- }
+ t = 0;
+ for (x = 0; x < y; x++)
+ {
+ if (a->used <= x)
+ {
+ adp = 0;
+ }
+ else
+ {
+ adp = (pstm_word) a->dp[x];
+ }
+ if (b->used <= x)
+ {
+ bdp = 0;
+ }
+ else
+ {
+ bdp = (pstm_word) b->dp[x];
+ }
+ t += (adp) + (bdp);
+ c->dp[x] = (pstm_digit) t;
+ t >>= DIGIT_BIT;
+ }
+ if (t != 0 && x < PSTM_MAX_SIZE)
+ {
+ if (c->used == c->alloc)
+ {
+ if (pstm_grow(c, c->alloc + 1) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ }
+ c->dp[c->used++] = (pstm_digit) t;
+ ++x;
+ }
- c->used = x;
- for (; x < oldused; x++) {
- c->dp[x] = 0;
- }
- pstm_clamp(c);
- return PSTM_OKAY;
+ c->used = x;
+ for (; x < oldused; x++)
+ {
+ c->dp[x] = 0;
+ }
+ pstm_clamp(c);
+ return PSTM_OKAY;
}
/******************************************************************************/
/**
- Signed subtraction. a and b can be any value.
- c = a - b.
-*/
+ Signed subtraction. a and b can be any value.
+ c = a - b.
+ */
int32_t pstm_sub(const pstm_int *a, const pstm_int *b, pstm_int *c)
{
- int32 res;
- int16 sa, sb;
+ int32 res;
+ int16 sa, sb;
- sa = a->sign;
- sb = b->sign;
+ sa = a->sign;
+ sb = b->sign;
- if (sa != sb) {
+ if (sa != sb)
+ {
/*
- subtract a negative from a positive, OR a positive from a negative.
- For both, ADD their magnitudes, and use the sign of the first number.
+ subtract a negative from a positive, OR a positive from a negative.
+ For both, ADD their magnitudes, and use the sign of the first number.
*/
- c->sign = sa;
- if ((res = s_pstm_add (a, b, c)) != PSTM_OKAY) {
- return res;
- }
- } else {
+ c->sign = sa;
+ if ((res = s_pstm_add(a, b, c)) != PSTM_OKAY)
+ {
+ return res;
+ }
+ }
+ else
+ {
/*
- subtract a positive from a positive, OR a negative from a negative.
- First, take the difference between their magnitudes, then...
+ subtract a positive from a positive, OR a negative from a negative.
+ First, take the difference between their magnitudes, then...
*/
- if (pstm_cmp_mag (a, b) != PSTM_LT) {
- /* Copy the sign from the first */
- c->sign = sa;
- /* The first has a larger or equal magnitude */
- if ((res = s_pstm_sub (a, b, c)) != PSTM_OKAY) {
- return res;
- }
- } else {
- /* The result has the _opposite_ sign from the first number. */
- c->sign = (sa == PSTM_ZPOS) ? PSTM_NEG : PSTM_ZPOS;
- /* The second has a larger magnitude */
- if ((res = s_pstm_sub (b, a, c)) != PSTM_OKAY) {
- return res;
- }
- }
- }
- return PS_SUCCESS;
+ if (pstm_cmp_mag(a, b) != PSTM_LT)
+ {
+ /* Copy the sign from the first */
+ c->sign = sa;
+ /* The first has a larger or equal magnitude */
+ if ((res = pstm_sub_s(a, b, c)) != PSTM_OKAY)
+ {
+ return res;
+ }
+ }
+ else
+ {
+ /* The result has the _opposite_ sign from the first number. */
+ c->sign = (sa == PSTM_ZPOS) ? PSTM_NEG : PSTM_ZPOS;
+ /* The second has a larger magnitude */
+ if ((res = pstm_sub_s(b, a, c)) != PSTM_OKAY)
+ {
+ return res;
+ }
+ }
+ }
+ return PS_SUCCESS;
}
/******************************************************************************/
/**
- Signed subtraction of a digit.
- c = a - b, where b is a digit
-*/
+ Signed subtraction of a digit.
+ c = a - b, where b is a digit
+ */
int32_t pstm_sub_d(psPool_t *pool, const pstm_int *a, pstm_digit b, pstm_int *c)
{
- pstm_int tmp;
- int32_t res;
+ pstm_int tmp;
+ int32_t res;
- if (pstm_init_size(pool, &tmp, sizeof(pstm_digit)) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- pstm_set(&tmp, b);
- res = pstm_sub(a, &tmp, c);
- pstm_clear(&tmp);
- return res;
+ if (pstm_init_size(pool, &tmp, sizeof(pstm_digit)) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ pstm_set(&tmp, b);
+ res = pstm_sub(a, &tmp, c);
+ pstm_clear(&tmp);
+ return res;
}
/******************************************************************************/
/**
- Sets up the montgomery reduction.
- Fast inversion mod 2**k
- Based on the fact that
- XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n)
- => 2*X*A - X*X*A*A = 1
- => 2*(1) - (1) = 1
- @param[in] a
- @param[out] rho
-*/
+ Sets up the montgomery reduction.
+ Fast inversion mod 2**k
+ Based on the fact that
+ XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n)
+ => 2*X*A - X*X*A*A = 1
+ => 2*(1) - (1) = 1
+ @param[in] a
+ @param[out] rho
+ */
int32_t pstm_montgomery_setup(const pstm_int *a, pstm_digit *rho)
{
- pstm_digit x, b;
+ pstm_digit x, b;
- b = a->dp[0];
+ b = a->dp[0];
- if ((b & 1) == 0) {
- psTraceCrypto("pstm_montogomery_setup failure\n");
- return PS_ARG_FAIL;
- }
+ if ((b & 1) == 0)
+ {
+ psTraceCrypto("pstm_montogomery_setup failure\n");
+ return PS_ARG_FAIL;
+ }
- x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
- x *= 2 - b * x; /* here x*a==1 mod 2**8 */
- x *= 2 - b * x; /* here x*a==1 mod 2**16 */
- x *= 2 - b * x; /* here x*a==1 mod 2**32 */
-#ifdef PSTM_64BIT
- x *= 2 - b * x; /* here x*a==1 mod 2**64 */
-#endif
- /* rho = -1/m mod b */
- *rho = (pstm_digit)(((pstm_word) 1 << ((pstm_word) DIGIT_BIT)) -
- ((pstm_word)x));
- return PSTM_OKAY;
+ x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
+ x *= 2 - b * x; /* here x*a==1 mod 2**8 */
+ x *= 2 - b * x; /* here x*a==1 mod 2**16 */
+ x *= 2 - b * x; /* here x*a==1 mod 2**32 */
+# ifdef PSTM_64BIT
+ x *= 2 - b * x; /* here x*a==1 mod 2**64 */
+# endif
+ /* rho = -1/m mod b */
+ *rho = (pstm_digit) (((pstm_word) 1 << ((pstm_word) DIGIT_BIT)) -
+ ((pstm_word) x));
+ return PSTM_OKAY;
}
/******************************************************************************/
/**
- a = B**n mod b, without division or multiplication.
- Useful for normalizing numbers in a Montgomery system.
+ a = B**n mod b, without division or multiplication.
+ Useful for normalizing numbers in a Montgomery system.
*/
int32_t pstm_montgomery_calc_normalization(pstm_int *a, const pstm_int *b)
{
- uint16_t x, bits;
+ uint16_t x, bits;
- /* how many bits of last digit does b use */
- bits = pstm_count_bits(b) % DIGIT_BIT;
- if (!bits) bits = DIGIT_BIT;
+ /* how many bits of last digit does b use */
+ bits = pstm_count_bits(b) % DIGIT_BIT;
+ if (!bits)
+ {
+ bits = DIGIT_BIT;
+ }
- /* compute A = B^(n-1) * 2^(bits-1) */
- if (b->used > 1) {
- if ((x = pstm_2expt(a, (b->used - 1) * DIGIT_BIT + bits - 1)) !=
- PSTM_OKAY) {
- return x;
- }
- } else {
- pstm_set(a, 1);
- bits = 1;
- }
- /* now compute C = A * B mod b */
- for (x = bits - 1; x < (uint16_t)DIGIT_BIT; x++) {
- if (pstm_mul_2 (a, a) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- if (pstm_cmp_mag (a, b) != PSTM_LT) {
- if (s_pstm_sub (a, b, a) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- }
- }
- return PSTM_OKAY;
+ /* compute A = B^(n-1) * 2^(bits-1) */
+ if (b->used > 1)
+ {
+ if ((x = pstm_2expt(a, (b->used - 1) * DIGIT_BIT + bits - 1)) !=
+ PSTM_OKAY)
+ {
+ return x;
+ }
+ }
+ else
+ {
+ pstm_set(a, 1);
+ bits = 1;
+ }
+ /* now compute C = A * B mod b */
+ for (x = bits - 1; x < (uint16_t) DIGIT_BIT; x++)
+ {
+ if (pstm_mul_2(a, a) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ if (pstm_cmp_mag(a, b) != PSTM_LT)
+ {
+ if (pstm_sub_s(a, b, a) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ }
+ }
+ return PSTM_OKAY;
}
/******************************************************************************/
/*
- c = a * 2**d
-*/
+ c = a * 2**d
+ */
static int32_t pstm_mul_2d(const pstm_int *a, int16_t b, pstm_int *c)
{
- pstm_digit carry, carrytmp, shift;
- uint16_t x;
+ pstm_digit carry, carrytmp, shift;
+ uint16_t x;
- /* copy it */
- if (pstm_copy(a, c) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
+ /* copy it */
+ if (pstm_copy(a, c) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
- /* handle whole digits */
- if (b >= DIGIT_BIT) {
- if (pstm_lshd(c, b/DIGIT_BIT) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- }
- b %= DIGIT_BIT;
+ /* handle whole digits */
+ if (b >= DIGIT_BIT)
+ {
+ if (pstm_lshd(c, b / DIGIT_BIT) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ }
+ b %= DIGIT_BIT;
- /* shift the digits */
- if (b != 0) {
- carry = 0;
- shift = DIGIT_BIT - b;
- for (x = 0; x < c->used; x++) {
- carrytmp = c->dp[x] >> shift;
- c->dp[x] = (c->dp[x] << b) + carry;
- carry = carrytmp;
- }
- /* store last carry if room */
- if (carry && x < PSTM_MAX_SIZE) {
- if (c->used == c->alloc) {
- if (pstm_grow(c, c->alloc + 1) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- }
- c->dp[c->used++] = carry;
- }
- }
- pstm_clamp(c);
- return PSTM_OKAY;
+ /* shift the digits */
+ if (b != 0)
+ {
+ carry = 0;
+ shift = DIGIT_BIT - b;
+ for (x = 0; x < c->used; x++)
+ {
+ carrytmp = c->dp[x] >> shift;
+ c->dp[x] = (c->dp[x] << b) + carry;
+ carry = carrytmp;
+ }
+ /* store last carry if room */
+ if (carry && x < PSTM_MAX_SIZE)
+ {
+ if (c->used == c->alloc)
+ {
+ if (pstm_grow(c, c->alloc + 1) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ }
+ c->dp[c->used++] = carry;
+ }
+ }
+ pstm_clamp(c);
+ return PSTM_OKAY;
}
/******************************************************************************/
/*
- c = a mod 2**b
-*/
+ c = a mod 2**b
+ */
static int32_t pstm_mod_2d(const pstm_int *a, int16_t b, pstm_int *c)
{
- uint16_t x;
+ uint16_t x;
- /* zero if count less than or equal to zero */
- if (b <= 0) {
- pstm_zero(c);
- return PSTM_OKAY;
- }
+ /* zero if count less than or equal to zero */
+ if (b <= 0)
+ {
+ pstm_zero(c);
+ return PSTM_OKAY;
+ }
- /* get copy of input */
- if (pstm_copy(a, c) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
+ /* get copy of input */
+ if (pstm_copy(a, c) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
- /* if 2**d is larger than we just return */
- if (b >= (DIGIT_BIT * a->used)) {
- return PSTM_OKAY;
- }
+ /* if 2**d is larger than we just return */
+ if (b >= (DIGIT_BIT * a->used))
+ {
+ return PSTM_OKAY;
+ }
- /* zero digits above the last digit of the modulus */
- for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++)
- {
- c->dp[x] = 0;
- }
- /* clear the digit that is not completely outside/inside the modulus */
- c->dp[b / DIGIT_BIT] &= ~((pstm_digit)0) >> (DIGIT_BIT - b);
- pstm_clamp (c);
- return PSTM_OKAY;
+ /* zero digits above the last digit of the modulus */
+ for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++)
+ {
+ c->dp[x] = 0;
+ }
+ /* clear the digit that is not completely outside/inside the modulus */
+ c->dp[b / DIGIT_BIT] &= ~((pstm_digit) 0) >> (DIGIT_BIT - b);
+ pstm_clamp(c);
+ return PSTM_OKAY;
}
/******************************************************************************/
/*
- c = a * b
-*/
+ c = a * b
+ */
int32_t pstm_mul_d(const pstm_int *a, const pstm_digit b, pstm_int *c)
{
- pstm_word w;
- int32 res;
- int16 x, oldused;
+ pstm_word w;
+ int32 res;
+ int16 x, oldused;
- if (c->alloc < a->used + 1) {
- if ((res = pstm_grow (c, a->used + 1)) != PSTM_OKAY) {
- return res;
- }
- }
- oldused = c->used;
- c->used = a->used;
- c->sign = a->sign;
- w = 0;
- for (x = 0; x < a->used; x++) {
- w = ((pstm_word)a->dp[x]) * ((pstm_word)b) + w;
- c->dp[x] = (pstm_digit)w;
- w = w >> DIGIT_BIT;
- }
- if (w != 0 && (a->used != PSTM_MAX_SIZE)) {
- c->dp[c->used++] = (pstm_digit)w;
- ++x;
- }
- for (; x < oldused; x++) {
- c->dp[x] = 0;
- }
- pstm_clamp(c);
- return PSTM_OKAY;
+ if (c->alloc < a->used + 1)
+ {
+ if ((res = pstm_grow(c, a->used + 1)) != PSTM_OKAY)
+ {
+ return res;
+ }
+ }
+ oldused = c->used;
+ c->used = a->used;
+ c->sign = a->sign;
+ w = 0;
+ for (x = 0; x < a->used; x++)
+ {
+ w = ((pstm_word) a->dp[x]) * ((pstm_word) b) + w;
+ c->dp[x] = (pstm_digit) w;
+ w = w >> DIGIT_BIT;
+ }
+ if (w != 0 && (a->used != PSTM_MAX_SIZE))
+ {
+ c->dp[c->used++] = (pstm_digit) w;
+ ++x;
+ }
+ for (; x < oldused; x++)
+ {
+ c->dp[x] = 0;
+ }
+ pstm_clamp(c);
+ return PSTM_OKAY;
}
/******************************************************************************/
/**
- c = a / 2**b, d = remainder.
- @param[in] pool Memory pool
- @param[in] a Numerator
- @param[in] b Exponent of the denominator
- @param[out] c The result
- @param[out] d If non-NULL, the remainder of the division is stored here
- @return < 0 on failure
-*/
+ c = a / 2**b, d = remainder.
+ @param[in] pool Memory pool
+ @param[in] a Numerator
+ @param[in] b Exponent of the denominator
+ @param[out] c The result
+ @param[out] d If non-NULL, the remainder of the division is stored here
+ @return < 0 on failure
+ */
int32_t pstm_div_2d(psPool_t *pool, const pstm_int *a, int16_t b, pstm_int *c,
- pstm_int *d)
+ pstm_int *d)
{
- pstm_digit D, r, rr;
- int32 res;
- int16 x;
+ pstm_digit D, r, rr;
+ int32 res;
+ int16 x;
- /* if the shift count is <= 0 then we do no work */
- if (b <= 0) {
- if (pstm_copy (a, c) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- if (d != NULL) {
- pstm_zero (d);
- }
- return PSTM_OKAY;
- }
- /* copy */
- if (pstm_copy(a, c) != PSTM_OKAY) {
- res = PS_MEM_FAIL;
- goto LBL_DONE;
- }
+ /* if the shift count is <= 0 then we do no work */
+ if (b <= 0)
+ {
+ if (pstm_copy(a, c) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ if (d != NULL)
+ {
+ pstm_zero(d);
+ }
+ return PSTM_OKAY;
+ }
+ /* copy */
+ if (pstm_copy(a, c) != PSTM_OKAY)
+ {
+ res = PS_MEM_FAIL;
+ goto LBL_DONE;
+ }
- /* shift by as many digits in the bit count */
- if (b >= (int16_t)DIGIT_BIT) {
- pstm_rshd (c, b / DIGIT_BIT);
- }
+ /* shift by as many digits in the bit count */
+ if (b >= (int16_t) DIGIT_BIT)
+ {
+ pstm_rshd(c, b / DIGIT_BIT);
+ }
- /* shift any bit count < DIGIT_BIT */
- D = (pstm_digit) (b % DIGIT_BIT);
- if (D != 0) {
- register pstm_digit *tmpc, mask, shift;
+ /* shift any bit count < DIGIT_BIT */
+ D = (pstm_digit) (b % DIGIT_BIT);
+ if (D != 0)
+ {
+ register pstm_digit *tmpc, mask, shift;
- /* mask */
- mask = (((pstm_digit)1) << D) - 1;
+ /* mask */
+ mask = (((pstm_digit) 1) << D) - 1;
- /* shift for lsb */
- shift = DIGIT_BIT - D;
+ /* shift for lsb */
+ shift = DIGIT_BIT - D;
- /* alias */
- tmpc = c->dp + (c->used - 1);
+ /* alias */
+ tmpc = c->dp + (c->used - 1);
- /* carry */
- r = 0;
- for (x = c->used - 1; x >= 0; x--) {
- /* get the lower bits of this word in a temp */
- rr = *tmpc & mask;
+ /* carry */
+ r = 0;
+ for (x = c->used - 1; x >= 0; x--)
+ {
+ /* get the lower bits of this word in a temp */
+ rr = *tmpc & mask;
- /* shift the current word and mix in the carry bits from previous */
- *tmpc = (*tmpc >> D) | (r << shift);
- --tmpc;
+ /* shift the current word and mix in the carry bits from previous */
+ *tmpc = (*tmpc >> D) | (r << shift);
+ --tmpc;
- /* set the carry to the carry bits of the current word above */
- r = rr;
- }
- }
- pstm_clamp (c);
+ /* set the carry to the carry bits of the current word above */
+ r = rr;
+ }
+ }
+ pstm_clamp(c);
- res = PSTM_OKAY;
+ res = PSTM_OKAY;
LBL_DONE:
- /* set the remainder */
- if (d != NULL) {
- if (pstm_mod_2d(a, b, d) != PSTM_OKAY) {
- res = PS_MEM_FAIL;
- }
- }
- return res;
+ /* set the remainder */
+ if (d != NULL)
+ {
+ if (pstm_mod_2d(a, b, d) != PSTM_OKAY)
+ {
+ res = PS_MEM_FAIL;
+ }
+ }
+ return res;
}
/******************************************************************************/
/**
- b = a / 2.
- Implemented as a right shift of one bit.
-*/
+ b = a / 2.
+ Implemented as a right shift of one bit.
+ */
int32_t pstm_div_2(const pstm_int *a, pstm_int *b)
{
- int16 x, oldused;
+ int16 x, oldused;
- if (b->alloc < a->used) {
- if (pstm_grow(b, a->used) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- }
- oldused = b->used;
- b->used = a->used;
- {
- register pstm_digit r, rr, *tmpa, *tmpb;
+ if (b->alloc < a->used)
+ {
+ if (pstm_grow(b, a->used) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ }
+ oldused = b->used;
+ b->used = a->used;
+ {
+ register pstm_digit r, rr, *tmpa, *tmpb;
- /* source alias */
- tmpa = a->dp + b->used - 1;
+ /* source alias */
+ tmpa = a->dp + b->used - 1;
- /* dest alias */
- tmpb = b->dp + b->used - 1;
+ /* dest alias */
+ tmpb = b->dp + b->used - 1;
- /* carry */
- r = 0;
- for (x = b->used - 1; x >= 0; x--) {
- /* get the carry for the next iteration */
- rr = *tmpa & 1;
+ /* carry */
+ r = 0;
+ for (x = b->used - 1; x >= 0; x--)
+ {
+ /* get the carry for the next iteration */
+ rr = *tmpa & 1;
- /* shift the current digit, add in carry and store */
- *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
+ /* shift the current digit, add in carry and store */
+ *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
- /* forward carry to next iteration */
- r = rr;
- }
+ /* forward carry to next iteration */
+ r = rr;
+ }
- /* zero excess digits */
- tmpb = b->dp + b->used;
- for (x = b->used; x < oldused; x++) {
- *tmpb++ = 0;
- }
- }
- b->sign = a->sign;
- pstm_clamp (b);
- return PSTM_OKAY;
+ /* zero excess digits */
+ tmpb = b->dp + b->used;
+ for (x = b->used; x < oldused; x++)
+ {
+ *tmpb++ = 0;
+ }
+ }
+ b->sign = a->sign;
+ pstm_clamp(b);
+ return PSTM_OKAY;
}
/******************************************************************************/
/*
- Creates "a" then copies b into it
+ Creates "a" then copies b into it
*/
int32_t pstm_init_copy(psPool_t *pool, pstm_int *a, const pstm_int *b,
- uint8_t toSqr)
+ uint8_t toSqr)
{
- int32_t res;
- uint16_t x;
+ int32_t res;
+ uint16_t x;
- if (a == b) {
- return PSTM_OKAY;
- }
- x = b->alloc;
+ if (a == b)
+ {
+ return PSTM_OKAY;
+ }
+ x = b->alloc;
- if (toSqr) {
+ if (toSqr)
+ {
/*
- Smart-size: Increasing size of a if b->used is roughly half
- of b->alloc because usage has shown that a lot of these copies
- go on to be squared and need these extra digits
-*/
- if ((b->used * 2) + 2 >= x) {
- x = (b->used * 2) + 3;
- }
- }
- if ((res = pstm_init_size(pool, a, x)) != PSTM_OKAY) {
- return res;
- }
- return pstm_copy(b, a);
+ Smart-size: Increasing size of a if b->used is roughly half
+ of b->alloc because usage has shown that a lot of these copies
+ go on to be squared and need these extra digits
+ */
+ if ((b->used * 2) + 2 >= x)
+ {
+ x = (b->used * 2) + 3;
+ }
+ }
+ if ((res = pstm_init_size(pool, a, x)) != PSTM_OKAY)
+ {
+ return res;
+ }
+ return pstm_copy(b, a);
}
/******************************************************************************/
/*
- With some compilers, we have seen issues linking with the builtin
- 64 bit division routine. The issues with either manifest in a failure
- to find 'udivdi3' at link time, or a runtime invalid instruction fault
- during an RSA operation.
- The routine below divides a 64 bit unsigned int by a 32 bit unsigned int
- explicitly, rather than using the division operation
- The 64 bit result is placed in the 'numerator' parameter
- The 32 bit mod (remainder) of the division is the return parameter
- Based on implementations by:
- Copyright (C) 2003 Bernardo Innocenti
- Copyright (C) 1999 Hewlett-Packard Co
- Copyright (C) 1999 David Mosberger-Tang
-*/
-#if defined(USE_MATRIX_DIV64) && defined(PSTM_32BIT)
+ With some compilers, we have seen issues linking with the builtin
+ 64 bit division routine. The issues with either manifest in a failure
+ to find 'udivdi3' at link time, or a runtime invalid instruction fault
+ during an RSA operation.
+ The routine below divides a 64 bit unsigned int by a 32 bit unsigned int
+ explicitly, rather than using the division operation
+ The 64 bit result is placed in the 'numerator' parameter
+ The 32 bit mod (remainder) of the division is the return parameter
+ Based on implementations by:
+ Copyright (C) 2003 Bernardo Innocenti
+ Copyright (C) 1999 Hewlett-Packard Co
+ Copyright (C) 1999 David Mosberger-Tang
+ */
+# if defined(USE_MATRIX_DIV64) && defined(PSTM_32BIT)
static uint32 psDiv64(uint64 *numerator, uint32 denominator)
{
- uint64 rem = *numerator;
- uint64 b = denominator;
- uint64 res = 0;
- uint64 d = 1;
- uint32 high = rem >> 32;
+ uint64 rem = *numerator;
+ uint64 b = denominator;
+ uint64 res = 0;
+ uint64 d = 1;
+ uint32 high = rem >> 32;
- if (high >= denominator) {
- high /= denominator;
- res = (uint64) high << 32;
- rem -= (uint64) (high * denominator) << 32;
- }
- while ((int64)b > 0 && b < rem) {
- b = b+b;
- d = d+d;
- }
- do {
- if (rem >= b) {
- rem -= b;
- res += d;
- }
- b >>= 1;
- d >>= 1;
- } while (d);
- *numerator = res;
- return rem;
+ if (high >= denominator)
+ {
+ high /= denominator;
+ res = (uint64) high << 32;
+ rem -= (uint64) (high * denominator) << 32;
+ }
+ while ((int64) b > 0 && b < rem)
+ {
+ b = b + b;
+ d = d + d;
+ }
+ do
+ {
+ if (rem >= b)
+ {
+ rem -= b;
+ res += d;
+ }
+ b >>= 1;
+ d >>= 1;
+ }
+ while (d);
+ *numerator = res;
+ return rem;
}
-#endif /* USE_MATRIX_DIV64 */
+# endif /* USE_MATRIX_DIV64 */
-#if defined(USE_MATRIX_DIV128) && defined(PSTM_64BIT)
-typedef unsigned long uint128 __attribute__ ((mode(TI)));
+# if defined(USE_MATRIX_DIV128) && defined(PSTM_64BIT)
+typedef unsigned long uint128 __attribute__ ((mode(TI)));
static uint64 psDiv128(uint128 *numerator, uint64 denominator)
{
- uint128 rem = *numerator;
- uint128 b = denominator;
- uint128 res = 0;
- uint128 d = 1;
- uint64 high = rem >> 64;
+ uint128 rem = *numerator;
+ uint128 b = denominator;
+ uint128 res = 0;
+ uint128 d = 1;
+ uint64 high = rem >> 64;
- if (high >= denominator) {
- high /= denominator;
- res = (uint128) high << 64;
- rem -= (uint128) (high * denominator) << 64;
- }
- while ((uint128)b > 0 && b < rem) {
- b = b+b;
- d = d+d;
- }
- do {
- if (rem >= b) {
- rem -= b;
- res += d;
- }
- b >>= 1;
- d >>= 1;
- } while (d);
- *numerator = res;
- return rem;
+ if (high >= denominator)
+ {
+ high /= denominator;
+ res = (uint128) high << 64;
+ rem -= (uint128) (high * denominator) << 64;
+ }
+ while ((uint128) b > 0 && b < rem)
+ {
+ b = b + b;
+ d = d + d;
+ }
+ do
+ {
+ if (rem >= b)
+ {
+ rem -= b;
+ res += d;
+ }
+ b >>= 1;
+ d >>= 1;
+ }
+ while (d);
+ *numerator = res;
+ return rem;
}
-#endif /* USE_MATRIX_DIV128 */
+# endif /* USE_MATRIX_DIV128 */
-#ifndef PSTM_LARGE_DIV
+# ifndef PSTM_LARGE_DIV
/* This version of division uses short & small function, but offers
bit worse performance than some others. */
int pstm_div(psPool_t *pool, const pstm_int *a, const pstm_int *b,
- pstm_int *c, pstm_int *d)
+ pstm_int *c, pstm_int *d)
{
- pstm_int ta, tb, tq, q;
- int res, n, n2;
+ pstm_int ta, tb, tq, q;
+ int res, n, n2;
- /* is divisor zero ? */
- if (pstm_iszero(b) == PSTM_YES) {
- return PS_LIMIT_FAIL;
- }
+ /* is divisor zero ? */
+ if (pstm_iszero(b) == PSTM_YES)
+ {
+ return PS_LIMIT_FAIL;
+ }
- /* if a < b then q=0, r = a */
- if (pstm_cmp_mag(a, b) == PSTM_LT) {
- if (d != NULL) {
- res = pstm_copy(a, d);
- } else {
- res = PSTM_OKAY;
- }
- if (c != NULL) {
- pstm_zero(c);
- }
- return res;
- }
+ /* if a < b then q=0, r = a */
+ if (pstm_cmp_mag(a, b) == PSTM_LT)
+ {
+ if (d != NULL)
+ {
+ res = pstm_copy(a, d);
+ }
+ else
+ {
+ res = PSTM_OKAY;
+ }
+ if (c != NULL)
+ {
+ pstm_zero(c);
+ }
+ return res;
+ }
- /* init our temps */
- res = pstm_init(pool, &ta);
- if (res != PSTM_OKAY) {
- return res;
- }
- res = pstm_init(pool, &tb);
- if (res != PSTM_OKAY) {
- pstm_clear(&ta);
- return res;
- }
- res = pstm_init(pool, &tq);
- if (res != PSTM_OKAY) {
- pstm_clear(&ta);
- pstm_clear(&tb);
- return res;
- }
- res = pstm_init(pool, &q);
- if (res != PSTM_OKAY) {
- pstm_clear(&ta);
- pstm_clear(&tb);
- pstm_clear(&tq);
- return res;
- }
+ /* init our temps */
+ res = pstm_init(pool, &ta);
+ if (res != PSTM_OKAY)
+ {
+ return res;
+ }
+ res = pstm_init(pool, &tb);
+ if (res != PSTM_OKAY)
+ {
+ pstm_clear(&ta);
+ return res;
+ }
+ res = pstm_init(pool, &tq);
+ if (res != PSTM_OKAY)
+ {
+ pstm_clear(&ta);
+ pstm_clear(&tb);
+ return res;
+ }
+ res = pstm_init(pool, &q);
+ if (res != PSTM_OKAY)
+ {
+ pstm_clear(&ta);
+ pstm_clear(&tb);
+ pstm_clear(&tq);
+ return res;
+ }
- pstm_set(&tq, 1);
- n = pstm_count_bits(a) - pstm_count_bits(b);
- if (((res = pstm_abs(a, &ta)) != PSTM_OKAY) ||
- ((res = pstm_abs(b, &tb)) != PSTM_OKAY) ||
- ((res = pstm_mul_2d(&tb, n, &tb)) != PSTM_OKAY) ||
- ((res = pstm_mul_2d(&tq, n, &tq)) != PSTM_OKAY)) {
- goto LBL_ERR;
- }
+ pstm_set(&tq, 1);
+ n = pstm_count_bits(a) - pstm_count_bits(b);
+ if (((res = pstm_abs(a, &ta)) != PSTM_OKAY) ||
+ ((res = pstm_abs(b, &tb)) != PSTM_OKAY) ||
+ ((res = pstm_mul_2d(&tb, n, &tb)) != PSTM_OKAY) ||
+ ((res = pstm_mul_2d(&tq, n, &tq)) != PSTM_OKAY))
+ {
+ goto LBL_ERR;
+ }
- while (n-- >= 0) {
- if (pstm_cmp(&tb, &ta) != PSTM_GT) {
- if (((res = pstm_sub(&ta, &tb, &ta)) != PSTM_OKAY) ||
- ((res = pstm_add(&q, &tq, &q)) != PSTM_OKAY)) {
- goto LBL_ERR;
- }
- }
- if (((res = pstm_div_2d(pool, &tb, 1, &tb, NULL)) !=
- PSTM_OKAY) ||
- ((res = pstm_div_2d(pool, &tq, 1, &tq, NULL)) !=
- PSTM_OKAY)) {
- goto LBL_ERR;
- }
- }
+ while (n-- >= 0)
+ {
+ if (pstm_cmp(&tb, &ta) != PSTM_GT)
+ {
+ if (((res = pstm_sub(&ta, &tb, &ta)) != PSTM_OKAY) ||
+ ((res = pstm_add(&q, &tq, &q)) != PSTM_OKAY))
+ {
+ goto LBL_ERR;
+ }
+ }
+ if (((res = pstm_div_2d(pool, &tb, 1, &tb, NULL)) !=
+ PSTM_OKAY) ||
+ ((res = pstm_div_2d(pool, &tq, 1, &tq, NULL)) !=
+ PSTM_OKAY))
+ {
+ goto LBL_ERR;
+ }
+ }
- /* now q == quotient and ta == remainder */
- n = a->sign;
- n2 = (a->sign == b->sign) ? PSTM_ZPOS : PSTM_NEG;
- if (c != NULL) {
- pstm_exch(c, &q);
- c->sign = (pstm_iszero(c) == PSTM_YES) ? PSTM_ZPOS : n2;
- }
- if (d != NULL) {
- pstm_exch(d, &ta);
- d->sign = (pstm_iszero(d) == PSTM_YES) ? PSTM_ZPOS : n;
- }
+ /* now q == quotient and ta == remainder */
+ n = a->sign;
+ n2 = (a->sign == b->sign) ? PSTM_ZPOS : PSTM_NEG;
+ if (c != NULL)
+ {
+ pstm_exch(c, &q);
+ c->sign = (pstm_iszero(c) == PSTM_YES) ? PSTM_ZPOS : n2;
+ }
+ if (d != NULL)
+ {
+ pstm_exch(d, &ta);
+ d->sign = (pstm_iszero(d) == PSTM_YES) ? PSTM_ZPOS : n;
+ }
LBL_ERR:
- pstm_clear (&ta);
- pstm_clear (&tb);
- pstm_clear (&tq);
- pstm_clear (&q);
- return res;
+ pstm_clear(&ta);
+ pstm_clear(&tb);
+ pstm_clear(&tq);
+ pstm_clear(&q);
+ return res;
}
-#else /* defined PSTM_LARGE_DIV */
+# else /* defined PSTM_LARGE_DIV */
/* This noticed is accompanied with this function to discourage its use. */
-#warning "This function has been noticed to give wrong results for some inputs."
+# warning "This function has been noticed to give wrong results for some inputs."
/******************************************************************************/
/**
- c = a / b, d = remainder.
+ c = a / b, d = remainder.
- @param[in] pool Memory pool
- @param[in] a Numerator
- @param[in] b Denominator
- @param[out] c The result
- @param[out] d If non-NULL, the remainder of the division is stored here
- @return < 0 on failure
+ @param[in] pool Memory pool
+ @param[in] a Numerator
+ @param[in] b Denominator
+ @param[out] c The result
+ @param[out] d If non-NULL, the remainder of the division is stored here
+ @return < 0 on failure
- a/b => cb + d == a
-*/
-int32_t pstm_div(psPool_t *pool, const pstm_int *a, const pstm_int *b,
- pstm_int *c, pstm_int *d)
-{
- pstm_int q, x, y, t1, t2;
- int32_t res;
- int16 n, t, i, norm, neg;
-
- /* is divisor zero ? */
- if (pstm_iszero (b) == 1) {
- return PS_LIMIT_FAIL;
- }
-
- /* if a < b then q=0, r = a */
- if (pstm_cmp_mag (a, b) == PSTM_LT) {
- if (d != NULL) {
- if (pstm_copy(a, d) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- }
- if (c != NULL) {
- pstm_zero (c);
- }
- return PSTM_OKAY;
- }
- /* Smart-size inits */
- if ((res = pstm_init_size(pool, &t1, a->alloc)) != PSTM_OKAY) {
- return res;
- }
- if ((res = pstm_init_size(pool, &t2, 3)) != PSTM_OKAY) {
- goto LBL_T1;
- }
- if ((res = pstm_init_copy(pool, &x, a, 0)) != PSTM_OKAY) {
- goto LBL_T2;
- }
- /* Used to be an init_copy on b but pstm_grow was always hit with triple
- size */
- if ((res = pstm_init_size(pool, &y, b->used * 3)) != PSTM_OKAY) {
- goto LBL_X;
- }
- if ((res = pstm_copy(b, &y)) != PSTM_OKAY) {
- goto LBL_Y;
- }
-
- /* fix the sign */
- neg = (a->sign == b->sign) ? PSTM_ZPOS : PSTM_NEG;
- x.sign = y.sign = PSTM_ZPOS;
-
- /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
- norm = pstm_count_bits(&y) % DIGIT_BIT;
- if (norm < (int16_t)(DIGIT_BIT-1)) {
- norm = (DIGIT_BIT-1) - norm;
- if ((res = pstm_mul_2d(&x, norm, &x)) != PSTM_OKAY) {
- goto LBL_Y;
- }
- if ((res = pstm_mul_2d(&y, norm, &y)) != PSTM_OKAY) {
- goto LBL_Y;
- }
- } else {
- norm = 0;
- }
-
- /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
- n = x.used - 1;
- t = y.used - 1;
-
- if ((res = pstm_init_size(pool, &q, (n - t) + 1)) != PSTM_OKAY) {
- goto LBL_Y;
- }
- q.used = (n - t) + 1;
-
- /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
- if ((res = pstm_lshd(&y, n - t)) != PSTM_OKAY) { /* y = y*b**{n-t} */
- goto LBL_Q;
- }
-
- while (pstm_cmp(&x, &y) != PSTM_LT) {
- ++(q.dp[n - t]);
- if ((res = pstm_sub(&x, &y, &x)) != PSTM_OKAY) {
- goto LBL_Q;
- }
- }
-
- /* reset y by shifting it back down */
- pstm_rshd (&y, n - t);
-
- /* step 3. for i from n down to (t + 1) */
- for (i = n; i >= (t + 1); i--) {
- if (i > x.used) {
- continue;
- }
-
- /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
- * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
- if (x.dp[i] == y.dp[t]) {
- q.dp[i - t - 1] = (pstm_digit)((((pstm_word)1) << DIGIT_BIT) - 1);
- } else {
- pstm_word tmp;
- tmp = ((pstm_word) x.dp[i]) << ((pstm_word) DIGIT_BIT);
- tmp |= ((pstm_word) x.dp[i - 1]);
-#if defined(USE_MATRIX_DIV64) && defined(PSTM_32BIT)
- psDiv64(&tmp, y.dp[t]);
-#elif defined(USE_MATRIX_DIV128) && defined(PSTM_64BIT)
- psDiv128(&tmp, y.dp[t]);
-#else
- tmp /= ((pstm_word) y.dp[t]);
-#endif /* USE_MATRIX_DIV64 */
- q.dp[i - t - 1] = (pstm_digit) (tmp);
- }
-
- /* while (q{i-t-1} * (yt * b + y{t-1})) >
- xi * b**2 + xi-1 * b + xi-2
-
- do q{i-t-1} -= 1;
- */
- q.dp[i - t - 1] = (q.dp[i - t - 1] + 1);
- do {
- q.dp[i - t - 1] = (q.dp[i - t - 1] - 1);
-
- /* find left hand */
- pstm_zero (&t1);
- t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1];
- t1.dp[1] = y.dp[t];
- t1.used = 2;
- if ((res = pstm_mul_d (&t1, q.dp[i - t - 1], &t1)) != PSTM_OKAY) {
- goto LBL_Q;
- }
-
- /* find right hand */
- t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2];
- t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1];
- t2.dp[2] = x.dp[i];
- t2.used = 3;
- } while (pstm_cmp_mag(&t1, &t2) == PSTM_GT);
-
- /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
- if ((res = pstm_mul_d(&y, q.dp[i - t - 1], &t1)) != PSTM_OKAY) {
- goto LBL_Q;
- }
-
- if ((res = pstm_lshd(&t1, i - t - 1)) != PSTM_OKAY) {
- goto LBL_Q;
- }
-
- if ((res = pstm_sub(&x, &t1, &x)) != PSTM_OKAY) {
- goto LBL_Q;
- }
-
- /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
- if (x.sign == PSTM_NEG) {
- if ((res = pstm_copy(&y, &t1)) != PSTM_OKAY) {
- goto LBL_Q;
- }
- if ((res = pstm_lshd (&t1, i - t - 1)) != PSTM_OKAY) {
- goto LBL_Q;
- }
- if ((res = pstm_add (&x, &t1, &x)) != PSTM_OKAY) {
- goto LBL_Q;
- }
- q.dp[i - t - 1] = q.dp[i - t - 1] - 1;
- }
- }
-/*
- now q is the quotient and x is the remainder (which we have to normalize)
-*/
- /* get sign before writing to c */
- x.sign = x.used == 0 ? PSTM_ZPOS : a->sign;
-
- if (c != NULL) {
- pstm_clamp (&q);
- if (pstm_copy (&q, c) != PSTM_OKAY) {
- res = PS_MEM_FAIL;
- goto LBL_Q;
- }
- c->sign = neg;
- }
-
- if (d != NULL) {
- if ((res = pstm_div_2d (pool, &x, norm, &x, NULL)) != PSTM_OKAY) {
- goto LBL_Q;
- }
-/*
- the following is a kludge, essentially we were seeing the right
- remainder but with excess digits that should have been zero
+ a/b => cb + d == a
*/
- for (i = b->used; i < x.used; i++) {
- x.dp[i] = 0;
- }
- pstm_clamp(&x);
- if (pstm_copy (&x, d) != PSTM_OKAY) {
- res = PS_MEM_FAIL;
- goto LBL_Q;
- }
- }
-
- res = PSTM_OKAY;
-
-LBL_Q:pstm_clear (&q);
-LBL_Y:pstm_clear (&y);
-LBL_X:pstm_clear (&x);
-LBL_T2:pstm_clear (&t2);
-LBL_T1:pstm_clear (&t1);
-
- return res;
-}
-#endif /* PSTM_LARGE_DIV */
-
-/******************************************************************************/
-/*
- Swap the elements of two integers, for cases where you can't simply swap
- the pstm_int pointers around
-*/
-void pstm_exch(pstm_int * a, pstm_int * b)
+int32_t pstm_div(psPool_t *pool, const pstm_int *a, const pstm_int *b,
+ pstm_int *c, pstm_int *d)
{
- pstm_int t;
+ pstm_int q, x, y, t1, t2;
+ int32_t res;
+ int16 n, t, i, norm, neg;
- t = *a;
- *a = *b;
- *b = t;
+ /* is divisor zero ? */
+ if (pstm_iszero(b) == 1)
+ {
+ return PS_LIMIT_FAIL;
+ }
+
+ /* if a < b then q=0, r = a */
+ if (pstm_cmp_mag(a, b) == PSTM_LT)
+ {
+ if (d != NULL)
+ {
+ if (pstm_copy(a, d) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ }
+ if (c != NULL)
+ {
+ pstm_zero(c);
+ }
+ return PSTM_OKAY;
+ }
+ /* Smart-size inits */
+ if ((res = pstm_init_size(pool, &t1, a->alloc)) != PSTM_OKAY)
+ {
+ return res;
+ }
+ if ((res = pstm_init_size(pool, &t2, 3)) != PSTM_OKAY)
+ {
+ goto LBL_T1;
+ }
+ if ((res = pstm_init_copy(pool, &x, a, 0)) != PSTM_OKAY)
+ {
+ goto LBL_T2;
+ }
+ /* Used to be an init_copy on b but pstm_grow was always hit with triple
+ size */
+ if ((res = pstm_init_size(pool, &y, b->used * 3)) != PSTM_OKAY)
+ {
+ goto LBL_X;
+ }
+ if ((res = pstm_copy(b, &y)) != PSTM_OKAY)
+ {
+ goto LBL_Y;
+ }
+
+ /* fix the sign */
+ neg = (a->sign == b->sign) ? PSTM_ZPOS : PSTM_NEG;
+ x.sign = y.sign = PSTM_ZPOS;
+
+ /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
+ norm = pstm_count_bits(&y) % DIGIT_BIT;
+ if (norm < (int16_t) (DIGIT_BIT - 1))
+ {
+ norm = (DIGIT_BIT - 1) - norm;
+ if ((res = pstm_mul_2d(&x, norm, &x)) != PSTM_OKAY)
+ {
+ goto LBL_Y;
+ }
+ if ((res = pstm_mul_2d(&y, norm, &y)) != PSTM_OKAY)
+ {
+ goto LBL_Y;
+ }
+ }
+ else
+ {
+ norm = 0;
+ }
+
+ /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
+ n = x.used - 1;
+ t = y.used - 1;
+
+ if ((res = pstm_init_size(pool, &q, (n - t) + 1)) != PSTM_OKAY)
+ {
+ goto LBL_Y;
+ }
+ q.used = (n - t) + 1;
+
+ /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
+ if ((res = pstm_lshd(&y, n - t)) != PSTM_OKAY) /* y = y*b**{n-t} */
+ {
+ goto LBL_Q;
+ }
+
+ while (pstm_cmp(&x, &y) != PSTM_LT)
+ {
+ ++(q.dp[n - t]);
+ if ((res = pstm_sub(&x, &y, &x)) != PSTM_OKAY)
+ {
+ goto LBL_Q;
+ }
+ }
+
+ /* reset y by shifting it back down */
+ pstm_rshd(&y, n - t);
+
+ /* step 3. for i from n down to (t + 1) */
+ for (i = n; i >= (t + 1); i--)
+ {
+ if (i > x.used)
+ {
+ continue;
+ }
+
+ /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
+ * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
+ if (x.dp[i] == y.dp[t])
+ {
+ q.dp[i - t - 1] = (pstm_digit) ((((pstm_word) 1) << DIGIT_BIT) - 1);
+ }
+ else
+ {
+ pstm_word tmp;
+ tmp = ((pstm_word) x.dp[i]) << ((pstm_word) DIGIT_BIT);
+ tmp |= ((pstm_word) x.dp[i - 1]);
+# if defined(USE_MATRIX_DIV64) && defined(PSTM_32BIT)
+ psDiv64(&tmp, y.dp[t]);
+# elif defined(USE_MATRIX_DIV128) && defined(PSTM_64BIT)
+ psDiv128(&tmp, y.dp[t]);
+# else
+ tmp /= ((pstm_word) y.dp[t]);
+# endif /* USE_MATRIX_DIV64 */
+ q.dp[i - t - 1] = (pstm_digit) (tmp);
+ }
+
+ /* while (q{i-t-1} * (yt * b + y{t-1})) >
+ xi * b**2 + xi-1 * b + xi-2
+
+ do q{i-t-1} -= 1;
+ */
+ q.dp[i - t - 1] = (q.dp[i - t - 1] + 1);
+ do
+ {
+ q.dp[i - t - 1] = (q.dp[i - t - 1] - 1);
+
+ /* find left hand */
+ pstm_zero(&t1);
+ t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1];
+ t1.dp[1] = y.dp[t];
+ t1.used = 2;
+ if ((res = pstm_mul_d(&t1, q.dp[i - t - 1], &t1)) != PSTM_OKAY)
+ {
+ goto LBL_Q;
+ }
+
+ /* find right hand */
+ t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2];
+ t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1];
+ t2.dp[2] = x.dp[i];
+ t2.used = 3;
+ }
+ while (pstm_cmp_mag(&t1, &t2) == PSTM_GT);
+
+ /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
+ if ((res = pstm_mul_d(&y, q.dp[i - t - 1], &t1)) != PSTM_OKAY)
+ {
+ goto LBL_Q;
+ }
+
+ if ((res = pstm_lshd(&t1, i - t - 1)) != PSTM_OKAY)
+ {
+ goto LBL_Q;
+ }
+
+ if ((res = pstm_sub(&x, &t1, &x)) != PSTM_OKAY)
+ {
+ goto LBL_Q;
+ }
+
+ /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
+ if (x.sign == PSTM_NEG)
+ {
+ if ((res = pstm_copy(&y, &t1)) != PSTM_OKAY)
+ {
+ goto LBL_Q;
+ }
+ if ((res = pstm_lshd(&t1, i - t - 1)) != PSTM_OKAY)
+ {
+ goto LBL_Q;
+ }
+ if ((res = pstm_add(&x, &t1, &x)) != PSTM_OKAY)
+ {
+ goto LBL_Q;
+ }
+ q.dp[i - t - 1] = q.dp[i - t - 1] - 1;
+ }
+ }
+/*
+ now q is the quotient and x is the remainder (which we have to normalize)
+ */
+ /* get sign before writing to c */
+ x.sign = x.used == 0 ? PSTM_ZPOS : a->sign;
+
+ if (c != NULL)
+ {
+ pstm_clamp(&q);
+ if (pstm_copy(&q, c) != PSTM_OKAY)
+ {
+ res = PS_MEM_FAIL;
+ goto LBL_Q;
+ }
+ c->sign = neg;
+ }
+
+ if (d != NULL)
+ {
+ if ((res = pstm_div_2d(pool, &x, norm, &x, NULL)) != PSTM_OKAY)
+ {
+ goto LBL_Q;
+ }
+/*
+ the following is a kludge, essentially we were seeing the right
+ remainder but with excess digits that should have been zero
+ */
+ for (i = b->used; i < x.used; i++)
+ {
+ x.dp[i] = 0;
+ }
+ pstm_clamp(&x);
+ if (pstm_copy(&x, d) != PSTM_OKAY)
+ {
+ res = PS_MEM_FAIL;
+ goto LBL_Q;
+ }
+ }
+
+ res = PSTM_OKAY;
+
+LBL_Q: pstm_clear(&q);
+LBL_Y: pstm_clear(&y);
+LBL_X: pstm_clear(&x);
+LBL_T2: pstm_clear(&t2);
+LBL_T1: pstm_clear(&t1);
+
+ return res;
+}
+# endif /* PSTM_LARGE_DIV */
+
+/******************************************************************************/
+/*
+ Swap the elements of two integers, for cases where you can't simply swap
+ the pstm_int pointers around
+ */
+void pstm_exch(pstm_int *a, pstm_int *b)
+{
+ pstm_int t;
+
+ t = *a;
+ *a = *b;
+ *b = t;
}
/******************************************************************************/
/*
- c = a mod b, 0 <= c < b
-*/
+ c = a mod b, 0 <= c < b
+ */
int32_t pstm_mod(psPool_t *pool, const pstm_int *a, const pstm_int *b, pstm_int *c)
{
- pstm_int t;
- int32_t err;
+ pstm_int t;
+ int32_t err;
- /* Smart-size */
- if ((err = pstm_init_size(pool, &t, b->alloc)) != PSTM_OKAY) {
- return err;
- }
- if ((err = pstm_div(pool, a, b, NULL, &t)) != PSTM_OKAY) {
- pstm_clear(&t);
- return err;
- }
- if (t.sign != b->sign) {
- err = pstm_add(&t, b, c);
- } else {
- pstm_exch(&t, c);
- }
- pstm_clear(&t);
- return err;
+ /* Smart-size */
+ if ((err = pstm_init_size(pool, &t, b->alloc)) != PSTM_OKAY)
+ {
+ return err;
+ }
+ if ((err = pstm_div(pool, a, b, NULL, &t)) != PSTM_OKAY)
+ {
+ pstm_clear(&t);
+ return err;
+ }
+ if (t.sign != b->sign)
+ {
+ err = pstm_add(&t, b, c);
+ }
+ else
+ {
+ pstm_exch(&t, c);
+ }
+ pstm_clear(&t);
+ return err;
}
-#if defined USE_MATRIX_RSA || defined USE_MATRIX_ECC || defined USE_MATRIX_DH
+# if defined USE_MATRIX_RSA || defined USE_MATRIX_ECC || defined USE_MATRIX_DH
/******************************************************************************/
/*
- d = a * b (mod c)
-*/
+ d = a * b (mod c)
+ */
int32_t pstm_mulmod(psPool_t *pool, const pstm_int *a, const pstm_int *b,
- const pstm_int *c, pstm_int *d)
+ const pstm_int *c, pstm_int *d)
{
- int32_t res;
- uint16_t size;
- pstm_int tmp;
+ int32_t res;
+ psSize_t size;
+ pstm_int tmp;
/*
- Smart-size pstm_inits. d is an output that is influenced by this local 't'
- so don't shrink 'd' if it wants to becuase this will lead to an pstm_grow
- in RSA operations
-*/
- size = a->used + b->used + 1;
- if ((a == d) && (size < a->alloc)) {
- size = a->alloc;
- }
- if ((res = pstm_init_size(pool, &tmp, size)) != PSTM_OKAY) {
- return res;
- }
- if ((res = pstm_mul_comba(pool, a, b, &tmp, NULL, 0)) != PSTM_OKAY) {
- pstm_clear(&tmp);
- return res;
- }
- res = pstm_mod(pool, &tmp, c, d);
- pstm_clear(&tmp);
- return res;
+ Smart-size pstm_inits. d is an output that is influenced by this local 't'
+ so don't shrink 'd' if it wants to becuase this will lead to an pstm_grow
+ in RSA operations
+ */
+ size = a->used + b->used + 1;
+ if ((a == d) && (size < a->alloc))
+ {
+ size = a->alloc;
+ }
+ if ((res = pstm_init_size(pool, &tmp, size)) != PSTM_OKAY)
+ {
+ return res;
+ }
+ if ((res = pstm_mul_comba(pool, a, b, &tmp, NULL, 0)) != PSTM_OKAY)
+ {
+ pstm_clear(&tmp);
+ return res;
+ }
+ res = pstm_mod(pool, &tmp, c, d);
+ pstm_clear(&tmp);
+ return res;
}
/******************************************************************************/
/*
- * y = g**x (mod p)
- * Some restrictions...
- * x must be positive and < p
- * p must be positive, odd, and [512,1024,1536,2048,3072,4096] bits
+ * y = g**x (mod p)
+ * Some restrictions...
+ * x must be positive and < p
+ * p must be positive, odd, and [512,1024,1536,2048,3072,4096] bits
*/
int32_t pstm_exptmod(psPool_t *pool, const pstm_int *G, const pstm_int *X,
- const pstm_int *P, pstm_int *Y)
+ const pstm_int *P, pstm_int *Y)
{
- pstm_int M[32], res; /* Keep this winsize based: (1 << max_winsize) */
- pstm_digit buf, mp;
- pstm_digit *paD;
- int32 err, bitbuf;
- int16 bitcpy, bitcnt, mode, digidx, x, y, winsize;
- uint32 paDlen;
+ pstm_int M[32], res; /* Keep this winsize based: (1 << max_winsize) */
+ pstm_digit buf, mp;
+ pstm_digit *paD;
+ int32 err, bitbuf;
+ int16 bitcpy, bitcnt, mode, digidx, x, y, winsize;
+ uint32 paDlen;
- x = pstm_count_bits(P);
- switch(x) {
- case 512:
- case 1024:
- case 1536:
- case 2048:
- case 3072:
- case 4096:
- break;
- default:
- psTraceIntCrypto("pstm_exptmod prime size failed: %hu\n", x);
- return -1;
- }
- /* set window size from what user set as optimization */
- x = pstm_count_bits(X);
- if (x < 50) {
- winsize = 2;
- } else {
- winsize = PS_EXPTMOD_WINSIZE;
- }
+ x = pstm_count_bits(P);
+ switch (x)
+ {
+ case 512:
+ case 1024:
+ case 1536:
+ case 2048:
+ case 3072:
+ case 4096:
+ break;
+ default:
+ psTraceIntCrypto("pstm_exptmod prime size failed: %hu\n", x);
+ return -1;
+ }
+# ifdef USE_CONSTANT_TIME_MODEXP
+ if (P->dp[0] & 1)
+ {
+ pstmnt_word Base[512 / sizeof(pstmnt_word)];
+ pstmnt_word Mod[512 / sizeof(pstmnt_word)];
+ pstmnt_word Temp[512 / sizeof(pstmnt_word) * 7 + 1];
+ pstmnt_word mp = pstmnt_neg_small_inv(pstmnt_const_ptr(P));
- /* now setup montgomery */
- if ((err = pstm_montgomery_setup (P, &mp)) != PSTM_OKAY) {
- return err;
- }
- /* setup result */
- if ((err = pstm_init_size(pool, &res, (P->used * 2) + 1)) != PSTM_OKAY) {
- return err;
- }
+ memset(Base, 0, sizeof(Base));
+ if (G->used <= P->used)
+ {
+ memcpy(Base, pstmnt_const_ptr(G), pstmnt_size_bytes(G));
+ }
+ else
+ {
+ /* Base > P -> have to compute Base % P to get the actual base. */
+ int32_t err;
+ pstm_int tmp_int;
+ if ((err = pstm_init_size(pool, &tmp_int, P->used)) != PSTM_OKAY)
+ {
+ return err;
+ }
+ err = pstm_mod(pool, G, P, &tmp_int);
+ memcpy(Base, pstmnt_const_ptr(&tmp_int),
+ pstmnt_size_bytes(&tmp_int));
+ pstm_clear(&tmp_int);
+ if (err != PSTM_OKAY)
+ {
+ return err;
+ }
+ }
+ memcpy(Mod, pstmnt_const_ptr(P), pstmnt_size_bytes(P));
+
+ Y->used = P->used;
+ if (Y->used > Y->alloc)
+ {
+ if (pstm_grow(Y, Y->used) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ }
+
+ /* Use constant time variant. */
+ pstmnt_montgomery_input(Base, Mod, Temp,
+ pstmnt_ptr(Y), pstmnt_size(P), mp);
+ pstmnt_mod_exp_montgomery_skip(pstmnt_const_ptr(Y), pstmnt_const_ptr(X),
+ pstmnt_ptr(Y), 0,
+ pstm_count_bits(X), Mod, Temp,
+ mp, pstmnt_size(P));
+ pstmnt_montgomery_output(pstmnt_const_ptr(Y), pstmnt_ptr(Y), Mod, Temp,
+ pstmnt_size(P), mp);
+ pstm_clamp(Y);
+ memset_s(Base, sizeof(Base), 0, sizeof(Base));
+ memset_s(Mod, sizeof(Mod), 0, sizeof(Mod));
+ memset_s(Temp, sizeof(Temp), 0, sizeof(Temp));
+ return PSTM_OKAY;
+ }
+# endif /* USE_CONSTANT_TIME_MODEXP */
+ /* set window size from what user set as optimization */
+ x = pstm_count_bits(X);
+ if (x < 50)
+ {
+ winsize = 2;
+ }
+ else
+ {
+ winsize = PS_EXPTMOD_WINSIZE;
+ }
+
+ /* now setup montgomery */
+ if ((err = pstm_montgomery_setup(P, &mp)) != PSTM_OKAY)
+ {
+ return err;
+ }
+
+ /* setup result */
+ if ((err = pstm_init_size(pool, &res, (P->used * 2) + 1)) != PSTM_OKAY)
+ {
+ return err;
+ }
/*
- create M table
- The M table contains powers of the input base, e.g. M[x] = G^x mod P
- The first half of the table is not computed though except for M[0] and M[1]
+ create M table
+ The M table contains powers of the input base, e.g. M[x] = G^x mod P
+ The first half of the table is not computed though except for M[0] and M[1]
*/
- /* now we need R mod m */
- if ((err = pstm_montgomery_calc_normalization (&res, P)) != PSTM_OKAY) {
- goto LBL_RES;
- }
+ /* now we need R mod m */
+ if ((err = pstm_montgomery_calc_normalization(&res, P)) != PSTM_OKAY)
+ {
+ goto LBL_RES;
+ }
/*
- init M array
- init first cell
+ init M array
+ init first cell
*/
- if ((err = pstm_init_size(pool, &M[1], res.used)) != PSTM_OKAY) {
- goto LBL_RES;
- }
+ if ((err = pstm_init_size(pool, &M[1], res.used)) != PSTM_OKAY)
+ {
+ goto LBL_RES;
+ }
- /* now set M[1] to G * R mod m */
- if (pstm_cmp_mag(P, G) != PSTM_GT) {
- /* G > P so we reduce it first */
- if ((err = pstm_mod(pool, G, P, &M[1])) != PSTM_OKAY) {
- goto LBL_M;
- }
- } else {
- if ((err = pstm_copy(G, &M[1])) != PSTM_OKAY) {
- goto LBL_M;
- }
- }
- if ((err = pstm_mulmod (pool, &M[1], &res, P, &M[1])) != PSTM_OKAY) {
- goto LBL_M;
- }
- /* Pre-allocated digit. Used for mul, sqr, AND reduce */
- paDlen = ((M[1].used + 3) * 2) * sizeof(pstm_digit);
- if ((paD = psMalloc(pool, paDlen)) == NULL) {
- err = PS_MEM_FAIL;
- goto LBL_M;
- }
- /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
- if (pstm_init_copy(pool, &M[1 << (winsize - 1)], &M[1], 1) != PSTM_OKAY) {
- err = PS_MEM_FAIL;
- goto LBL_PAD;
- }
- for (x = 0; x < (winsize - 1); x++) {
- if ((err = pstm_sqr_comba (pool, &M[1 << (winsize - 1)],
- &M[1 << (winsize - 1)], paD, paDlen)) != PSTM_OKAY) {
- goto LBL_PAD;
- }
- if ((err = pstm_montgomery_reduce(pool, &M[1 << (winsize - 1)], P, mp,
- paD, paDlen)) != PSTM_OKAY) {
- goto LBL_PAD;
- }
- }
- /* now init the second half of the array */
- for (x = (1<<(winsize-1)) + 1; x < (1 << winsize); x++) {
- if ((err = pstm_init_size(pool, &M[x], M[1<<(winsize-1)].alloc + 1))
- != PSTM_OKAY) {
- for (y = 1<<(winsize-1); y < x; y++) {
- pstm_clear(&M[y]);
- }
- goto LBL_PAD;
- }
- }
+ /* now set M[1] to G * R mod m */
+ if (pstm_cmp_mag(P, G) != PSTM_GT)
+ {
+ /* G > P so we reduce it first */
+ if ((err = pstm_mod(pool, G, P, &M[1])) != PSTM_OKAY)
+ {
+ goto LBL_M;
+ }
+ }
+ else
+ {
+ if ((err = pstm_copy(G, &M[1])) != PSTM_OKAY)
+ {
+ goto LBL_M;
+ }
+ }
+ if ((err = pstm_mulmod(pool, &M[1], &res, P, &M[1])) != PSTM_OKAY)
+ {
+ goto LBL_M;
+ }
+ /* Pre-allocated digit. Used for mul, sqr, AND reduce */
+ paDlen = ((M[1].used + 3) * 2) * sizeof(pstm_digit);
+ if ((paD = psMalloc(pool, paDlen)) == NULL)
+ {
+ err = PS_MEM_FAIL;
+ goto LBL_M;
+ }
+ /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
+ if (pstm_init_copy(pool, &M[1 << (winsize - 1)], &M[1], 1) != PSTM_OKAY)
+ {
+ err = PS_MEM_FAIL;
+ goto LBL_PAD;
+ }
+ for (x = 0; x < (winsize - 1); x++)
+ {
+ if ((err = pstm_sqr_comba(pool, &M[1 << (winsize - 1)],
+ &M[1 << (winsize - 1)], paD, paDlen)) != PSTM_OKAY)
+ {
+ goto LBL_PAD;
+ }
+ if ((err = pstm_montgomery_reduce(pool, &M[1 << (winsize - 1)], P, mp,
+ paD, paDlen)) != PSTM_OKAY)
+ {
+ goto LBL_PAD;
+ }
+ }
+ /* now init the second half of the array */
+ for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++)
+ {
+ if ((err = pstm_init_size(pool, &M[x], M[1 << (winsize - 1)].alloc + 1))
+ != PSTM_OKAY)
+ {
+ for (y = 1 << (winsize - 1); y < x; y++)
+ {
+ pstm_clear(&M[y]);
+ }
+ goto LBL_PAD;
+ }
+ }
- /* create upper table */
- for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
- if ((err = pstm_mul_comba(pool, &M[x - 1], &M[1], &M[x], paD, paDlen))
- != PSTM_OKAY) {
- goto LBL_MARRAY;
- }
- if ((err = pstm_montgomery_reduce(pool, &M[x], P, mp, paD, paDlen)) !=
- PSTM_OKAY) {
- goto LBL_MARRAY;
- }
- }
+ /* create upper table */
+ for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++)
+ {
+ if ((err = pstm_mul_comba(pool, &M[x - 1], &M[1], &M[x], paD, paDlen))
+ != PSTM_OKAY)
+ {
+ goto LBL_MARRAY;
+ }
+ if ((err = pstm_montgomery_reduce(pool, &M[x], P, mp, paD, paDlen)) !=
+ PSTM_OKAY)
+ {
+ goto LBL_MARRAY;
+ }
+ }
- /* set initial mode and bit cnt */
- mode = 0;
- bitcnt = 1;
- buf = 0;
- digidx = X->used - 1;
- bitcpy = 0;
- bitbuf = 0;
+ /* set initial mode and bit cnt */
+ mode = 0;
+ bitcnt = 1;
+ buf = 0;
+ digidx = X->used - 1;
+ bitcpy = 0;
+ bitbuf = 0;
- for (;;) {
- /* grab next digit as required */
- if (--bitcnt == 0) {
- /* if digidx == -1 we are out of digits so break */
- if (digidx == -1) {
- break;
- }
- /* read next digit and reset bitcnt */
- buf = X->dp[digidx--];
- bitcnt = (int32)DIGIT_BIT;
- }
+ for (;; )
+ {
+ /* grab next digit as required */
+ if (--bitcnt == 0)
+ {
+ /* if digidx == -1 we are out of digits so break */
+ if (digidx == -1)
+ {
+ break;
+ }
+ /* read next digit and reset bitcnt */
+ buf = X->dp[digidx--];
+ bitcnt = (int32) DIGIT_BIT;
+ }
- /* grab the next msb from the exponent */
- y = (pstm_digit)(buf >> (DIGIT_BIT - 1)) & 1;
- buf <<= (pstm_digit)1;
+ /* grab the next msb from the exponent */
+ y = (pstm_digit) (buf >> (DIGIT_BIT - 1)) & 1;
+ buf <<= (pstm_digit) 1;
/*
- If the bit is zero and mode == 0 then we ignore it.
- These represent the leading zero bits before the first 1 bit
- in the exponent. Technically this opt is not required but it
- does lower the # of trivial squaring/reductions used
-*/
- if (mode == 0 && y == 0) {
- continue;
- }
+ If the bit is zero and mode == 0 then we ignore it.
+ These represent the leading zero bits before the first 1 bit
+ in the exponent. Technically this opt is not required but it
+ does lower the # of trivial squaring/reductions used
+ */
+ if (mode == 0 && y == 0)
+ {
+ continue;
+ }
- /* if the bit is zero and mode == 1 then we square */
- if (mode == 1 && y == 0) {
- if ((err = pstm_sqr_comba(pool, &res, &res, paD, paDlen)) !=
- PSTM_OKAY) {
- goto LBL_MARRAY;
- }
- if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen))
- != PSTM_OKAY) {
- goto LBL_MARRAY;
- }
- continue;
- }
+ /* if the bit is zero and mode == 1 then we square */
+ if (mode == 1 && y == 0)
+ {
+ if ((err = pstm_sqr_comba(pool, &res, &res, paD, paDlen)) !=
+ PSTM_OKAY)
+ {
+ goto LBL_MARRAY;
+ }
+ if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen))
+ != PSTM_OKAY)
+ {
+ goto LBL_MARRAY;
+ }
+ continue;
+ }
- /* else we add it to the window */
- bitbuf |= (y << (winsize - ++bitcpy));
- mode = 2;
+ /* else we add it to the window */
+ bitbuf |= (y << (winsize - ++bitcpy));
+ mode = 2;
- if (bitcpy == winsize) {
- /* ok window is filled so square as required and mul square first */
- for (x = 0; x < winsize; x++) {
- if ((err = pstm_sqr_comba(pool, &res, &res, paD, paDlen)) !=
- PSTM_OKAY) {
- goto LBL_MARRAY;
- }
- if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD,
- paDlen)) != PSTM_OKAY) {
- goto LBL_MARRAY;
- }
- }
+ if (bitcpy == winsize)
+ {
+ /* ok window is filled so square as required and mul square first */
+ for (x = 0; x < winsize; x++)
+ {
+ if ((err = pstm_sqr_comba(pool, &res, &res, paD, paDlen)) !=
+ PSTM_OKAY)
+ {
+ goto LBL_MARRAY;
+ }
+ if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD,
+ paDlen)) != PSTM_OKAY)
+ {
+ goto LBL_MARRAY;
+ }
+ }
- /* then multiply */
- if ((err = pstm_mul_comba(pool, &res, &M[bitbuf], &res, paD,
- paDlen)) != PSTM_OKAY) {
- goto LBL_MARRAY;
- }
- if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen))
- != PSTM_OKAY) {
- goto LBL_MARRAY;
- }
+ /* then multiply */
+ if ((err = pstm_mul_comba(pool, &res, &M[bitbuf], &res, paD,
+ paDlen)) != PSTM_OKAY)
+ {
+ goto LBL_MARRAY;
+ }
+ if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen))
+ != PSTM_OKAY)
+ {
+ goto LBL_MARRAY;
+ }
- /* empty window and reset */
- bitcpy = 0;
- bitbuf = 0;
- mode = 1;
- }
- }
+ /* empty window and reset */
+ bitcpy = 0;
+ bitbuf = 0;
+ mode = 1;
+ }
+ }
- /* if bits remain then square/multiply */
- if (mode == 2 && bitcpy > 0) {
- /* square then multiply if the bit is set */
- for (x = 0; x < bitcpy; x++) {
- if ((err = pstm_sqr_comba(pool, &res, &res, paD, paDlen)) !=
- PSTM_OKAY) {
- goto LBL_MARRAY;
- }
- if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen))
- != PSTM_OKAY) {
- goto LBL_MARRAY;
- }
+ /* if bits remain then square/multiply */
+ if (mode == 2 && bitcpy > 0)
+ {
+ /* square then multiply if the bit is set */
+ for (x = 0; x < bitcpy; x++)
+ {
+ if ((err = pstm_sqr_comba(pool, &res, &res, paD, paDlen)) !=
+ PSTM_OKAY)
+ {
+ goto LBL_MARRAY;
+ }
+ if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen))
+ != PSTM_OKAY)
+ {
+ goto LBL_MARRAY;
+ }
- /* get next bit of the window */
- bitbuf <<= 1;
- if ((bitbuf & (1 << winsize)) != 0) {
- /* then multiply */
- if ((err = pstm_mul_comba(pool, &res, &M[1], &res, paD, paDlen))
- != PSTM_OKAY) {
- goto LBL_MARRAY;
- }
- if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD,
- paDlen)) != PSTM_OKAY) {
- goto LBL_MARRAY;
- }
- }
- }
- }
+ /* get next bit of the window */
+ bitbuf <<= 1;
+ if ((bitbuf & (1 << winsize)) != 0)
+ {
+ /* then multiply */
+ if ((err = pstm_mul_comba(pool, &res, &M[1], &res, paD, paDlen))
+ != PSTM_OKAY)
+ {
+ goto LBL_MARRAY;
+ }
+ if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD,
+ paDlen)) != PSTM_OKAY)
+ {
+ goto LBL_MARRAY;
+ }
+ }
+ }
+ }
/*
- Fix up result if Montgomery reduction is used recall that any value in a
- Montgomery system is actually multiplied by R mod n. So we have to reduce
- one more time to cancel out the factor of R.
-*/
- if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen)) !=
- PSTM_OKAY) {
- goto LBL_MARRAY;
- }
- /* swap res with Y */
- if ((err = pstm_copy (&res, Y)) != PSTM_OKAY) {
- goto LBL_MARRAY;
- }
- err = PSTM_OKAY;
+ Fix up result if Montgomery reduction is used recall that any value in a
+ Montgomery system is actually multiplied by R mod n. So we have to reduce
+ one more time to cancel out the factor of R.
+ */
+ if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen)) !=
+ PSTM_OKAY)
+ {
+ goto LBL_MARRAY;
+ }
+ /* swap res with Y */
+ if ((err = pstm_copy(&res, Y)) != PSTM_OKAY)
+ {
+ goto LBL_MARRAY;
+ }
+ err = PSTM_OKAY;
LBL_MARRAY:
- for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
- pstm_clear(&M[x]);
- }
-LBL_PAD:psFree(paD, pool);
+ for (x = 1 << (winsize - 1); x < (1 << winsize); x++)
+ {
+ pstm_clear(&M[x]);
+ }
+LBL_PAD: psFree(paD, pool);
LBL_M: pstm_clear(&M[1]);
-LBL_RES:pstm_clear(&res);
- return err;
+LBL_RES: pstm_clear(&res);
+
+ return err;
}
-#endif /* USE_MATRIX_RSA || USE_MATRIX_ECC || USE_MATRIX_DH */
+# endif /* USE_MATRIX_RSA || USE_MATRIX_ECC || USE_MATRIX_DH */
/******************************************************************************/
/**
- c = a + b.
-*/
+ c = a + b.
+ */
int32_t pstm_add(const pstm_int *a, const pstm_int *b, pstm_int *c)
{
- int32_t res;
- uint8_t sa, sb;
+ int32_t res;
+ uint8_t sa, sb;
- /* get sign of both inputs */
- sa = a->sign;
- sb = b->sign;
+ /* get sign of both inputs */
+ sa = a->sign;
+ sb = b->sign;
- /* handle two cases, not four */
- if (sa == sb) {
- /* both positive or both negative, add their mags, copy the sign */
- c->sign = sa;
- if ((res = s_pstm_add (a, b, c)) != PSTM_OKAY) {
- return res;
- }
- } else {
+ /* handle two cases, not four */
+ if (sa == sb)
+ {
+ /* both positive or both negative, add their mags, copy the sign */
+ c->sign = sa;
+ if ((res = s_pstm_add(a, b, c)) != PSTM_OKAY)
+ {
+ return res;
+ }
+ }
+ else
+ {
/*
- one positive, the other negative
- subtract the one with the greater magnitude from the one of the lesser
- magnitude. The result gets the sign of the one with the greater mag.
+ one positive, the other negative
+ subtract the one with the greater magnitude from the one of the lesser
+ magnitude. The result gets the sign of the one with the greater mag.
*/
- if (pstm_cmp_mag(a, b) == PSTM_LT) {
- c->sign = sb;
- if ((res = s_pstm_sub (b, a, c)) != PSTM_OKAY) {
- return res;
- }
- } else {
- c->sign = sa;
- if ((res = s_pstm_sub (a, b, c)) != PSTM_OKAY) {
- return res;
- }
- }
- }
- return PS_SUCCESS;
+ if (pstm_cmp_mag(a, b) == PSTM_LT)
+ {
+ c->sign = sb;
+ if ((res = pstm_sub_s(b, a, c)) != PSTM_OKAY)
+ {
+ return res;
+ }
+ }
+ else
+ {
+ c->sign = sa;
+ if ((res = pstm_sub_s(a, b, c)) != PSTM_OKAY)
+ {
+ return res;
+ }
+ }
+ }
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- No reverse. Useful in some of the EIP-154 PKA stuff where special byte
- order seems to come into play more often
-*/
+ No reverse. Useful in some of the EIP-154 PKA stuff where special byte
+ order seems to come into play more often
+ */
int32_t pstm_to_unsigned_bin_nr(psPool_t *pool, const pstm_int *a, unsigned char *b)
{
- int32_t res;
- uint16_t x;
- pstm_int t = { 0 };
+ int32_t res;
+ uint16_t x;
+ pstm_int t = { 0 };
- if ((res = pstm_init_copy(pool, &t, a, 0)) != PSTM_OKAY) {
- return res;
- }
+ if ((res = pstm_init_copy(pool, &t, a, 0)) != PSTM_OKAY)
+ {
+ return res;
+ }
- x = 0;
- while (pstm_iszero (&t) == 0) {
- b[x++] = (unsigned char) (t.dp[0] & 255);
- if ((res = pstm_div_2d (pool, &t, 8, &t, NULL)) != PSTM_OKAY) {
- pstm_clear(&t);
- return res;
- }
- }
- pstm_clear(&t);
- return PS_SUCCESS;
+ x = 0;
+ while (pstm_iszero(&t) == 0)
+ {
+ b[x++] = (unsigned char) (t.dp[0] & 255);
+ if ((res = pstm_div_2d(pool, &t, 8, &t, NULL)) != PSTM_OKAY)
+ {
+ pstm_clear(&t);
+ return res;
+ }
+ }
+ pstm_clear(&t);
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- reverse an array, used for unsigned bin code
-*/
-static void pstm_reverse(unsigned char *s, uint16_t len)
+ reverse an array, used for unsigned bin code
+ */
+static void pstm_reverse(unsigned char *s, psSize_t len)
{
- uint16_t ix, iy;
- unsigned char t;
+ uint16_t ix, iy;
+ unsigned char t;
- if (len == 0) {
- return;
- }
- ix = 0;
- iy = len - 1;
- while (ix < iy) {
- t = s[ix];
- s[ix] = s[iy];
- s[iy] = t;
- ++ix;
- --iy;
- }
+ if (len == 0)
+ {
+ return;
+ }
+ ix = 0;
+ iy = len - 1;
+ while (ix < iy)
+ {
+ t = s[ix];
+ s[ix] = s[iy];
+ s[iy] = t;
+ ++ix;
+ --iy;
+ }
}
/******************************************************************************/
/**
- Write a pstm format integer to a raw binary format.
- @return < 0 on failure. PS_SUCCESS on success.
-*/
+ Write a pstm format integer to a raw binary format.
+ @return < 0 on failure. PS_SUCCESS on success.
+ */
int32_t pstm_to_unsigned_bin(psPool_t *pool, const pstm_int *a, unsigned char *b)
{
- int32_t res;
- uint16_t x;
- pstm_int t = { 0 };
+ int32_t res;
+ uint16_t x;
+ pstm_int t = { 0 };
- if ((res = pstm_init_copy(pool, &t, a, 0)) != PSTM_OKAY) {
- return res;
- }
- x = 0;
- while (pstm_iszero (&t) == 0) {
- b[x++] = (unsigned char) (t.dp[0] & 255);
- if ((res = pstm_div_2d (pool, &t, 8, &t, NULL)) != PSTM_OKAY) {
- pstm_clear(&t);
- return res;
- }
- }
- pstm_reverse (b, x);
- pstm_clear(&t);
- return PS_SUCCESS;
+ if ((res = pstm_init_copy(pool, &t, a, 0)) != PSTM_OKAY)
+ {
+ return res;
+ }
+ x = 0;
+ while (pstm_iszero(&t) == 0)
+ {
+ b[x++] = (unsigned char) (t.dp[0] & 255);
+ if ((res = pstm_div_2d(pool, &t, 8, &t, NULL)) != PSTM_OKAY)
+ {
+ pstm_clear(&t);
+ return res;
+ }
+ }
+ pstm_reverse(b, x);
+ pstm_clear(&t);
+ return PS_SUCCESS;
}
/******************************************************************************/
/**
- c = 1/a (mod b).
+ c = 1/a (mod b).
- @note Slow version supporting an even 'b'. Should call pstm_invmod() and let it
- decide which to use.
+ @note Slow version supporting an even 'b'. Should call pstm_invmod() and let it
+ decide which to use.
- Need invmod for ECC and also private key loading for hardware crypto
- in cases where dQ > dP. The values must be switched and a new qP must be
- calculated using this function
-*/
+ Need invmod for ECC and also private key loading for hardware crypto
+ in cases where dQ > dP. The values must be switched and a new qP must be
+ calculated using this function
+ */
static int32_t pstm_invmod_slow(psPool_t *pool, const pstm_int *a,
- const pstm_int *b, pstm_int * c)
+ const pstm_int *b, pstm_int *c)
{
- pstm_int x, y, u, v, A, B, C, D;
- int32 res;
+ pstm_int x, y, u, v, A, B, C, D;
+ int32 res;
- /* b cannot be negative */
- if (b->sign == PSTM_NEG || pstm_iszero(b) == 1) {
- return PS_LIMIT_FAIL;
- }
+ /* b cannot be negative */
+ if (b->sign == PSTM_NEG || pstm_iszero(b) == 1)
+ {
+ return PS_LIMIT_FAIL;
+ }
- /* init temps */
- if (pstm_init_size(pool, &x, b->used) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
+ /* init temps */
+ if (pstm_init_size(pool, &x, b->used) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
- /* x = a, y = b */
- if ((res = pstm_mod(pool, a, b, &x)) != PSTM_OKAY) {
- goto LBL_X;
- }
+ /* x = a, y = b */
+ if ((res = pstm_mod(pool, a, b, &x)) != PSTM_OKAY)
+ {
+ goto LBL_X;
+ }
- if (pstm_init_copy(pool, &y, b, 0) != PSTM_OKAY) {
- goto LBL_X;
- }
+ if (pstm_init_copy(pool, &y, b, 0) != PSTM_OKAY)
+ {
+ goto LBL_X;
+ }
- /* 2. [modified] if x,y are both even then return an error! */
- if (pstm_iseven (&x) == 1 && pstm_iseven (&y) == 1) {
- res = PS_FAILURE;
- goto LBL_Y;
- }
+ /* 2. [modified] if x,y are both even then return an error! */
+ if (pstm_iseven(&x) == 1 && pstm_iseven(&y) == 1)
+ {
+ res = PS_FAILURE;
+ goto LBL_Y;
+ }
- /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
- if ((res = pstm_init_copy(pool, &u, &x, 0)) != PSTM_OKAY) {
- goto LBL_Y;
- }
- if ((res = pstm_init_copy(pool, &v, &y, 0)) != PSTM_OKAY) {
- goto LBL_U;
- }
+ /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
+ if ((res = pstm_init_copy(pool, &u, &x, 0)) != PSTM_OKAY)
+ {
+ goto LBL_Y;
+ }
+ if ((res = pstm_init_copy(pool, &v, &y, 0)) != PSTM_OKAY)
+ {
+ goto LBL_U;
+ }
- if ((res = pstm_init_size(pool, &A, sizeof(pstm_digit))) != PSTM_OKAY) {
- goto LBL_V;
- }
+ if ((res = pstm_init_size(pool, &A, sizeof(pstm_digit))) != PSTM_OKAY)
+ {
+ goto LBL_V;
+ }
- if ((res = pstm_init_size(pool, &D, sizeof(pstm_digit))) != PSTM_OKAY) {
- goto LBL_A;
- }
- pstm_set (&A, 1);
- pstm_set (&D, 1);
+ if ((res = pstm_init_size(pool, &D, sizeof(pstm_digit))) != PSTM_OKAY)
+ {
+ goto LBL_A;
+ }
+ pstm_set(&A, 1);
+ pstm_set(&D, 1);
- if ((res = pstm_init(pool, &B)) != PSTM_OKAY) {
- goto LBL_D;
- }
- if ((res = pstm_init(pool, &C)) != PSTM_OKAY) {
- goto LBL_B;
- }
+ if ((res = pstm_init(pool, &B)) != PSTM_OKAY)
+ {
+ goto LBL_D;
+ }
+ if ((res = pstm_init(pool, &C)) != PSTM_OKAY)
+ {
+ goto LBL_B;
+ }
top:
- /* 4. while u is even do */
- while (pstm_iseven (&u) == 1) {
- /* 4.1 u = u/2 */
- if ((res = pstm_div_2(&u, &u)) != PSTM_OKAY) {
- goto LBL_C;
- }
+ /* 4. while u is even do */
+ while (pstm_iseven(&u) == 1)
+ {
+ /* 4.1 u = u/2 */
+ if ((res = pstm_div_2(&u, &u)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
- /* 4.2 if A or B is odd then */
- if (pstm_isodd(&A) == 1 || pstm_isodd (&B) == 1) {
- /* A = (A+y)/2, B = (B-x)/2 */
- if ((res = pstm_add(&A, &y, &A)) != PSTM_OKAY) {
- goto LBL_C;
- }
- if ((res = pstm_sub(&B, &x, &B)) != PSTM_OKAY) {
- goto LBL_C;
- }
- }
- /* A = A/2, B = B/2 */
- if ((res = pstm_div_2(&A, &A)) != PSTM_OKAY) {
- goto LBL_C;
- }
- if ((res = pstm_div_2(&B, &B)) != PSTM_OKAY) {
- goto LBL_C;
- }
- }
+ /* 4.2 if A or B is odd then */
+ if (pstm_isodd(&A) == 1 || pstm_isodd(&B) == 1)
+ {
+ /* A = (A+y)/2, B = (B-x)/2 */
+ if ((res = pstm_add(&A, &y, &A)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ if ((res = pstm_sub(&B, &x, &B)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ }
+ /* A = A/2, B = B/2 */
+ if ((res = pstm_div_2(&A, &A)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ if ((res = pstm_div_2(&B, &B)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ }
- /* 5. while v is even do */
- while (pstm_iseven(&v) == 1) {
- /* 5.1 v = v/2 */
- if ((res = pstm_div_2(&v, &v)) != PSTM_OKAY) {
- goto LBL_C;
- }
+ /* 5. while v is even do */
+ while (pstm_iseven(&v) == 1)
+ {
+ /* 5.1 v = v/2 */
+ if ((res = pstm_div_2(&v, &v)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
- /* 5.2 if C or D is odd then */
- if (pstm_isodd(&C) == 1 || pstm_isodd(&D) == 1) {
- /* C = (C+y)/2, D = (D-x)/2 */
- if ((res = pstm_add(&C, &y, &C)) != PSTM_OKAY) {
- goto LBL_C;
- }
- if ((res = pstm_sub(&D, &x, &D)) != PSTM_OKAY) {
- goto LBL_C;
- }
- }
- /* C = C/2, D = D/2 */
- if ((res = pstm_div_2(&C, &C)) != PSTM_OKAY) {
- goto LBL_C;
- }
- if ((res = pstm_div_2(&D, &D)) != PSTM_OKAY) {
- goto LBL_C;
- }
- }
+ /* 5.2 if C or D is odd then */
+ if (pstm_isodd(&C) == 1 || pstm_isodd(&D) == 1)
+ {
+ /* C = (C+y)/2, D = (D-x)/2 */
+ if ((res = pstm_add(&C, &y, &C)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ if ((res = pstm_sub(&D, &x, &D)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ }
+ /* C = C/2, D = D/2 */
+ if ((res = pstm_div_2(&C, &C)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ if ((res = pstm_div_2(&D, &D)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ }
- /* 6. if u >= v then */
- if (pstm_cmp(&u, &v) != PSTM_LT) {
- /* u = u - v, A = A - C, B = B - D */
- if ((res = pstm_sub(&u, &v, &u)) != PSTM_OKAY) {
- goto LBL_C;
- }
- if ((res = pstm_sub(&A, &C, &A)) != PSTM_OKAY) {
- goto LBL_C;
- }
- if ((res = pstm_sub(&B, &D, &B)) != PSTM_OKAY) {
- goto LBL_C;
- }
- } else {
- /* v - v - u, C = C - A, D = D - B */
- if ((res = pstm_sub(&v, &u, &v)) != PSTM_OKAY) {
- goto LBL_C;
- }
- if ((res = pstm_sub(&C, &A, &C)) != PSTM_OKAY) {
- goto LBL_C;
- }
- if ((res = pstm_sub(&D, &B, &D)) != PSTM_OKAY) {
- goto LBL_C;
- }
- }
+ /* 6. if u >= v then */
+ if (pstm_cmp(&u, &v) != PSTM_LT)
+ {
+ /* u = u - v, A = A - C, B = B - D */
+ if ((res = pstm_sub(&u, &v, &u)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ if ((res = pstm_sub(&A, &C, &A)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ if ((res = pstm_sub(&B, &D, &B)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ }
+ else
+ {
+ /* v - v - u, C = C - A, D = D - B */
+ if ((res = pstm_sub(&v, &u, &v)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ if ((res = pstm_sub(&C, &A, &C)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ if ((res = pstm_sub(&D, &B, &D)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ }
- /* if not zero goto step 4 */
- if (pstm_iszero(&u) == 0)
- goto top;
+ /* if not zero goto step 4 */
+ if (pstm_iszero(&u) == 0)
+ {
+ goto top;
+ }
- /* now a = C, b = D, gcd == g*v */
+ /* now a = C, b = D, gcd == g*v */
- /* if v != 1 then there is no inverse */
- if (pstm_cmp_d(&v, 1) != PSTM_EQ) {
- res = PS_FAILURE;
- goto LBL_C;
- }
+ /* if v != 1 then there is no inverse */
+ if (pstm_cmp_d(&v, 1) != PSTM_EQ)
+ {
+ res = PS_FAILURE;
+ goto LBL_C;
+ }
- /* if its too low */
- while (pstm_cmp_d(&C, 0) == PSTM_LT) {
- if ((res = pstm_add(&C, b, &C)) != PSTM_OKAY) {
- goto LBL_C;
- }
- }
+ /* if its too low */
+ while (pstm_cmp_d(&C, 0) == PSTM_LT)
+ {
+ if ((res = pstm_add(&C, b, &C)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ }
- /* too big */
- while (pstm_cmp_mag(&C, b) != PSTM_LT) {
- if ((res = pstm_sub(&C, b, &C)) != PSTM_OKAY) {
- goto LBL_C;
- }
- }
+ /* too big */
+ while (pstm_cmp_mag(&C, b) != PSTM_LT)
+ {
+ if ((res = pstm_sub(&C, b, &C)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ }
- /* C is now the inverse */
- if ((res = pstm_copy(&C, c)) != PSTM_OKAY) {
- goto LBL_C;
- }
- res = PSTM_OKAY;
+ /* C is now the inverse */
+ if ((res = pstm_copy(&C, c)) != PSTM_OKAY)
+ {
+ goto LBL_C;
+ }
+ res = PSTM_OKAY;
LBL_C: pstm_clear(&C);
LBL_D: pstm_clear(&D);
@@ -2349,143 +2762,174 @@ LBL_U: pstm_clear(&u);
LBL_Y: pstm_clear(&y);
LBL_X: pstm_clear(&x);
- return res;
+ return res;
}
/**
- c = 1/a (mod b).
- This code is for for odd 'b'. pstm_invmod_slow() will be called if 'b'
- is even.
-*/
+ c = 1/a (mod b).
+ This code is for for odd 'b'. pstm_invmod_slow() will be called if 'b'
+ is even.
+ */
int32_t pstm_invmod(psPool_t *pool, const pstm_int *a, const pstm_int *b, pstm_int *c)
{
- pstm_int x, y, u, v, B, D;
- int32 res;
- uint16 neg, sanity;
+ pstm_int x, y, u, v, B, D;
+ int32 res;
+ uint16 neg, sanity;
- /* 2. [modified] b must be odd */
- if (pstm_iseven (b) == 1) {
- return pstm_invmod_slow(pool, a,b,c);
- }
+ /* 2. [modified] b must be odd */
+ if (pstm_iseven(b) == 1)
+ {
+ return pstm_invmod_slow(pool, a, b, c);
+ }
- /* x == modulus, y == value to invert */
- if ((res = pstm_init_copy(pool, &x, b, 0)) != PSTM_OKAY) {
- return res;
- }
+ /* x == modulus, y == value to invert */
+ if ((res = pstm_init_copy(pool, &x, b, 0)) != PSTM_OKAY)
+ {
+ return res;
+ }
- if ((res = pstm_init_size(pool, &y, a->alloc)) != PSTM_OKAY) {
- goto LBL_X;
- }
+ if ((res = pstm_init_size(pool, &y, a->alloc)) != PSTM_OKAY)
+ {
+ goto LBL_X;
+ }
- /* we need y = |a| */
- if ((res = pstm_abs(a, &y)) != PSTM_OKAY) {
- goto LBL_X;
- }
+ /* we need y = |a| */
+ if ((res = pstm_abs(a, &y)) != PSTM_OKAY)
+ {
+ goto LBL_X;
+ }
- /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
- if ((res = pstm_init_copy(pool, &u, &x, 0)) != PSTM_OKAY) {
- goto LBL_Y;
- }
- if ((res = pstm_init_copy(pool, &v, &y, 0)) != PSTM_OKAY) {
- goto LBL_U;
- }
- if ((res = pstm_init(pool, &B)) != PSTM_OKAY) {
- goto LBL_V;
- }
- if ((res = pstm_init(pool, &D)) != PSTM_OKAY) {
- goto LBL_B;
- }
+ /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
+ if ((res = pstm_init_copy(pool, &u, &x, 0)) != PSTM_OKAY)
+ {
+ goto LBL_Y;
+ }
+ if ((res = pstm_init_copy(pool, &v, &y, 0)) != PSTM_OKAY)
+ {
+ goto LBL_U;
+ }
+ if ((res = pstm_init(pool, &B)) != PSTM_OKAY)
+ {
+ goto LBL_V;
+ }
+ if ((res = pstm_init(pool, &D)) != PSTM_OKAY)
+ {
+ goto LBL_B;
+ }
- pstm_set (&D, 1);
+ pstm_set(&D, 1);
- sanity = 0;
+ sanity = 0;
top:
- /* 4. while u is even do */
- while (pstm_iseven (&u) == 1) {
- /* 4.1 u = u/2 */
- if ((res = pstm_div_2 (&u, &u)) != PSTM_OKAY) {
- goto LBL_D;
- }
+ /* 4. while u is even do */
+ while (pstm_iseven(&u) == 1)
+ {
+ /* 4.1 u = u/2 */
+ if ((res = pstm_div_2(&u, &u)) != PSTM_OKAY)
+ {
+ goto LBL_D;
+ }
- /* 4.2 if B is odd then */
- if (pstm_isodd (&B) == 1) {
- if ((res = pstm_sub (&B, &x, &B)) != PSTM_OKAY) {
- goto LBL_D;
- }
- }
- /* B = B/2 */
- if ((res = pstm_div_2 (&B, &B)) != PSTM_OKAY) {
- goto LBL_D;
- }
- }
+ /* 4.2 if B is odd then */
+ if (pstm_isodd(&B) == 1)
+ {
+ if ((res = pstm_sub(&B, &x, &B)) != PSTM_OKAY)
+ {
+ goto LBL_D;
+ }
+ }
+ /* B = B/2 */
+ if ((res = pstm_div_2(&B, &B)) != PSTM_OKAY)
+ {
+ goto LBL_D;
+ }
+ }
- /* 5. while v is even do */
- while (pstm_iseven (&v) == 1) {
- /* 5.1 v = v/2 */
- if ((res = pstm_div_2 (&v, &v)) != PSTM_OKAY) {
- goto LBL_D;
- }
- /* 5.2 if D is odd then */
- if (pstm_isodd (&D) == 1) {
- /* D = (D-x)/2 */
- if ((res = pstm_sub (&D, &x, &D)) != PSTM_OKAY) {
- goto LBL_D;
- }
- }
- /* D = D/2 */
- if ((res = pstm_div_2 (&D, &D)) != PSTM_OKAY) {
- goto LBL_D;
- }
- }
+ /* 5. while v is even do */
+ while (pstm_iseven(&v) == 1)
+ {
+ /* 5.1 v = v/2 */
+ if ((res = pstm_div_2(&v, &v)) != PSTM_OKAY)
+ {
+ goto LBL_D;
+ }
+ /* 5.2 if D is odd then */
+ if (pstm_isodd(&D) == 1)
+ {
+ /* D = (D-x)/2 */
+ if ((res = pstm_sub(&D, &x, &D)) != PSTM_OKAY)
+ {
+ goto LBL_D;
+ }
+ }
+ /* D = D/2 */
+ if ((res = pstm_div_2(&D, &D)) != PSTM_OKAY)
+ {
+ goto LBL_D;
+ }
+ }
- /* 6. if u >= v then */
- if (pstm_cmp(&u, &v) != PSTM_LT) {
- /* u = u - v, B = B - D */
- if ((res = pstm_sub (&u, &v, &u)) != PSTM_OKAY) {
- goto LBL_D;
- }
- if ((res = pstm_sub (&B, &D, &B)) != PSTM_OKAY) {
- goto LBL_D;
- }
- } else {
- /* v - v - u, D = D - B */
- if ((res = pstm_sub (&v, &u, &v)) != PSTM_OKAY) {
- goto LBL_D;
- }
- if ((res = pstm_sub (&D, &B, &D)) != PSTM_OKAY) {
- goto LBL_D;
- }
- }
+ /* 6. if u >= v then */
+ if (pstm_cmp(&u, &v) != PSTM_LT)
+ {
+ /* u = u - v, B = B - D */
+ if ((res = pstm_sub(&u, &v, &u)) != PSTM_OKAY)
+ {
+ goto LBL_D;
+ }
+ if ((res = pstm_sub(&B, &D, &B)) != PSTM_OKAY)
+ {
+ goto LBL_D;
+ }
+ }
+ else
+ {
+ /* v - v - u, D = D - B */
+ if ((res = pstm_sub(&v, &u, &v)) != PSTM_OKAY)
+ {
+ goto LBL_D;
+ }
+ if ((res = pstm_sub(&D, &B, &D)) != PSTM_OKAY)
+ {
+ goto LBL_D;
+ }
+ }
- /* if not zero goto step 4 */
- if (sanity++ > 4096) {
- res = PS_LIMIT_FAIL;
- goto LBL_D;
- }
- if (pstm_iszero (&u) == 0) {
- goto top;
- }
+ /* if not zero goto step 4 */
+ if (sanity++ > 4096)
+ {
+ res = PS_LIMIT_FAIL;
+ goto LBL_D;
+ }
+ if (pstm_iszero(&u) == 0)
+ {
+ goto top;
+ }
- /* now a = C, b = D, gcd == g*v */
+ /* now a = C, b = D, gcd == g*v */
- /* if v != 1 then there is no inverse */
- if (pstm_cmp_d(&v, 1) != PSTM_EQ) {
- res = PS_FAILURE;
- goto LBL_D;
- }
+ /* if v != 1 then there is no inverse */
+ if (pstm_cmp_d(&v, 1) != PSTM_EQ)
+ {
+ res = PS_FAILURE;
+ goto LBL_D;
+ }
- /* b is now the inverse */
- neg = a->sign;
- while (D.sign == PSTM_NEG) {
- if ((res = pstm_add (&D, b, &D)) != PSTM_OKAY) {
- goto LBL_D;
- }
- }
- if ((res = pstm_copy (&D, c)) != PSTM_OKAY) {
- goto LBL_D;
- }
- c->sign = neg;
- res = PSTM_OKAY;
+ /* b is now the inverse */
+ neg = a->sign;
+ while (D.sign == PSTM_NEG)
+ {
+ if ((res = pstm_add(&D, b, &D)) != PSTM_OKAY)
+ {
+ goto LBL_D;
+ }
+ }
+ if ((res = pstm_copy(&D, c)) != PSTM_OKAY)
+ {
+ goto LBL_D;
+ }
+ c->sign = neg;
+ res = PSTM_OKAY;
LBL_D: pstm_clear(&D);
LBL_B: pstm_clear(&B);
@@ -2493,12 +2937,12 @@ LBL_V: pstm_clear(&v);
LBL_U: pstm_clear(&u);
LBL_Y: pstm_clear(&y);
LBL_X: pstm_clear(&x);
- return res;
+ return res;
}
/******************************************************************************/
-#endif /* USE_MATRIX_RSA || USE_MATRIX_ECC || USE_MATRIX_DH || USE_CL_RSA || USE_CL_DH || USE_QUICK_ASSIST_RSA || USE_QUICK_ASSIST_ECC */
+#endif /* USE_MATRIX_RSA || USE_MATRIX_ECC || USE_MATRIX_DH || USE_CL_RSA || USE_CL_DH || USE_QUICK_ASSIST_RSA || USE_QUICK_ASSIST_ECC */
/******************************************************************************/
diff --git a/crypto/math/pstm.h b/crypto/math/pstm.h
index d49ece3..0e7ebfd 100644
--- a/crypto/math/pstm.h
+++ b/crypto/math/pstm.h
@@ -1,174 +1,176 @@
/**
- * @file pstm.h
- * @version $Format:%h%d$
+ * @file pstm.h
+ * @version $Format:%h%d$
*
- * multiple-precision integer library.
+ * multiple-precision integer library.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
#ifndef _h_PSTMATH
-#define _h_PSTMATH
+# define _h_PSTMATH
-#include "../cryptoApi.h"
+# include "../cryptoApi.h"
-#if defined(USE_MATRIX_RSA) || defined(USE_MATRIX_ECC) || defined(USE_MATRIX_DH) || defined(USE_CL_RSA) || defined(USE_CL_DH) || defined(USE_QUICK_ASSIST_RSA) || defined(USE_QUICK_ASSIST_ECC)
+# if defined(USE_MATRIX_RSA) || defined(USE_MATRIX_ECC) || defined(USE_MATRIX_DH) || defined(USE_CL_RSA) || defined(USE_CL_DH) || defined(USE_QUICK_ASSIST_RSA) || defined(USE_QUICK_ASSIST_ECC)
-#if defined(PS_PUBKEY_OPTIMIZE_FOR_FASTER_SPEED) && defined(PS_PUBKEY_OPTIMIZE_FOR_SMALLER_RAM)
-#error "May only enable either PS_PUBKEY_OPTIMIZE_FOR_FASTER_SPEED or PS_PUBKEY_OPTIMIZE_FOR_SMALLER_RAM"
-#endif
+# if defined(PS_PUBKEY_OPTIMIZE_FOR_FASTER_SPEED) && defined(PS_PUBKEY_OPTIMIZE_FOR_SMALLER_RAM)
+# error "May only enable either PS_PUBKEY_OPTIMIZE_FOR_FASTER_SPEED or PS_PUBKEY_OPTIMIZE_FOR_SMALLER_RAM"
+# endif
-#if !defined(PS_PUBKEY_OPTIMIZE_FOR_FASTER_SPEED) && !defined(PS_PUBKEY_OPTIMIZE_FOR_SMALLER_RAM)
-#define PS_PUBKEY_OPTIMIZE_FOR_SMALLER_RAM
-#endif
+# if !defined(PS_PUBKEY_OPTIMIZE_FOR_FASTER_SPEED) && !defined(PS_PUBKEY_OPTIMIZE_FOR_SMALLER_RAM)
+# define PS_PUBKEY_OPTIMIZE_FOR_SMALLER_RAM
+# endif
-#ifdef PS_PUBKEY_OPTIMIZE_FOR_SMALLER_RAM
-#define PS_EXPTMOD_WINSIZE 3
-#endif
+# ifdef PS_PUBKEY_OPTIMIZE_FOR_SMALLER_RAM
+# define PS_EXPTMOD_WINSIZE 3
+# endif
-#ifdef PS_PUBKEY_OPTIMIZE_FOR_FASTER_SPEED
-#define PS_EXPTMOD_WINSIZE 5
-#endif
+# ifdef PS_PUBKEY_OPTIMIZE_FOR_FASTER_SPEED
+# define PS_EXPTMOD_WINSIZE 5
+# endif
/******************************************************************************/
/* Define this here to avoid including circular limits.h on some platforms */
-#ifndef CHAR_BIT
- #define CHAR_BIT 8
-#endif
+# ifndef CHAR_BIT
+# define CHAR_BIT 8
+# endif
/******************************************************************************/
/*
- If native 64 bit integers are not supported, we do not support 32x32->64
- in hardware, so we must set the 16 bit flag to produce 16x16->32 products.
-*/
-#ifndef HAVE_NATIVE_INT64
- #define PSTM_16BIT
-#endif /* ! HAVE_NATIVE_INT64 */
-
-/******************************************************************************/
-/*
- Some default configurations.
-
- pstm_word should be the largest value the processor can hold as the product
- of a multiplication. Most platforms support a 32x32->64 MAC instruction,
- so 64bits is the default pstm_word size.
- pstm_digit should be half the size of pstm_word
+ If native 64 bit integers are not supported, we do not support 32x32->64
+ in hardware, so we must set the 16 bit flag to produce 16x16->32 products.
*/
-#ifdef PSTM_8BIT
-/* 8-bit digits, 16-bit word products */
- typedef unsigned char pstm_digit;
- typedef unsigned short pstm_word;
- #define DIGIT_BIT 8
-
-#elif defined(PSTM_16BIT)
-/* 16-bit digits, 32-bit word products */
- typedef unsigned short pstm_digit;
- typedef unsigned long pstm_word;
- #define DIGIT_BIT 16
-
-#elif defined(PSTM_64BIT)
-/* 64-bit digits, 128-bit word products */
- #ifndef __GNUC__
- #error "64bit digits requires GCC"
- #endif
- typedef unsigned long pstm_digit;
- typedef unsigned long pstm_word __attribute__ ((mode(TI)));
- #define DIGIT_BIT 64
-
-#else
-/* This is the default case, 32-bit digits, 64-bit word products */
- typedef uint32 pstm_digit;
- typedef uint64 pstm_word;
- #define DIGIT_BIT 32
- #define PSTM_32BIT
-#endif /* digit and word size */
-
-#define PSTM_MASK (pstm_digit)(-1)
-#define PSTM_DIGIT_MAX PSTM_MASK
+# ifndef HAVE_NATIVE_INT64
+# define PSTM_16BIT
+# endif /* ! HAVE_NATIVE_INT64 */
/******************************************************************************/
/*
- equalities
+ Some default configurations.
+
+ pstm_word should be the largest value the processor can hold as the product
+ of a multiplication. Most platforms support a 32x32->64 MAC instruction,
+ so 64bits is the default pstm_word size.
+ pstm_digit should be half the size of pstm_word
*/
-#define PSTM_LT -1 /* less than */
-#define PSTM_EQ 0 /* equal to */
-#define PSTM_GT 1 /* greater than */
+# ifdef PSTM_8BIT
+/* 8-bit digits, 16-bit word products */
+typedef unsigned char pstm_digit;
+typedef unsigned short pstm_word;
+# define DIGIT_BIT 8
-#define PSTM_ZPOS 0 /* pstm_int.sign positive */
-#define PSTM_NEG 1 /* pstm_int.sign negative */
+# elif defined(PSTM_16BIT)
+/* 16-bit digits, 32-bit word products */
+typedef unsigned short pstm_digit;
+typedef unsigned long pstm_word;
+# define DIGIT_BIT 16
-#define PSTM_OKAY PS_SUCCESS
-#define PSTM_MEM PS_MEM_FAIL
+# elif defined(PSTM_64BIT)
+/* 64-bit digits, 128-bit word products */
+# ifndef __GNUC__
+# error "64bit digits requires GCC"
+# endif
+typedef unsigned long pstm_digit;
+typedef unsigned long pstm_word __attribute__ ((mode(TI)));
+# define DIGIT_BIT 64
+
+# else
+/* This is the default case, 32-bit digits, 64-bit word products */
+typedef uint32 pstm_digit;
+typedef uint64 pstm_word;
+# define DIGIT_BIT 32
+# define PSTM_32BIT
+# endif /* digit and word size */
+
+# define PSTM_MASK (pstm_digit) (-1)
+# define PSTM_DIGIT_MAX PSTM_MASK
+
+/******************************************************************************/
+/*
+ equalities
+ */
+# define PSTM_LT -1 /* less than */
+# define PSTM_EQ 0 /* equal to */
+# define PSTM_GT 1 /* greater than */
+
+# define PSTM_ZPOS 0 /* pstm_int.sign positive */
+# define PSTM_NEG 1 /* pstm_int.sign negative */
+
+# define PSTM_OKAY PS_SUCCESS
+# define PSTM_MEM PS_MEM_FAIL
+# define PSTM_AVAILABLE 1
/* replies */
-#define PSTM_YES 1 /* yes response */
-#define PSTM_NO 0 /* no response */
+# define PSTM_YES 1 /* yes response */
+# define PSTM_NO 0 /* no response */
/******************************************************************************/
-/* This is the maximum size that pstm_int.alloc can be for crypto operations.
- Effectively, it is three times the size of the largest private key. */
-#define PSTM_MAX_SIZE ((4096 / DIGIT_BIT) * 3)
+/* This is the maximum size that pstm_int.alloc can be for crypto operations.
+ Effectively, it is three times the size of the largest private key. */
+# define PSTM_MAX_SIZE ((4096 / DIGIT_BIT) * 3)
-typedef struct {
- pstm_digit *dp;
- psPool_t *pool;
-#if defined (__GNUC__) || defined(__llvm__)
- /* Save a little space with compilers we know will handle this right */
- uint32_t used:12,
- alloc:12,
- sign:1;
-#else
- uint16_t used;
- uint16_t alloc;
- uint8_t sign;
-#endif
+typedef struct
+{
+ pstm_digit *dp;
+ psPool_t *pool;
+# if defined (__GNUC__) || defined(__llvm__)
+ /* Save a little space with compilers we know will handle this right */
+ uint32_t used : 12,
+ alloc : 12,
+ sign : 1;
+# else
+ uint16_t used;
+ uint16_t alloc;
+ uint8_t sign;
+# endif
} pstm_int;
/******************************************************************************/
/*
- Operations on large integers
+ Operations on large integers
*/
-#define pstm_iszero(a) (((a)->used == 0) ? PS_TRUE : PS_FALSE)
-#define pstm_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? PS_TRUE : PS_FALSE)
-#define pstm_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? PS_TRUE : PS_FALSE)
+# define pstm_iszero(a) (((a)->used == 0) ? PS_TRUE : PS_FALSE)
+# define pstm_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? PS_TRUE : PS_FALSE)
+# define pstm_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? PS_TRUE : PS_FALSE)
extern void pstm_set(pstm_int *a, pstm_digit b);
extern void pstm_zero(pstm_int *a);
extern int32_t pstm_init(psPool_t *pool, pstm_int *a);
-extern int32_t pstm_init_size(psPool_t *pool, pstm_int *a, uint16_t size);
+extern int32_t pstm_init_size(psPool_t *pool, pstm_int *a, psSize_t size);
extern int32_t pstm_init_copy(psPool_t *pool, pstm_int *a, const pstm_int *b,
- uint8_t toSqr);
+ uint8_t toSqr);
extern int32_t pstm_init_for_read_unsigned_bin(psPool_t *pool, pstm_int *a,
- uint16_t len);
+ psSize_t len);
-extern int32_t pstm_grow(pstm_int *a, uint16_t size);
+extern int32_t pstm_grow(pstm_int *a, psSize_t size);
extern void pstm_clamp(pstm_int *a);
extern int32_t pstm_copy(const pstm_int *a, pstm_int *b);
@@ -177,24 +179,24 @@ extern int32_t pstm_abs(const pstm_int *a, pstm_int *b);
extern void pstm_clear(pstm_int *a);
extern void pstm_clear_multi(
- pstm_int *mp0, pstm_int *mp1, pstm_int *mp2, pstm_int *mp3,
- pstm_int *mp4, pstm_int *mp5, pstm_int *mp6, pstm_int *mp7);
+ pstm_int *mp0, pstm_int *mp1, pstm_int *mp2, pstm_int *mp3,
+ pstm_int *mp4, pstm_int *mp5, pstm_int *mp6, pstm_int *mp7);
extern uint16_t pstm_unsigned_bin_size(const pstm_int *a);
extern uint16_t pstm_count_bits(const pstm_int *a);
extern int32_t pstm_read_unsigned_bin(pstm_int *a,
- const unsigned char *buf, uint16_t len);
-extern int32_t pstm_read_asn(psPool_t *pool, const unsigned char **pp, uint16_t len,
- pstm_int *a);
+ const unsigned char *buf, psSize_t len);
+extern int32_t pstm_read_asn(psPool_t *pool, const unsigned char **pp, psSize_t len,
+ pstm_int *a);
extern int32_t pstm_to_unsigned_bin(psPool_t *pool, const pstm_int *a,
- unsigned char *b);
+ unsigned char *b);
extern int32_t pstm_to_unsigned_bin_nr(psPool_t *pool, const pstm_int *a,
- unsigned char *b);
-#ifdef USE_ECC
+ unsigned char *b);
+# ifdef USE_ECC
extern int32_t pstm_read_radix(psPool_t *pool, pstm_int *a,
- const char *buf, uint16_t len, uint8_t radix);
-#endif
+ const char *buf, psSize_t len, uint8_t radix);
+# endif
extern int32_t pstm_cmp(const pstm_int *a, const pstm_int *b);
extern int32_t pstm_cmp_mag(const pstm_int *a, const pstm_int *b);
@@ -206,41 +208,41 @@ extern int32_t pstm_lshd(pstm_int *a, uint16_t b);
extern int32_t pstm_add(const pstm_int *a, const pstm_int *b, pstm_int *c);
extern int32_t pstm_add_d(psPool_t *pool, const pstm_int *a, pstm_digit b, pstm_int *c);
-extern int32_t s_pstm_sub(const pstm_int *a, const pstm_int *b, pstm_int *c);
+extern int32_t pstm_sub_s(const pstm_int *a, const pstm_int *b, pstm_int *c);
extern int32_t pstm_sub(const pstm_int *a, const pstm_int *b, pstm_int *c);
extern int32_t pstm_sub_d(psPool_t *pool, const pstm_int *a, pstm_digit b, pstm_int *c);
extern int32_t pstm_div(psPool_t *pool, const pstm_int *a, const pstm_int *b,
- pstm_int *c, pstm_int *d);
+ pstm_int *c, pstm_int *d);
extern int32_t pstm_div_2d(psPool_t *pool, const pstm_int *a, int16_t b,
- pstm_int *c, pstm_int *d);
+ pstm_int *c, pstm_int *d);
extern int32_t pstm_div_2(const pstm_int *a, pstm_int *b);
extern int32_t pstm_mod(psPool_t *pool, const pstm_int *a, const pstm_int *b,
- pstm_int *c);
+ pstm_int *c);
extern int32_t pstm_invmod(psPool_t *pool, const pstm_int *a, const pstm_int *b,
- pstm_int *c);
+ pstm_int *c);
extern int32_t pstm_mul_2(const pstm_int *a, pstm_int *b);
extern int32_t pstm_mulmod(psPool_t *pool, const pstm_int *a, const pstm_int *b,
- const pstm_int *c, pstm_int *d);
+ const pstm_int *c, pstm_int *d);
extern int32_t pstm_mul_comba(psPool_t *pool, const pstm_int *A, const pstm_int *B,
- pstm_int *C, pstm_digit *paD, uint16_t paDlen);
+ pstm_int *C, pstm_digit *paD, psSize_t paDlen);
extern int32_t pstm_mul_d(const pstm_int *a, const pstm_digit b, pstm_int *c);
extern int32_t pstm_sqr_comba(psPool_t *pool, const pstm_int *A, pstm_int *B,
- pstm_digit *paD, uint16_t paDlen);
+ pstm_digit *paD, psSize_t paDlen);
extern int32_t pstm_exptmod(psPool_t *pool, const pstm_int *G, const pstm_int *X,
- const pstm_int *P, pstm_int *Y);
+ const pstm_int *P, pstm_int *Y);
extern int32_t pstm_2expt(pstm_int *a, int16_t b);
extern int32_t pstm_montgomery_setup(const pstm_int *a, pstm_digit *rho);
extern int32_t pstm_montgomery_reduce(psPool_t *pool, pstm_int *a, const pstm_int *m,
- pstm_digit mp, pstm_digit *paD, uint16_t paDlen);
+ pstm_digit mp, pstm_digit *paD, psSize_t paDlen);
extern int32_t pstm_montgomery_calc_normalization(pstm_int *a, const pstm_int *b);
-#endif /* USE_MATRIX_RSA || USE_MATRIX_ECC || USE_MATRIX_DH || USE_CL_RSA || USE_CL_DH || USE_QUICK_ASSIST_RSA || USE_QUICK_ASSIST_ECC */
+# endif /* USE_MATRIX_RSA || USE_MATRIX_ECC || USE_MATRIX_DH || USE_CL_RSA || USE_CL_DH || USE_QUICK_ASSIST_RSA || USE_QUICK_ASSIST_ECC */
-#endif /* _h_PSTMATH */
+#endif /* _h_PSTMATH */
diff --git a/crypto/math/pstm_montgomery_reduce.c b/crypto/math/pstm_montgomery_reduce.c
index 7cd0c5a..71c4845 100644
--- a/crypto/math/pstm_montgomery_reduce.c
+++ b/crypto/math/pstm_montgomery_reduce.c
@@ -1,421 +1,438 @@
/**
- * @file pstm_montgomery_reduce.c
- * @version $Format:%h%d$
+ * @file pstm_montgomery_reduce.c
+ * @version $Format:%h%d$
*
- * Multiprecision Montgomery Reduction.
+ * Multiprecision Montgomery Reduction.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
#if defined(USE_MATRIX_RSA) || defined(USE_MATRIX_ECC) || defined(USE_MATRIX_DH)
/******************************************************************************/
-#if defined(PSTM_X86)
+# if defined(PSTM_X86)
/* x86-32 optimized for 32 bit platforms. For 64 bit mode use X86_64 instead */
-#if !defined(__GNUC__) || !defined(__i386__) || !defined(PSTM_32BIT)
-#error "PSTM_X86 option requires GCC and 32 bit mode x86 processor"
-#endif
-//#pragma message ("Using 32 bit x86 Assembly Optimizations")
+# if !defined(__GNUC__) || !defined(__i386__) || !defined(PSTM_32BIT)
+# error "PSTM_X86 option requires GCC and 32 bit mode x86 processor"
+# endif
+/* #pragma message ("Using 32 bit x86 Assembly Optimizations") */
-#define MONT_START
-#define MONT_FINI
-#define LOOP_END
-#define LOOP_START \
- mu = c[x] * mp
+# define MONT_START
+# define MONT_FINI
+# define LOOP_END
+# define LOOP_START \
+ mu = c[x] * mp
-#define INNERMUL \
-asm( \
- "movl %5,%%eax \n\t" \
- "mull %4 \n\t" \
- "addl %1,%%eax \n\t" \
- "adcl $0,%%edx \n\t" \
- "addl %%eax,%0 \n\t" \
- "adcl $0,%%edx \n\t" \
- "movl %%edx,%1 \n\t" \
-:"=g"(_c[LO]), "=r"(cy) \
-:"0"(_c[LO]), "1"(cy), "g"(mu), "g"(*tmpm++) \
-: "%eax", "%edx", "cc")
+# define INNERMUL \
+ asm ( \
+ "movl %5,%%eax \n\t" \
+ "mull %4 \n\t" \
+ "addl %1,%%eax \n\t" \
+ "adcl $0,%%edx \n\t" \
+ "addl %%eax,%0 \n\t" \
+ "adcl $0,%%edx \n\t" \
+ "movl %%edx,%1 \n\t" \
+ : "=g" (_c[LO]), "=r" (cy) \
+ : "0" (_c[LO]), "1" (cy), "g" (mu), "g" (*tmpm++) \
+ : "%eax", "%edx", "cc")
-#define PROPCARRY \
-asm( \
- "addl %1,%0 \n\t" \
- "setb %%al \n\t" \
- "movzbl %%al,%1 \n\t" \
-:"=g"(_c[LO]), "=r"(cy) \
-:"0"(_c[LO]), "1"(cy) \
-: "%eax", "cc")
+# define PROPCARRY \
+ asm ( \
+ "addl %1,%0 \n\t" \
+ "setb %%al \n\t" \
+ "movzbl %%al,%1 \n\t" \
+ : "=g" (_c[LO]), "=r" (cy) \
+ : "0" (_c[LO]), "1" (cy) \
+ : "%eax", "cc")
/******************************************************************************/
-#elif defined(PSTM_X86_64)
+# elif defined(PSTM_X86_64)
/* x86-64 optimized */
-#if !defined(__GNUC__) || !defined(__x86_64__) || !defined(PSTM_64BIT)
-#error "PSTM_X86_64 option requires PSTM_64BIT, GCC and 64 bit mode x86 processor"
-#endif
-//#pragma message ("Using 64 bit x86_64 Assembly Optimizations")
+# if !defined(__GNUC__) || !defined(__x86_64__) || !defined(PSTM_64BIT)
+# error "PSTM_X86_64 option requires PSTM_64BIT, GCC and 64 bit mode x86 processor"
+# endif
+/* #pragma message ("Using 64 bit x86_64 Assembly Optimizations") */
-#define MONT_START
-#define MONT_FINI
-#define LOOP_END
-#define LOOP_START \
-mu = c[x] * mp
+# define MONT_START
+# define MONT_FINI
+# define LOOP_END
+# define LOOP_START \
+ mu = c[x] * mp
-#define INNERMUL \
-asm( \
- "movq %5,%%rax \n\t" \
- "mulq %4 \n\t" \
- "addq %1,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "addq %%rax,%0 \n\t" \
- "adcq $0,%%rdx \n\t" \
- "movq %%rdx,%1 \n\t" \
- :"=g"(_c[LO]), "=r"(cy) \
- :"0"(_c[LO]), "1"(cy), "r"(mu), "r"(*tmpm++) \
- : "%rax", "%rdx", "cc")
+# define INNERMUL \
+ asm ( \
+ "movq %5,%%rax \n\t" \
+ "mulq %4 \n\t" \
+ "addq %1,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "addq %%rax,%0 \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "movq %%rdx,%1 \n\t" \
+ : "=g" (_c[LO]), "=r" (cy) \
+ : "0" (_c[LO]), "1" (cy), "r" (mu), "r" (*tmpm++) \
+ : "%rax", "%rdx", "cc")
-#define INNERMUL8 \
-asm( \
- "movq 0(%5),%%rax \n\t" \
- "movq 0(%2),%%r10 \n\t" \
- "movq 0x8(%5),%%r11 \n\t" \
- "mulq %4 \n\t" \
- "addq %%r10,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "movq 0x8(%2),%%r10 \n\t" \
- "addq %3,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "movq %%rax,0(%0) \n\t" \
- "movq %%rdx,%1 \n\t" \
- \
- "movq %%r11,%%rax \n\t" \
- "movq 0x10(%5),%%r11 \n\t" \
- "mulq %4 \n\t" \
- "addq %%r10,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "movq 0x10(%2),%%r10 \n\t" \
- "addq %3,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "movq %%rax,0x8(%0) \n\t" \
- "movq %%rdx,%1 \n\t" \
- \
- "movq %%r11,%%rax \n\t" \
- "movq 0x18(%5),%%r11 \n\t" \
- "mulq %4 \n\t" \
- "addq %%r10,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "movq 0x18(%2),%%r10 \n\t" \
- "addq %3,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "movq %%rax,0x10(%0) \n\t" \
- "movq %%rdx,%1 \n\t" \
- \
- "movq %%r11,%%rax \n\t" \
- "movq 0x20(%5),%%r11 \n\t" \
- "mulq %4 \n\t" \
- "addq %%r10,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "movq 0x20(%2),%%r10 \n\t" \
- "addq %3,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "movq %%rax,0x18(%0) \n\t" \
- "movq %%rdx,%1 \n\t" \
- \
- "movq %%r11,%%rax \n\t" \
- "movq 0x28(%5),%%r11 \n\t" \
- "mulq %4 \n\t" \
- "addq %%r10,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "movq 0x28(%2),%%r10 \n\t" \
- "addq %3,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "movq %%rax,0x20(%0) \n\t" \
- "movq %%rdx,%1 \n\t" \
- \
- "movq %%r11,%%rax \n\t" \
- "movq 0x30(%5),%%r11 \n\t" \
- "mulq %4 \n\t" \
- "addq %%r10,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "movq 0x30(%2),%%r10 \n\t" \
- "addq %3,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "movq %%rax,0x28(%0) \n\t" \
- "movq %%rdx,%1 \n\t" \
- \
- "movq %%r11,%%rax \n\t" \
- "movq 0x38(%5),%%r11 \n\t" \
- "mulq %4 \n\t" \
- "addq %%r10,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "movq 0x38(%2),%%r10 \n\t" \
- "addq %3,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "movq %%rax,0x30(%0) \n\t" \
- "movq %%rdx,%1 \n\t" \
- \
- "movq %%r11,%%rax \n\t" \
- "mulq %4 \n\t" \
- "addq %%r10,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "addq %3,%%rax \n\t" \
- "adcq $0,%%rdx \n\t" \
- "movq %%rax,0x38(%0) \n\t" \
- "movq %%rdx,%1 \n\t" \
- \
- :"=r"(_c), "=r"(cy) \
- : "0"(_c), "1"(cy), "g"(mu), "r"(tmpm)\
- : "%rax", "%rdx", "%r10", "%r11", "cc")
+# define INNERMUL8 \
+ asm ( \
+ "movq 0(%5),%%rax \n\t" \
+ "movq 0(%2),%%r10 \n\t" \
+ "movq 0x8(%5),%%r11 \n\t" \
+ "mulq %4 \n\t" \
+ "addq %%r10,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "movq 0x8(%2),%%r10 \n\t" \
+ "addq %3,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "movq %%rax,0(%0) \n\t" \
+ "movq %%rdx,%1 \n\t" \
+ \
+ "movq %%r11,%%rax \n\t" \
+ "movq 0x10(%5),%%r11 \n\t" \
+ "mulq %4 \n\t" \
+ "addq %%r10,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "movq 0x10(%2),%%r10 \n\t" \
+ "addq %3,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "movq %%rax,0x8(%0) \n\t" \
+ "movq %%rdx,%1 \n\t" \
+ \
+ "movq %%r11,%%rax \n\t" \
+ "movq 0x18(%5),%%r11 \n\t" \
+ "mulq %4 \n\t" \
+ "addq %%r10,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "movq 0x18(%2),%%r10 \n\t" \
+ "addq %3,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "movq %%rax,0x10(%0) \n\t" \
+ "movq %%rdx,%1 \n\t" \
+ \
+ "movq %%r11,%%rax \n\t" \
+ "movq 0x20(%5),%%r11 \n\t" \
+ "mulq %4 \n\t" \
+ "addq %%r10,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "movq 0x20(%2),%%r10 \n\t" \
+ "addq %3,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "movq %%rax,0x18(%0) \n\t" \
+ "movq %%rdx,%1 \n\t" \
+ \
+ "movq %%r11,%%rax \n\t" \
+ "movq 0x28(%5),%%r11 \n\t" \
+ "mulq %4 \n\t" \
+ "addq %%r10,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "movq 0x28(%2),%%r10 \n\t" \
+ "addq %3,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "movq %%rax,0x20(%0) \n\t" \
+ "movq %%rdx,%1 \n\t" \
+ \
+ "movq %%r11,%%rax \n\t" \
+ "movq 0x30(%5),%%r11 \n\t" \
+ "mulq %4 \n\t" \
+ "addq %%r10,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "movq 0x30(%2),%%r10 \n\t" \
+ "addq %3,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "movq %%rax,0x28(%0) \n\t" \
+ "movq %%rdx,%1 \n\t" \
+ \
+ "movq %%r11,%%rax \n\t" \
+ "movq 0x38(%5),%%r11 \n\t" \
+ "mulq %4 \n\t" \
+ "addq %%r10,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "movq 0x38(%2),%%r10 \n\t" \
+ "addq %3,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "movq %%rax,0x30(%0) \n\t" \
+ "movq %%rdx,%1 \n\t" \
+ \
+ "movq %%r11,%%rax \n\t" \
+ "mulq %4 \n\t" \
+ "addq %%r10,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "addq %3,%%rax \n\t" \
+ "adcq $0,%%rdx \n\t" \
+ "movq %%rax,0x38(%0) \n\t" \
+ "movq %%rdx,%1 \n\t" \
+ \
+ : "=r" (_c), "=r" (cy) \
+ : "0" (_c), "1" (cy), "g" (mu), "r" (tmpm) \
+ : "%rax", "%rdx", "%r10", "%r11", "cc")
-#define PROPCARRY \
-asm( \
- "addq %1,%0 \n\t" \
- "setb %%al \n\t" \
- "movzbq %%al,%1 \n\t" \
- :"=g"(_c[LO]), "=r"(cy) \
- :"0"(_c[LO]), "1"(cy) \
- : "%rax", "cc")
+# define PROPCARRY \
+ asm ( \
+ "addq %1,%0 \n\t" \
+ "setb %%al \n\t" \
+ "movzbq %%al,%1 \n\t" \
+ : "=g" (_c[LO]), "=r" (cy) \
+ : "0" (_c[LO]), "1" (cy) \
+ : "%rax", "cc")
/******************************************************************************/
-#elif defined(PSTM_ARM)
+# elif defined(PSTM_ARM)
-#define MONT_START
-#define MONT_FINI
-#define LOOP_END
-#define LOOP_START \
-mu = c[x] * mp
+# define MONT_START
+# define MONT_FINI
+# define LOOP_END
+# define LOOP_START \
+ mu = c[x] * mp
-#ifdef __thumb2__
-//#pragma message ("Using 32 bit ARM Thumb2 Assembly Optimizations")
-#define INNERMUL \
-asm( \
- " LDR r0,%1 \n\t" \
- " ADDS r0,r0,%0 \n\t" \
- " ITE CS \n\t" \
- " MOVCS %0,#1 \n\t" \
- " MOVCC %0,#0 \n\t" \
- " UMLAL r0,%0,%3,%4 \n\t" \
- " STR r0,%1 \n\t" \
- :"=r"(cy),"=m"(_c[0])\
- :"0"(cy),"r"(mu),"r"(*tmpm++),"m"(_c[0])\
- :"r0","cc");
-#define PROPCARRY \
-asm( \
- " LDR r0,%1 \n\t" \
- " ADDS r0,r0,%0 \n\t" \
- " STR r0,%1 \n\t" \
- " ITE CS \n\t" \
- " MOVCS %0,#1 \n\t" \
- " MOVCC %0,#0 \n\t" \
- :"=r"(cy),"=m"(_c[0])\
- :"0"(cy),"m"(_c[0])\
- :"r0","cc");
-#else /* Non-Thumb2 code */
-//#pragma message ("Using 32 bit ARM Assembly Optimizations")
-#define INNERMUL \
-asm( \
- " LDR r0,%1 \n\t" \
- " ADDS r0,r0,%0 \n\t" \
- " MOVCS %0,#1 \n\t" \
- " MOVCC %0,#0 \n\t" \
- " UMLAL r0,%0,%3,%4 \n\t" \
- " STR r0,%1 \n\t" \
- :"=r"(cy),"=m"(_c[0])\
- :"0"(cy),"r"(mu),"r"(*tmpm++),"m"(_c[0])\
- :"r0","cc");
-#define PROPCARRY \
-asm( \
- " LDR r0,%1 \n\t" \
- " ADDS r0,r0,%0 \n\t" \
- " STR r0,%1 \n\t" \
- " MOVCS %0,#1 \n\t" \
- " MOVCC %0,#0 \n\t" \
- :"=r"(cy),"=m"(_c[0])\
- :"0"(cy),"m"(_c[0])\
- :"r0","cc");
-#endif /* __thumb2__ */
+# ifdef __thumb2__
+/* #pragma message ("Using 32 bit ARM Thumb2 Assembly Optimizations") */
+# define INNERMUL \
+ asm ( \
+ " LDR r0,%1 \n\t" \
+ " ADDS r0,r0,%0 \n\t" \
+ " ITE CS \n\t" \
+ " MOVCS %0,#1 \n\t" \
+ " MOVCC %0,#0 \n\t" \
+ " UMLAL r0,%0,%3,%4 \n\t" \
+ " STR r0,%1 \n\t" \
+ : "=r" (cy), "=m" (_c[0]) \
+ : "0" (cy), "r" (mu), "r" (*tmpm++), "m" (_c[0]) \
+ : "r0", "cc");
+# define PROPCARRY \
+ asm ( \
+ " LDR r0,%1 \n\t" \
+ " ADDS r0,r0,%0 \n\t" \
+ " STR r0,%1 \n\t" \
+ " ITE CS \n\t" \
+ " MOVCS %0,#1 \n\t" \
+ " MOVCC %0,#0 \n\t" \
+ : "=r" (cy), "=m" (_c[0]) \
+ : "0" (cy), "m" (_c[0]) \
+ : "r0", "cc");
+# else /* Non-Thumb2 code */
+/* #pragma message ("Using 32 bit ARM Assembly Optimizations") */
+# define INNERMUL \
+ asm ( \
+ " LDR r0,%1 \n\t" \
+ " ADDS r0,r0,%0 \n\t" \
+ " MOVCS %0,#1 \n\t" \
+ " MOVCC %0,#0 \n\t" \
+ " UMLAL r0,%0,%3,%4 \n\t" \
+ " STR r0,%1 \n\t" \
+ : "=r" (cy), "=m" (_c[0]) \
+ : "0" (cy), "r" (mu), "r" (*tmpm++), "m" (_c[0]) \
+ : "r0", "cc");
+# define PROPCARRY \
+ asm ( \
+ " LDR r0,%1 \n\t" \
+ " ADDS r0,r0,%0 \n\t" \
+ " STR r0,%1 \n\t" \
+ " MOVCS %0,#1 \n\t" \
+ " MOVCC %0,#0 \n\t" \
+ : "=r" (cy), "=m" (_c[0]) \
+ : "0" (cy), "m" (_c[0]) \
+ : "r0", "cc");
+# endif /* __thumb2__ */
/******************************************************************************/
-#elif defined(PSTM_MIPS)
+# elif defined(PSTM_MIPS)
/* MIPS32 */
-//#pragma message ("Using 32 bit MIPS Assembly Optimizations")
-#define MONT_START
-#define MONT_FINI
-#define LOOP_END
-#define LOOP_START \
-mu = c[x] * mp
+/* #pragma message ("Using 32 bit MIPS Assembly Optimizations") */
+# define MONT_START
+# define MONT_FINI
+# define LOOP_END
+# define LOOP_START \
+ mu = c[x] * mp
-#define INNERMUL \
-asm( \
- " multu %3,%4 \n\t" \
- " mflo $12 \n\t" \
- " mfhi $13 \n\t" \
- " addu $12,$12,%0 \n\t" \
- " sltu $10,$12,%0 \n\t" \
- " addu $13,$13,$10 \n\t" \
- " lw $10,%1 \n\t" \
- " addu $12,$12,$10 \n\t" \
- " sltu $10,$12,$10 \n\t" \
- " addu %0,$13,$10 \n\t" \
- " sw $12,%1 \n\t" \
- :"=r"(cy),"=m"(_c[0])\
- :"r"(cy),"r"(mu),"r"(tmpm[0]),"r"(_c[0])\
- :"$10","$12","$13")\
-; ++tmpm;
+# define INNERMUL \
+ asm ( \
+ " multu %3,%4 \n\t" \
+ " mflo $12 \n\t" \
+ " mfhi $13 \n\t" \
+ " addu $12,$12,%0 \n\t" \
+ " sltu $10,$12,%0 \n\t" \
+ " addu $13,$13,$10 \n\t" \
+ " lw $10,%1 \n\t" \
+ " addu $12,$12,$10 \n\t" \
+ " sltu $10,$12,$10 \n\t" \
+ " addu %0,$13,$10 \n\t" \
+ " sw $12,%1 \n\t" \
+ : "=r" (cy), "=m" (_c[0]) \
+ : "r" (cy), "r" (mu), "r" (tmpm[0]), "r" (_c[0]) \
+ : "$10", "$12", "$13") \
+ ; ++tmpm;
-#define PROPCARRY \
-asm( \
- " lw $10,%1 \n\t" \
- " addu $10,$10,%0 \n\t" \
- " sw $10,%1 \n\t" \
- " sltu %0,$10,%0 \n\t" \
- :"=r"(cy),"=m"(_c[0])\
- :"r"(cy),"r"(_c[0])\
- :"$10");
+# define PROPCARRY \
+ asm ( \
+ " lw $10,%1 \n\t" \
+ " addu $10,$10,%0 \n\t" \
+ " sw $10,%1 \n\t" \
+ " sltu %0,$10,%0 \n\t" \
+ : "=r" (cy), "=m" (_c[0]) \
+ : "r" (cy), "r" (_c[0]) \
+ : "$10");
/******************************************************************************/
-#else
+# else
/* ISO C code */
-#define MONT_START
-#define MONT_FINI
-#define LOOP_END
-#define LOOP_START \
- mu = c[x] * mp
+# define MONT_START
+# define MONT_FINI
+# define LOOP_END
+# define LOOP_START \
+ mu = c[x] * mp
-#define INNERMUL \
- do { pstm_word t; \
- t = ((pstm_word)_c[0] + (pstm_word)cy) + \
- (((pstm_word)mu) * ((pstm_word)*tmpm++)); \
- _c[0] = (pstm_digit)t; \
- cy = (pstm_digit)(t >> DIGIT_BIT); \
- } while (0)
+# define INNERMUL \
+ do { pstm_word t; \
+ t = ((pstm_word) _c[0] + (pstm_word) cy) + \
+ (((pstm_word) mu) * ((pstm_word) * tmpm++)); \
+ _c[0] = (pstm_digit) t; \
+ cy = (pstm_digit) (t >> DIGIT_BIT); \
+ } while (0)
-#define PROPCARRY \
- do { pstm_digit t = _c[0] += cy; cy = (t < cy); } while (0)
+# define PROPCARRY \
+ do { pstm_digit t = _c[0] += cy; cy = (t < cy); } while (0)
-#endif
+# endif
/******************************************************************************/
-#define LO 0
+# define LO 0
/**
- computes x/R == x (mod N) via Montgomery Reduction.
-*/
+ computes x/R == x (mod N) via Montgomery Reduction.
+ */
int32_t pstm_montgomery_reduce(psPool_t *pool, pstm_int *a, const pstm_int *m,
- pstm_digit mp, pstm_digit *paD, uint16_t paDlen)
+ pstm_digit mp, pstm_digit *paD, psSize_t paDlen)
{
- pstm_digit *c, *_c, *tmpm, mu;
- int32 oldused, x, y;
- int16 pa;
- uint32 cSize;
+ pstm_digit *c, *_c, *tmpm, mu;
+ int32 oldused, x, y;
+ int16 pa;
+ uint32 cSize;
- pa = m->used;
- if (pa > a->alloc) {
- /* Sanity test for bad numbers. This will confirm no buffer overruns */
- return PS_LIMIT_FAIL;
- }
+ pa = m->used;
+ if (pa > a->alloc)
+ {
+ /* Sanity test for bad numbers. This will confirm no buffer overruns */
+ return PS_LIMIT_FAIL;
+ }
- cSize = (2 * pa + 1) * sizeof(pstm_digit);
- if (paD && paDlen >= cSize) {
- c = paD;
- memset(c, 0x0, paDlen);
- } else {
- c = psMalloc(pool, cSize);
- if (c == NULL) {
- return PS_MEM_FAIL;
- } else {
- memset(c, 0x0, cSize);
- }
- }
- /* copy the input */
- oldused = a->used;
- for (x = 0; x < oldused; x++) {
- c[x] = a->dp[x];
- }
+ cSize = (2 * pa + 1) * sizeof(pstm_digit);
+ if (paD && paDlen >= cSize)
+ {
+ c = paD;
+ memset(c, 0x0, paDlen);
+ }
+ else
+ {
+ c = psMalloc(pool, cSize);
+ if (c == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ else
+ {
+ memset(c, 0x0, cSize);
+ }
+ }
+ /* copy the input */
+ oldused = a->used;
+ for (x = 0; x < oldused; x++)
+ {
+ c[x] = a->dp[x];
+ }
- MONT_START;
+ MONT_START;
- for (x = 0; x < pa; x++) {
- pstm_digit cy = 0;
- /* get Mu for this round */
- LOOP_START;
- _c = c + x;
- tmpm = m->dp;
- y = 0;
-#ifdef PSTM_X86_64
- for (; y < (pa & ~7); y += 8) {
- INNERMUL8;
- _c += 8;
- tmpm += 8;
- }
-#endif /* PSTM_X86_64 */
- for (; y < pa; y++) {
- INNERMUL;
- ++_c;
- }
- LOOP_END;
- while (cy) {
- PROPCARRY;
- ++_c;
- }
- }
- /* now copy out */
- _c = c + pa;
- tmpm = a->dp;
- for (x = 0; x < pa+1; x++) {
- *tmpm++ = *_c++;
- }
+ for (x = 0; x < pa; x++)
+ {
+ pstm_digit cy = 0;
+ /* get Mu for this round */
+ LOOP_START;
+ _c = c + x;
+ tmpm = m->dp;
+ y = 0;
+# ifdef PSTM_X86_64
+ for (; y < (pa & ~7); y += 8)
+ {
+ INNERMUL8;
+ _c += 8;
+ tmpm += 8;
+ }
+# endif /* PSTM_X86_64 */
+ for (; y < pa; y++)
+ {
+ INNERMUL;
+ ++_c;
+ }
+ LOOP_END;
+ while (cy)
+ {
+ PROPCARRY;
+ ++_c;
+ }
+ }
+ /* now copy out */
+ _c = c + pa;
+ tmpm = a->dp;
+ for (x = 0; x < pa + 1; x++)
+ {
+ *tmpm++ = *_c++;
+ }
- for (; x < oldused; x++) {
- *tmpm++ = 0;
- }
+ for (; x < oldused; x++)
+ {
+ *tmpm++ = 0;
+ }
- MONT_FINI;
+ MONT_FINI;
- a->used = pa+1;
- pstm_clamp(a);
+ a->used = pa + 1;
+ pstm_clamp(a);
- /* reuse x as return code */
- x = PSTM_OKAY;
+ /* reuse x as return code */
+ x = PSTM_OKAY;
- /* if A >= m then A = A - m */
- if (pstm_cmp_mag (a, m) != PSTM_LT) {
- if (s_pstm_sub (a, m, a) != PSTM_OKAY) {
- x = PS_MEM_FAIL;
- }
- }
- if (c && c != paD) {
- psFree(c, pool);
- }
- return x;
+ /* if A >= m then A = A - m */
+ if (pstm_cmp_mag(a, m) != PSTM_LT)
+ {
+ if (pstm_sub_s(a, m, a) != PSTM_OKAY)
+ {
+ x = PS_MEM_FAIL;
+ }
+ }
+ if (c && c != paD)
+ {
+ psFree(c, pool);
+ }
+ return x;
}
#endif /* defined(USE_MATRIX_RSA) || defined(USE_MATRIX_ECC) */
diff --git a/crypto/math/pstm_mul_comba.c b/crypto/math/pstm_mul_comba.c
index f81845c..b9fbbcf 100644
--- a/crypto/math/pstm_mul_comba.c
+++ b/crypto/math/pstm_mul_comba.c
@@ -1,773 +1,806 @@
/**
- * @file pstm_mul_comba.c
- * @version $Format:%h%d$
+ * @file pstm_mul_comba.c
+ * @version $Format:%h%d$
*
- * Multiprecision multiplication with Comba technique.
+ * Multiprecision multiplication with Comba technique.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
#if defined(USE_MATRIX_RSA) || defined(USE_MATRIX_ECC) || defined(USE_MATRIX_DH)
/******************************************************************************/
-#if defined(PSTM_X86)
+# if defined(PSTM_X86)
/* x86-32 optimized for 32 bit platforms. For 64 bit mode use X86_64 instead */
-#if !defined(__GNUC__) || !defined(__i386__) || !defined(PSTM_32BIT)
-#error "PSTM_X86 option requires GCC and 32 bit mode x86 processor"
-#endif
-//#pragma message ("Using 32 bit x86 Assembly Optimizations")
+# if !defined(__GNUC__) || !defined(__i386__) || !defined(PSTM_32BIT)
+# error "PSTM_X86 option requires GCC and 32 bit mode x86 processor"
+# endif
+/* #pragma message ("Using 32 bit x86 Assembly Optimizations") */
/* anything you need at the start */
-#define COMBA_START
+# define COMBA_START
/* clear the chaining variables */
-#define COMBA_CLEAR \
- c0 = c1 = c2 = 0;
+# define COMBA_CLEAR \
+ c0 = c1 = c2 = 0;
/* forward the carry to the next digit */
-#define COMBA_FORWARD \
- do { c0 = c1; c1 = c2; c2 = 0; } while (0);
+# define COMBA_FORWARD \
+ do { c0 = c1; c1 = c2; c2 = 0; } while (0);
/* store the first sum */
-#define COMBA_STORE(x) \
- x = c0;
+# define COMBA_STORE(x) \
+ x = c0;
/* store the second sum [carry] */
-#define COMBA_STORE2(x) \
- x = c1;
+# define COMBA_STORE2(x) \
+ x = c1;
/* anything you need at the end */
-#define COMBA_FINI
+# define COMBA_FINI
/* this should multiply i and j */
-#define MULADD(i, j) \
-asm( \
- "movl %6,%%eax \n\t" \
- "mull %7 \n\t" \
- "addl %%eax,%0 \n\t" \
- "adcl %%edx,%1 \n\t" \
- "adcl $0,%2 \n\t" \
- :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","cc");
+# define MULADD(i, j) \
+ asm ( \
+ "movl %6,%%eax \n\t" \
+ "mull %7 \n\t" \
+ "addl %%eax,%0 \n\t" \
+ "adcl %%edx,%1 \n\t" \
+ "adcl $0,%2 \n\t" \
+ : "=r" (c0), "=r" (c1), "=r" (c2) : "0" (c0), "1" (c1), "2" (c2), "m" (i), "m" (j) : "%eax", "%edx", "cc");
/******************************************************************************/
-#elif defined(PSTM_X86_64)
+# elif defined(PSTM_X86_64)
/* x86-64 optimized */
-#if !defined(__GNUC__) || !defined(__x86_64__) || !defined(PSTM_64BIT)
-#error "PSTM_X86_64 option requires PSTM_64BIT, GCC and 64 bit mode x86 processor"
-#endif
-//#pragma message ("Using 64 bit x86_64 Assembly Optimizations")
+# if !defined(__GNUC__) || !defined(__x86_64__) || !defined(PSTM_64BIT)
+# error "PSTM_X86_64 option requires PSTM_64BIT, GCC and 64 bit mode x86 processor"
+# endif
+/* #pragma message ("Using 64 bit x86_64 Assembly Optimizations") */
/* anything you need at the start */
-#define COMBA_START
+# define COMBA_START
/* clear the chaining variables */
-#define COMBA_CLEAR \
-c0 = c1 = c2 = 0;
+# define COMBA_CLEAR \
+ c0 = c1 = c2 = 0;
/* forward the carry to the next digit */
-#define COMBA_FORWARD \
-do { c0 = c1; c1 = c2; c2 = 0; } while (0);
+# define COMBA_FORWARD \
+ do { c0 = c1; c1 = c2; c2 = 0; } while (0);
/* store the first sum */
-#define COMBA_STORE(x) \
-x = c0;
+# define COMBA_STORE(x) \
+ x = c0;
/* store the second sum [carry] */
-#define COMBA_STORE2(x) \
-x = c1;
+# define COMBA_STORE2(x) \
+ x = c1;
/* anything you need at the end */
-#define COMBA_FINI
+# define COMBA_FINI
/* this should multiply i and j */
-#define MULADD(i, j) \
-asm ( \
- "movq %6,%%rax \n\t" \
- "mulq %7 \n\t" \
- "addq %%rax,%0 \n\t" \
- "adcq %%rdx,%1 \n\t" \
- "adcq $0,%2 \n\t" \
- :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","cc");
+# define MULADD(i, j) \
+ asm ( \
+ "movq %6,%%rax \n\t" \
+ "mulq %7 \n\t" \
+ "addq %%rax,%0 \n\t" \
+ "adcq %%rdx,%1 \n\t" \
+ "adcq $0,%2 \n\t" \
+ : "=r" (c0), "=r" (c1), "=r" (c2) : "0" (c0), "1" (c1), "2" (c2), "g" (i), "g" (j) : "%rax", "%rdx", "cc");
/******************************************************************************/
-#elif defined(PSTM_ARM)
+# elif defined(PSTM_ARM)
/* ARM code */
-//#pragma message ("Using 32 bit ARM Assembly Optimizations")
+/* #pragma message ("Using 32 bit ARM Assembly Optimizations") */
-#define COMBA_START
+# define COMBA_START
-#define COMBA_CLEAR \
-c0 = c1 = c2 = 0;
+# define COMBA_CLEAR \
+ c0 = c1 = c2 = 0;
-#define COMBA_FORWARD \
-do { c0 = c1; c1 = c2; c2 = 0; } while (0);
+# define COMBA_FORWARD \
+ do { c0 = c1; c1 = c2; c2 = 0; } while (0);
-#define COMBA_STORE(x) \
-x = c0;
+# define COMBA_STORE(x) \
+ x = c0;
-#define COMBA_STORE2(x) \
-x = c1;
+# define COMBA_STORE2(x) \
+ x = c1;
-#define COMBA_FINI
+# define COMBA_FINI
-#define MULADD(i, j) \
-asm( \
- " UMULL r0,r1,%6,%7 \n\t" \
- " ADDS %0,%0,r0 \n\t" \
- " ADCS %1,%1,r1 \n\t" \
- " ADC %2,%2,#0 \n\t" \
- :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j) : "r0", "r1", "cc");
+# define MULADD(i, j) \
+ asm ( \
+ " UMULL r0,r1,%6,%7 \n\t" \
+ " ADDS %0,%0,r0 \n\t" \
+ " ADCS %1,%1,r1 \n\t" \
+ " ADC %2,%2,#0 \n\t" \
+ : "=r" (c0), "=r" (c1), "=r" (c2) : "0" (c0), "1" (c1), "2" (c2), "r" (i), "r" (j) : "r0", "r1", "cc");
/******************************************************************************/
-#elif defined(PSTM_MIPS)
+# elif defined(PSTM_MIPS)
/* MIPS32 code */
-//#pragma message ("Using 32 bit MIPS Assembly Optimizations")
+/* #pragma message ("Using 32 bit MIPS Assembly Optimizations") */
-#define COMBA_START
+# define COMBA_START
-#define COMBA_CLEAR \
-c0 = c1 = c2 = 0;
+# define COMBA_CLEAR \
+ c0 = c1 = c2 = 0;
-#define COMBA_FORWARD \
-do { c0 = c1; c1 = c2; c2 = 0; } while (0);
+# define COMBA_FORWARD \
+ do { c0 = c1; c1 = c2; c2 = 0; } while (0);
-#define COMBA_STORE(x) \
-x = c0;
+# define COMBA_STORE(x) \
+ x = c0;
-#define COMBA_STORE2(x) \
-x = c1;
+# define COMBA_STORE2(x) \
+ x = c1;
-#define COMBA_FINI
+# define COMBA_FINI
-#define MULADD(i, j) \
-asm( \
- " multu %6,%7 \n\t" \
- " mflo $12 \n\t" \
- " mfhi $13 \n\t" \
- " addu %0,%0,$12 \n\t" \
- " sltu $12,%0,$12 \n\t" \
- " addu %1,%1,$13 \n\t" \
- " sltu $13,%1,$13 \n\t" \
- " addu %1,%1,$12 \n\t" \
- " sltu $12,%1,$12 \n\t" \
- " addu %2,%2,$13 \n\t" \
- " addu %2,%2,$12 \n\t" \
- :"=r"(c0), "=r"(c1), "=r"(c2):"0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j):"$12","$13");
+# define MULADD(i, j) \
+ asm ( \
+ " multu %6,%7 \n\t" \
+ " mflo $12 \n\t" \
+ " mfhi $13 \n\t" \
+ " addu %0,%0,$12 \n\t" \
+ " sltu $12,%0,$12 \n\t" \
+ " addu %1,%1,$13 \n\t" \
+ " sltu $13,%1,$13 \n\t" \
+ " addu %1,%1,$12 \n\t" \
+ " sltu $12,%1,$12 \n\t" \
+ " addu %2,%2,$13 \n\t" \
+ " addu %2,%2,$12 \n\t" \
+ : "=r" (c0), "=r" (c1), "=r" (c2) : "0" (c0), "1" (c1), "2" (c2), "r" (i), "r" (j) : "$12", "$13");
/******************************************************************************/
-#else
+# else
-#define COMBA_START
+# define COMBA_START
-#define COMBA_CLEAR \
- c0 = c1 = c2 = 0;
+# define COMBA_CLEAR \
+ c0 = c1 = c2 = 0;
-#define COMBA_FORWARD \
- do { c0 = c1; c1 = c2; c2 = 0; } while (0);
+# define COMBA_FORWARD \
+ do { c0 = c1; c1 = c2; c2 = 0; } while (0);
-#define COMBA_STORE(x) \
- x = c0;
+# define COMBA_STORE(x) \
+ x = c0;
-#define COMBA_STORE2(x) \
- x = c1;
+# define COMBA_STORE2(x) \
+ x = c1;
-#define COMBA_FINI
+# define COMBA_FINI
-#define MULADD(i, j) \
- do { pstm_word t; \
- t = (pstm_word)c0 + ((pstm_word)i) * ((pstm_word)j); c0 = (pstm_digit)t; \
- t = (pstm_word)c1 + (t >> DIGIT_BIT); \
- c1 = (pstm_digit)t; c2 += (pstm_digit)(t >> DIGIT_BIT); \
- } while (0);
+# define MULADD(i, j) \
+ do { pstm_word t; \
+ t = (pstm_word) c0 + ((pstm_word) i) * ((pstm_word) j); c0 = (pstm_digit) t; \
+ t = (pstm_word) c1 + (t >> DIGIT_BIT); \
+ c1 = (pstm_digit) t; c2 += (pstm_digit) (t >> DIGIT_BIT); \
+ } while (0);
-#endif
+# endif
/******************************************************************************/
/* generic PxQ multiplier */
static int32_t pstm_mul_comba_gen(psPool_t *pool, const pstm_int *A,
- const pstm_int *B, pstm_int *C,
- pstm_digit *paD, uint16_t paDlen)
+ const pstm_int *B, pstm_int *C,
+ pstm_digit *paD, psSize_t paDlen)
{
- int16 paDfail, pa;
- int32 ix, iy, iz, tx, ty;
- pstm_digit c0, c1, c2, *tmpx, *tmpy, *dst;
+ int16 paDfail, pa;
+ int32 ix, iy, iz, tx, ty;
+ pstm_digit c0, c1, c2, *tmpx, *tmpy, *dst;
- COMBA_START;
- COMBA_CLEAR;
+ COMBA_START;
+ COMBA_CLEAR;
- paDfail = 0;
- /* get size of output and trim */
- pa = A->used + B->used;
+ paDfail = 0;
+ /* get size of output and trim */
+ pa = A->used + B->used;
/*
- If c is not large enough grow it and continue
-*/
- if (C->alloc < pa) {
- if (pstm_grow(C, pa) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- }
- if (paD != NULL) {
- if (paDlen < (sizeof(pstm_digit) * pa)) {
- paDfail = 1; /* have a paD but it's not large enough */
- if ((dst = psMalloc(pool, sizeof(pstm_digit) * pa)) == NULL) {
- return PS_MEM_FAIL;
- }
- memset(dst, 0x0, sizeof(pstm_digit) * pa);
- } else {
- dst = paD;
- memset(dst, 0x0, paDlen);
- }
- } else {
- if ((dst = psMalloc(pool, sizeof(pstm_digit) * pa)) == NULL) {
- return PS_MEM_FAIL;
- }
- memset(dst, 0x0, sizeof(pstm_digit) * pa);
- }
-
- for (ix = 0; ix < pa; ix++) {
- /* get offsets into the two bignums */
- ty = min(ix, B->used-1);
- tx = ix - ty;
-
- /* setup temp aliases */
- tmpx = A->dp + tx;
- tmpy = B->dp + ty;
-/*
- This is the number of times the loop will iterate, essentially it's
- while (tx++ < a->used && ty-- >= 0) { ... }
-*/
- iy = min(A->used-tx, ty+1);
-
- /* execute loop */
- COMBA_FORWARD;
- for (iz = 0; iz < iy; ++iz) {
- MULADD(*tmpx++, *tmpy--);
- }
-
- /* store term */
- COMBA_STORE(dst[ix]);
- }
- COMBA_FINI;
-/*
- setup dest
+ If c is not large enough grow it and continue
*/
- iy = C->used;
- C->used = pa;
- C->sign = A->sign ^ B->sign;
- {
- pstm_digit *tmpc;
- tmpc = C->dp;
- for (ix = 0; ix < pa; ix++) {
- *tmpc++ = dst[ix];
- }
+ if (C->alloc < pa)
+ {
+ if (pstm_grow(C, pa) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ }
+ if (paD != NULL)
+ {
+ if (paDlen < (sizeof(pstm_digit) * pa))
+ {
+ paDfail = 1; /* have a paD but it's not large enough */
+ if ((dst = psMalloc(pool, sizeof(pstm_digit) * pa)) == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ memset(dst, 0x0, sizeof(pstm_digit) * pa);
+ }
+ else
+ {
+ dst = paD;
+ memset(dst, 0x0, paDlen);
+ }
+ }
+ else
+ {
+ if ((dst = psMalloc(pool, sizeof(pstm_digit) * pa)) == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ memset(dst, 0x0, sizeof(pstm_digit) * pa);
+ }
+
+ for (ix = 0; ix < pa; ix++)
+ {
+ /* get offsets into the two bignums */
+ ty = min(ix, B->used - 1);
+ tx = ix - ty;
+
+ /* setup temp aliases */
+ tmpx = A->dp + tx;
+ tmpy = B->dp + ty;
/*
- clear unused digits [that existed in the old copy of c]
+ This is the number of times the loop will iterate, essentially it's
+ while (tx++ < a->used && ty-- >= 0) { ... }
*/
- for (; ix < iy; ix++) {
- *tmpc++ = 0;
- }
- }
- pstm_clamp(C);
+ iy = min(A->used - tx, ty + 1);
- if ((paD == NULL) || (paDfail == 1)) {
- psFree(dst, pool);
- }
+ /* execute loop */
+ COMBA_FORWARD;
+ for (iz = 0; iz < iy; ++iz)
+ {
+ MULADD(*tmpx++, *tmpy--);
+ }
- return PS_SUCCESS;
+ /* store term */
+ COMBA_STORE(dst[ix]);
+ }
+ COMBA_FINI;
+/*
+ setup dest
+ */
+ iy = C->used;
+ C->used = pa;
+ C->sign = A->sign ^ B->sign;
+ {
+ pstm_digit *tmpc;
+ tmpc = C->dp;
+ for (ix = 0; ix < pa; ix++)
+ {
+ *tmpc++ = dst[ix];
+ }
+/*
+ clear unused digits [that existed in the old copy of c]
+ */
+ for (; ix < iy; ix++)
+ {
+ *tmpc++ = 0;
+ }
+ }
+ pstm_clamp(C);
+
+ if ((paD == NULL) || (paDfail == 1))
+ {
+ psFree(dst, pool);
+ }
+
+ return PS_SUCCESS;
}
/******************************************************************************/
-#ifdef USE_1024_KEY_SPEED_OPTIMIZATIONS
+# ifdef USE_1024_KEY_SPEED_OPTIMIZATIONS
static int32_t pstm_mul_comba16(const pstm_int *A, const pstm_int *B, pstm_int *C)
{
- pstm_digit c0, c1, c2, at[32];
+ pstm_digit c0, c1, c2, at[32];
- if (C->alloc < 32) {
- if (pstm_grow(C, 32) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- }
- memcpy(at, A->dp, 16 * sizeof(pstm_digit));
- memcpy(at+16, B->dp, 16 * sizeof(pstm_digit));
+ if (C->alloc < 32)
+ {
+ if (pstm_grow(C, 32) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ }
+ memcpy(at, A->dp, 16 * sizeof(pstm_digit));
+ memcpy(at + 16, B->dp, 16 * sizeof(pstm_digit));
- COMBA_START;
+ COMBA_START;
- COMBA_CLEAR;
- /* 0 */
- MULADD(at[0], at[16]);
- COMBA_STORE(C->dp[0]);
- /* 1 */
- COMBA_FORWARD;
- MULADD(at[0], at[17]); MULADD(at[1], at[16]);
- COMBA_STORE(C->dp[1]);
- /* 2 */
- COMBA_FORWARD;
- MULADD(at[0], at[18]); MULADD(at[1], at[17]); MULADD(at[2], at[16]);
- COMBA_STORE(C->dp[2]);
- /* 3 */
- COMBA_FORWARD;
- MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); MULADD(at[3], at[16]);
- COMBA_STORE(C->dp[3]);
- /* 4 */
- COMBA_FORWARD;
- MULADD(at[0], at[20]); MULADD(at[1], at[19]); MULADD(at[2], at[18]); MULADD(at[3], at[17]); MULADD(at[4], at[16]);
- COMBA_STORE(C->dp[4]);
- /* 5 */
- COMBA_FORWARD;
- MULADD(at[0], at[21]); MULADD(at[1], at[20]); MULADD(at[2], at[19]); MULADD(at[3], at[18]); MULADD(at[4], at[17]); MULADD(at[5], at[16]);
- COMBA_STORE(C->dp[5]);
- /* 6 */
- COMBA_FORWARD;
- MULADD(at[0], at[22]); MULADD(at[1], at[21]); MULADD(at[2], at[20]); MULADD(at[3], at[19]); MULADD(at[4], at[18]); MULADD(at[5], at[17]); MULADD(at[6], at[16]);
- COMBA_STORE(C->dp[6]);
- /* 7 */
- COMBA_FORWARD;
- MULADD(at[0], at[23]); MULADD(at[1], at[22]); MULADD(at[2], at[21]); MULADD(at[3], at[20]); MULADD(at[4], at[19]); MULADD(at[5], at[18]); MULADD(at[6], at[17]); MULADD(at[7], at[16]);
- COMBA_STORE(C->dp[7]);
- /* 8 */
- COMBA_FORWARD;
- MULADD(at[0], at[24]); MULADD(at[1], at[23]); MULADD(at[2], at[22]); MULADD(at[3], at[21]); MULADD(at[4], at[20]); MULADD(at[5], at[19]); MULADD(at[6], at[18]); MULADD(at[7], at[17]); MULADD(at[8], at[16]);
- COMBA_STORE(C->dp[8]);
- /* 9 */
- COMBA_FORWARD;
- MULADD(at[0], at[25]); MULADD(at[1], at[24]); MULADD(at[2], at[23]); MULADD(at[3], at[22]); MULADD(at[4], at[21]); MULADD(at[5], at[20]); MULADD(at[6], at[19]); MULADD(at[7], at[18]); MULADD(at[8], at[17]); MULADD(at[9], at[16]);
- COMBA_STORE(C->dp[9]);
- /* 10 */
- COMBA_FORWARD;
- MULADD(at[0], at[26]); MULADD(at[1], at[25]); MULADD(at[2], at[24]); MULADD(at[3], at[23]); MULADD(at[4], at[22]); MULADD(at[5], at[21]); MULADD(at[6], at[20]); MULADD(at[7], at[19]); MULADD(at[8], at[18]); MULADD(at[9], at[17]); MULADD(at[10], at[16]);
- COMBA_STORE(C->dp[10]);
- /* 11 */
- COMBA_FORWARD;
- MULADD(at[0], at[27]); MULADD(at[1], at[26]); MULADD(at[2], at[25]); MULADD(at[3], at[24]); MULADD(at[4], at[23]); MULADD(at[5], at[22]); MULADD(at[6], at[21]); MULADD(at[7], at[20]); MULADD(at[8], at[19]); MULADD(at[9], at[18]); MULADD(at[10], at[17]); MULADD(at[11], at[16]);
- COMBA_STORE(C->dp[11]);
- /* 12 */
- COMBA_FORWARD;
- MULADD(at[0], at[28]); MULADD(at[1], at[27]); MULADD(at[2], at[26]); MULADD(at[3], at[25]); MULADD(at[4], at[24]); MULADD(at[5], at[23]); MULADD(at[6], at[22]); MULADD(at[7], at[21]); MULADD(at[8], at[20]); MULADD(at[9], at[19]); MULADD(at[10], at[18]); MULADD(at[11], at[17]); MULADD(at[12], at[16]);
- COMBA_STORE(C->dp[12]);
- /* 13 */
- COMBA_FORWARD;
- MULADD(at[0], at[29]); MULADD(at[1], at[28]); MULADD(at[2], at[27]); MULADD(at[3], at[26]); MULADD(at[4], at[25]); MULADD(at[5], at[24]); MULADD(at[6], at[23]); MULADD(at[7], at[22]); MULADD(at[8], at[21]); MULADD(at[9], at[20]); MULADD(at[10], at[19]); MULADD(at[11], at[18]); MULADD(at[12], at[17]); MULADD(at[13], at[16]);
- COMBA_STORE(C->dp[13]);
- /* 14 */
- COMBA_FORWARD;
- MULADD(at[0], at[30]); MULADD(at[1], at[29]); MULADD(at[2], at[28]); MULADD(at[3], at[27]); MULADD(at[4], at[26]); MULADD(at[5], at[25]); MULADD(at[6], at[24]); MULADD(at[7], at[23]); MULADD(at[8], at[22]); MULADD(at[9], at[21]); MULADD(at[10], at[20]); MULADD(at[11], at[19]); MULADD(at[12], at[18]); MULADD(at[13], at[17]); MULADD(at[14], at[16]);
- COMBA_STORE(C->dp[14]);
- /* 15 */
- COMBA_FORWARD;
- MULADD(at[0], at[31]); MULADD(at[1], at[30]); MULADD(at[2], at[29]); MULADD(at[3], at[28]); MULADD(at[4], at[27]); MULADD(at[5], at[26]); MULADD(at[6], at[25]); MULADD(at[7], at[24]); MULADD(at[8], at[23]); MULADD(at[9], at[22]); MULADD(at[10], at[21]); MULADD(at[11], at[20]); MULADD(at[12], at[19]); MULADD(at[13], at[18]); MULADD(at[14], at[17]); MULADD(at[15], at[16]);
- COMBA_STORE(C->dp[15]);
- /* 16 */
- COMBA_FORWARD;
- MULADD(at[1], at[31]); MULADD(at[2], at[30]); MULADD(at[3], at[29]); MULADD(at[4], at[28]); MULADD(at[5], at[27]); MULADD(at[6], at[26]); MULADD(at[7], at[25]); MULADD(at[8], at[24]); MULADD(at[9], at[23]); MULADD(at[10], at[22]); MULADD(at[11], at[21]); MULADD(at[12], at[20]); MULADD(at[13], at[19]); MULADD(at[14], at[18]); MULADD(at[15], at[17]);
- COMBA_STORE(C->dp[16]);
- /* 17 */
- COMBA_FORWARD;
- MULADD(at[2], at[31]); MULADD(at[3], at[30]); MULADD(at[4], at[29]); MULADD(at[5], at[28]); MULADD(at[6], at[27]); MULADD(at[7], at[26]); MULADD(at[8], at[25]); MULADD(at[9], at[24]); MULADD(at[10], at[23]); MULADD(at[11], at[22]); MULADD(at[12], at[21]); MULADD(at[13], at[20]); MULADD(at[14], at[19]); MULADD(at[15], at[18]);
- COMBA_STORE(C->dp[17]);
- /* 18 */
- COMBA_FORWARD;
- MULADD(at[3], at[31]); MULADD(at[4], at[30]); MULADD(at[5], at[29]); MULADD(at[6], at[28]); MULADD(at[7], at[27]); MULADD(at[8], at[26]); MULADD(at[9], at[25]); MULADD(at[10], at[24]); MULADD(at[11], at[23]); MULADD(at[12], at[22]); MULADD(at[13], at[21]); MULADD(at[14], at[20]); MULADD(at[15], at[19]);
- COMBA_STORE(C->dp[18]);
- /* 19 */
- COMBA_FORWARD;
- MULADD(at[4], at[31]); MULADD(at[5], at[30]); MULADD(at[6], at[29]); MULADD(at[7], at[28]); MULADD(at[8], at[27]); MULADD(at[9], at[26]); MULADD(at[10], at[25]); MULADD(at[11], at[24]); MULADD(at[12], at[23]); MULADD(at[13], at[22]); MULADD(at[14], at[21]); MULADD(at[15], at[20]);
- COMBA_STORE(C->dp[19]);
- /* 20 */
- COMBA_FORWARD;
- MULADD(at[5], at[31]); MULADD(at[6], at[30]); MULADD(at[7], at[29]); MULADD(at[8], at[28]); MULADD(at[9], at[27]); MULADD(at[10], at[26]); MULADD(at[11], at[25]); MULADD(at[12], at[24]); MULADD(at[13], at[23]); MULADD(at[14], at[22]); MULADD(at[15], at[21]);
- COMBA_STORE(C->dp[20]);
- /* 21 */
- COMBA_FORWARD;
- MULADD(at[6], at[31]); MULADD(at[7], at[30]); MULADD(at[8], at[29]); MULADD(at[9], at[28]); MULADD(at[10], at[27]); MULADD(at[11], at[26]); MULADD(at[12], at[25]); MULADD(at[13], at[24]); MULADD(at[14], at[23]); MULADD(at[15], at[22]);
- COMBA_STORE(C->dp[21]);
- /* 22 */
- COMBA_FORWARD;
- MULADD(at[7], at[31]); MULADD(at[8], at[30]); MULADD(at[9], at[29]); MULADD(at[10], at[28]); MULADD(at[11], at[27]); MULADD(at[12], at[26]); MULADD(at[13], at[25]); MULADD(at[14], at[24]); MULADD(at[15], at[23]);
- COMBA_STORE(C->dp[22]);
- /* 23 */
- COMBA_FORWARD;
- MULADD(at[8], at[31]); MULADD(at[9], at[30]); MULADD(at[10], at[29]); MULADD(at[11], at[28]); MULADD(at[12], at[27]); MULADD(at[13], at[26]); MULADD(at[14], at[25]); MULADD(at[15], at[24]);
- COMBA_STORE(C->dp[23]);
- /* 24 */
- COMBA_FORWARD;
- MULADD(at[9], at[31]); MULADD(at[10], at[30]); MULADD(at[11], at[29]); MULADD(at[12], at[28]); MULADD(at[13], at[27]); MULADD(at[14], at[26]); MULADD(at[15], at[25]);
- COMBA_STORE(C->dp[24]);
- /* 25 */
- COMBA_FORWARD;
- MULADD(at[10], at[31]); MULADD(at[11], at[30]); MULADD(at[12], at[29]); MULADD(at[13], at[28]); MULADD(at[14], at[27]); MULADD(at[15], at[26]);
- COMBA_STORE(C->dp[25]);
- /* 26 */
- COMBA_FORWARD;
- MULADD(at[11], at[31]); MULADD(at[12], at[30]); MULADD(at[13], at[29]); MULADD(at[14], at[28]); MULADD(at[15], at[27]);
- COMBA_STORE(C->dp[26]);
- /* 27 */
- COMBA_FORWARD;
- MULADD(at[12], at[31]); MULADD(at[13], at[30]); MULADD(at[14], at[29]); MULADD(at[15], at[28]);
- COMBA_STORE(C->dp[27]);
- /* 28 */
- COMBA_FORWARD;
- MULADD(at[13], at[31]); MULADD(at[14], at[30]); MULADD(at[15], at[29]);
- COMBA_STORE(C->dp[28]);
- /* 29 */
- COMBA_FORWARD;
- MULADD(at[14], at[31]); MULADD(at[15], at[30]);
- COMBA_STORE(C->dp[29]);
- /* 30 */
- COMBA_FORWARD;
- MULADD(at[15], at[31]);
- COMBA_STORE(C->dp[30]);
- COMBA_STORE2(C->dp[31]);
- C->used = 32;
- C->sign = A->sign ^ B->sign;
- pstm_clamp(C);
- COMBA_FINI;
- return PSTM_OKAY;
+ COMBA_CLEAR;
+ /* 0 */
+ MULADD(at[0], at[16]);
+ COMBA_STORE(C->dp[0]);
+ /* 1 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[17]); MULADD(at[1], at[16]);
+ COMBA_STORE(C->dp[1]);
+ /* 2 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[18]); MULADD(at[1], at[17]); MULADD(at[2], at[16]);
+ COMBA_STORE(C->dp[2]);
+ /* 3 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); MULADD(at[3], at[16]);
+ COMBA_STORE(C->dp[3]);
+ /* 4 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[20]); MULADD(at[1], at[19]); MULADD(at[2], at[18]); MULADD(at[3], at[17]); MULADD(at[4], at[16]);
+ COMBA_STORE(C->dp[4]);
+ /* 5 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[21]); MULADD(at[1], at[20]); MULADD(at[2], at[19]); MULADD(at[3], at[18]); MULADD(at[4], at[17]); MULADD(at[5], at[16]);
+ COMBA_STORE(C->dp[5]);
+ /* 6 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[22]); MULADD(at[1], at[21]); MULADD(at[2], at[20]); MULADD(at[3], at[19]); MULADD(at[4], at[18]); MULADD(at[5], at[17]); MULADD(at[6], at[16]);
+ COMBA_STORE(C->dp[6]);
+ /* 7 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[23]); MULADD(at[1], at[22]); MULADD(at[2], at[21]); MULADD(at[3], at[20]); MULADD(at[4], at[19]); MULADD(at[5], at[18]); MULADD(at[6], at[17]); MULADD(at[7], at[16]);
+ COMBA_STORE(C->dp[7]);
+ /* 8 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[24]); MULADD(at[1], at[23]); MULADD(at[2], at[22]); MULADD(at[3], at[21]); MULADD(at[4], at[20]); MULADD(at[5], at[19]); MULADD(at[6], at[18]); MULADD(at[7], at[17]); MULADD(at[8], at[16]);
+ COMBA_STORE(C->dp[8]);
+ /* 9 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[25]); MULADD(at[1], at[24]); MULADD(at[2], at[23]); MULADD(at[3], at[22]); MULADD(at[4], at[21]); MULADD(at[5], at[20]); MULADD(at[6], at[19]); MULADD(at[7], at[18]); MULADD(at[8], at[17]); MULADD(at[9], at[16]);
+ COMBA_STORE(C->dp[9]);
+ /* 10 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[26]); MULADD(at[1], at[25]); MULADD(at[2], at[24]); MULADD(at[3], at[23]); MULADD(at[4], at[22]); MULADD(at[5], at[21]); MULADD(at[6], at[20]); MULADD(at[7], at[19]); MULADD(at[8], at[18]); MULADD(at[9], at[17]); MULADD(at[10], at[16]);
+ COMBA_STORE(C->dp[10]);
+ /* 11 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[27]); MULADD(at[1], at[26]); MULADD(at[2], at[25]); MULADD(at[3], at[24]); MULADD(at[4], at[23]); MULADD(at[5], at[22]); MULADD(at[6], at[21]); MULADD(at[7], at[20]); MULADD(at[8], at[19]); MULADD(at[9], at[18]); MULADD(at[10], at[17]); MULADD(at[11], at[16]);
+ COMBA_STORE(C->dp[11]);
+ /* 12 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[28]); MULADD(at[1], at[27]); MULADD(at[2], at[26]); MULADD(at[3], at[25]); MULADD(at[4], at[24]); MULADD(at[5], at[23]); MULADD(at[6], at[22]); MULADD(at[7], at[21]); MULADD(at[8], at[20]); MULADD(at[9], at[19]); MULADD(at[10], at[18]); MULADD(at[11], at[17]); MULADD(at[12], at[16]);
+ COMBA_STORE(C->dp[12]);
+ /* 13 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[29]); MULADD(at[1], at[28]); MULADD(at[2], at[27]); MULADD(at[3], at[26]); MULADD(at[4], at[25]); MULADD(at[5], at[24]); MULADD(at[6], at[23]); MULADD(at[7], at[22]); MULADD(at[8], at[21]); MULADD(at[9], at[20]); MULADD(at[10], at[19]); MULADD(at[11], at[18]); MULADD(at[12], at[17]); MULADD(at[13], at[16]);
+ COMBA_STORE(C->dp[13]);
+ /* 14 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[30]); MULADD(at[1], at[29]); MULADD(at[2], at[28]); MULADD(at[3], at[27]); MULADD(at[4], at[26]); MULADD(at[5], at[25]); MULADD(at[6], at[24]); MULADD(at[7], at[23]); MULADD(at[8], at[22]); MULADD(at[9], at[21]); MULADD(at[10], at[20]); MULADD(at[11], at[19]); MULADD(at[12], at[18]); MULADD(at[13], at[17]); MULADD(at[14], at[16]);
+ COMBA_STORE(C->dp[14]);
+ /* 15 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[31]); MULADD(at[1], at[30]); MULADD(at[2], at[29]); MULADD(at[3], at[28]); MULADD(at[4], at[27]); MULADD(at[5], at[26]); MULADD(at[6], at[25]); MULADD(at[7], at[24]); MULADD(at[8], at[23]); MULADD(at[9], at[22]); MULADD(at[10], at[21]); MULADD(at[11], at[20]); MULADD(at[12], at[19]); MULADD(at[13], at[18]); MULADD(at[14], at[17]); MULADD(at[15], at[16]);
+ COMBA_STORE(C->dp[15]);
+ /* 16 */
+ COMBA_FORWARD;
+ MULADD(at[1], at[31]); MULADD(at[2], at[30]); MULADD(at[3], at[29]); MULADD(at[4], at[28]); MULADD(at[5], at[27]); MULADD(at[6], at[26]); MULADD(at[7], at[25]); MULADD(at[8], at[24]); MULADD(at[9], at[23]); MULADD(at[10], at[22]); MULADD(at[11], at[21]); MULADD(at[12], at[20]); MULADD(at[13], at[19]); MULADD(at[14], at[18]); MULADD(at[15], at[17]);
+ COMBA_STORE(C->dp[16]);
+ /* 17 */
+ COMBA_FORWARD;
+ MULADD(at[2], at[31]); MULADD(at[3], at[30]); MULADD(at[4], at[29]); MULADD(at[5], at[28]); MULADD(at[6], at[27]); MULADD(at[7], at[26]); MULADD(at[8], at[25]); MULADD(at[9], at[24]); MULADD(at[10], at[23]); MULADD(at[11], at[22]); MULADD(at[12], at[21]); MULADD(at[13], at[20]); MULADD(at[14], at[19]); MULADD(at[15], at[18]);
+ COMBA_STORE(C->dp[17]);
+ /* 18 */
+ COMBA_FORWARD;
+ MULADD(at[3], at[31]); MULADD(at[4], at[30]); MULADD(at[5], at[29]); MULADD(at[6], at[28]); MULADD(at[7], at[27]); MULADD(at[8], at[26]); MULADD(at[9], at[25]); MULADD(at[10], at[24]); MULADD(at[11], at[23]); MULADD(at[12], at[22]); MULADD(at[13], at[21]); MULADD(at[14], at[20]); MULADD(at[15], at[19]);
+ COMBA_STORE(C->dp[18]);
+ /* 19 */
+ COMBA_FORWARD;
+ MULADD(at[4], at[31]); MULADD(at[5], at[30]); MULADD(at[6], at[29]); MULADD(at[7], at[28]); MULADD(at[8], at[27]); MULADD(at[9], at[26]); MULADD(at[10], at[25]); MULADD(at[11], at[24]); MULADD(at[12], at[23]); MULADD(at[13], at[22]); MULADD(at[14], at[21]); MULADD(at[15], at[20]);
+ COMBA_STORE(C->dp[19]);
+ /* 20 */
+ COMBA_FORWARD;
+ MULADD(at[5], at[31]); MULADD(at[6], at[30]); MULADD(at[7], at[29]); MULADD(at[8], at[28]); MULADD(at[9], at[27]); MULADD(at[10], at[26]); MULADD(at[11], at[25]); MULADD(at[12], at[24]); MULADD(at[13], at[23]); MULADD(at[14], at[22]); MULADD(at[15], at[21]);
+ COMBA_STORE(C->dp[20]);
+ /* 21 */
+ COMBA_FORWARD;
+ MULADD(at[6], at[31]); MULADD(at[7], at[30]); MULADD(at[8], at[29]); MULADD(at[9], at[28]); MULADD(at[10], at[27]); MULADD(at[11], at[26]); MULADD(at[12], at[25]); MULADD(at[13], at[24]); MULADD(at[14], at[23]); MULADD(at[15], at[22]);
+ COMBA_STORE(C->dp[21]);
+ /* 22 */
+ COMBA_FORWARD;
+ MULADD(at[7], at[31]); MULADD(at[8], at[30]); MULADD(at[9], at[29]); MULADD(at[10], at[28]); MULADD(at[11], at[27]); MULADD(at[12], at[26]); MULADD(at[13], at[25]); MULADD(at[14], at[24]); MULADD(at[15], at[23]);
+ COMBA_STORE(C->dp[22]);
+ /* 23 */
+ COMBA_FORWARD;
+ MULADD(at[8], at[31]); MULADD(at[9], at[30]); MULADD(at[10], at[29]); MULADD(at[11], at[28]); MULADD(at[12], at[27]); MULADD(at[13], at[26]); MULADD(at[14], at[25]); MULADD(at[15], at[24]);
+ COMBA_STORE(C->dp[23]);
+ /* 24 */
+ COMBA_FORWARD;
+ MULADD(at[9], at[31]); MULADD(at[10], at[30]); MULADD(at[11], at[29]); MULADD(at[12], at[28]); MULADD(at[13], at[27]); MULADD(at[14], at[26]); MULADD(at[15], at[25]);
+ COMBA_STORE(C->dp[24]);
+ /* 25 */
+ COMBA_FORWARD;
+ MULADD(at[10], at[31]); MULADD(at[11], at[30]); MULADD(at[12], at[29]); MULADD(at[13], at[28]); MULADD(at[14], at[27]); MULADD(at[15], at[26]);
+ COMBA_STORE(C->dp[25]);
+ /* 26 */
+ COMBA_FORWARD;
+ MULADD(at[11], at[31]); MULADD(at[12], at[30]); MULADD(at[13], at[29]); MULADD(at[14], at[28]); MULADD(at[15], at[27]);
+ COMBA_STORE(C->dp[26]);
+ /* 27 */
+ COMBA_FORWARD;
+ MULADD(at[12], at[31]); MULADD(at[13], at[30]); MULADD(at[14], at[29]); MULADD(at[15], at[28]);
+ COMBA_STORE(C->dp[27]);
+ /* 28 */
+ COMBA_FORWARD;
+ MULADD(at[13], at[31]); MULADD(at[14], at[30]); MULADD(at[15], at[29]);
+ COMBA_STORE(C->dp[28]);
+ /* 29 */
+ COMBA_FORWARD;
+ MULADD(at[14], at[31]); MULADD(at[15], at[30]);
+ COMBA_STORE(C->dp[29]);
+ /* 30 */
+ COMBA_FORWARD;
+ MULADD(at[15], at[31]);
+ COMBA_STORE(C->dp[30]);
+ COMBA_STORE2(C->dp[31]);
+ C->used = 32;
+ C->sign = A->sign ^ B->sign;
+ pstm_clamp(C);
+ COMBA_FINI;
+ return PSTM_OKAY;
}
-#endif /* USE_1024_KEY_SPEED_OPTIMIZATIONS */
+# endif /* USE_1024_KEY_SPEED_OPTIMIZATIONS */
-#ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS
+# ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS
static int32_t pstm_mul_comba32(const pstm_int *A, const pstm_int *B, pstm_int *C)
{
- pstm_digit c0, c1, c2, at[64];
- int32 out_size;
+ pstm_digit c0, c1, c2, at[64];
+ int32 out_size;
- if (C->alloc < 64) {
- if (pstm_grow(C, 64) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- }
+ if (C->alloc < 64)
+ {
+ if (pstm_grow(C, 64) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ }
- out_size = A->used + B->used;
- memcpy(at, A->dp, 32 * sizeof(pstm_digit));
- memcpy(at+32, B->dp, 32 * sizeof(pstm_digit));
- COMBA_START;
+ out_size = A->used + B->used;
+ memcpy(at, A->dp, 32 * sizeof(pstm_digit));
+ memcpy(at + 32, B->dp, 32 * sizeof(pstm_digit));
+ COMBA_START;
- COMBA_CLEAR;
- /* 0 */
- MULADD(at[0], at[32]);
- COMBA_STORE(C->dp[0]);
- /* 1 */
- COMBA_FORWARD;
- MULADD(at[0], at[33]); MULADD(at[1], at[32]);
- COMBA_STORE(C->dp[1]);
- /* 2 */
- COMBA_FORWARD;
- MULADD(at[0], at[34]); MULADD(at[1], at[33]); MULADD(at[2], at[32]);
- COMBA_STORE(C->dp[2]);
- /* 3 */
- COMBA_FORWARD;
- MULADD(at[0], at[35]); MULADD(at[1], at[34]); MULADD(at[2], at[33]); MULADD(at[3], at[32]);
- COMBA_STORE(C->dp[3]);
- /* 4 */
- COMBA_FORWARD;
- MULADD(at[0], at[36]); MULADD(at[1], at[35]); MULADD(at[2], at[34]); MULADD(at[3], at[33]); MULADD(at[4], at[32]);
- COMBA_STORE(C->dp[4]);
- /* 5 */
- COMBA_FORWARD;
- MULADD(at[0], at[37]); MULADD(at[1], at[36]); MULADD(at[2], at[35]); MULADD(at[3], at[34]); MULADD(at[4], at[33]); MULADD(at[5], at[32]);
- COMBA_STORE(C->dp[5]);
- /* 6 */
- COMBA_FORWARD;
- MULADD(at[0], at[38]); MULADD(at[1], at[37]); MULADD(at[2], at[36]); MULADD(at[3], at[35]); MULADD(at[4], at[34]); MULADD(at[5], at[33]); MULADD(at[6], at[32]);
- COMBA_STORE(C->dp[6]);
- /* 7 */
- COMBA_FORWARD;
- MULADD(at[0], at[39]); MULADD(at[1], at[38]); MULADD(at[2], at[37]); MULADD(at[3], at[36]); MULADD(at[4], at[35]); MULADD(at[5], at[34]); MULADD(at[6], at[33]); MULADD(at[7], at[32]);
- COMBA_STORE(C->dp[7]);
- /* 8 */
- COMBA_FORWARD;
- MULADD(at[0], at[40]); MULADD(at[1], at[39]); MULADD(at[2], at[38]); MULADD(at[3], at[37]); MULADD(at[4], at[36]); MULADD(at[5], at[35]); MULADD(at[6], at[34]); MULADD(at[7], at[33]); MULADD(at[8], at[32]);
- COMBA_STORE(C->dp[8]);
- /* 9 */
- COMBA_FORWARD;
- MULADD(at[0], at[41]); MULADD(at[1], at[40]); MULADD(at[2], at[39]); MULADD(at[3], at[38]); MULADD(at[4], at[37]); MULADD(at[5], at[36]); MULADD(at[6], at[35]); MULADD(at[7], at[34]); MULADD(at[8], at[33]); MULADD(at[9], at[32]);
- COMBA_STORE(C->dp[9]);
- /* 10 */
- COMBA_FORWARD;
- MULADD(at[0], at[42]); MULADD(at[1], at[41]); MULADD(at[2], at[40]); MULADD(at[3], at[39]); MULADD(at[4], at[38]); MULADD(at[5], at[37]); MULADD(at[6], at[36]); MULADD(at[7], at[35]); MULADD(at[8], at[34]); MULADD(at[9], at[33]); MULADD(at[10], at[32]);
- COMBA_STORE(C->dp[10]);
- /* 11 */
- COMBA_FORWARD;
- MULADD(at[0], at[43]); MULADD(at[1], at[42]); MULADD(at[2], at[41]); MULADD(at[3], at[40]); MULADD(at[4], at[39]); MULADD(at[5], at[38]); MULADD(at[6], at[37]); MULADD(at[7], at[36]); MULADD(at[8], at[35]); MULADD(at[9], at[34]); MULADD(at[10], at[33]); MULADD(at[11], at[32]);
- COMBA_STORE(C->dp[11]);
- /* 12 */
- COMBA_FORWARD;
- MULADD(at[0], at[44]); MULADD(at[1], at[43]); MULADD(at[2], at[42]); MULADD(at[3], at[41]); MULADD(at[4], at[40]); MULADD(at[5], at[39]); MULADD(at[6], at[38]); MULADD(at[7], at[37]); MULADD(at[8], at[36]); MULADD(at[9], at[35]); MULADD(at[10], at[34]); MULADD(at[11], at[33]); MULADD(at[12], at[32]);
- COMBA_STORE(C->dp[12]);
- /* 13 */
- COMBA_FORWARD;
- MULADD(at[0], at[45]); MULADD(at[1], at[44]); MULADD(at[2], at[43]); MULADD(at[3], at[42]); MULADD(at[4], at[41]); MULADD(at[5], at[40]); MULADD(at[6], at[39]); MULADD(at[7], at[38]); MULADD(at[8], at[37]); MULADD(at[9], at[36]); MULADD(at[10], at[35]); MULADD(at[11], at[34]); MULADD(at[12], at[33]); MULADD(at[13], at[32]);
- COMBA_STORE(C->dp[13]);
- /* 14 */
- COMBA_FORWARD;
- MULADD(at[0], at[46]); MULADD(at[1], at[45]); MULADD(at[2], at[44]); MULADD(at[3], at[43]); MULADD(at[4], at[42]); MULADD(at[5], at[41]); MULADD(at[6], at[40]); MULADD(at[7], at[39]); MULADD(at[8], at[38]); MULADD(at[9], at[37]); MULADD(at[10], at[36]); MULADD(at[11], at[35]); MULADD(at[12], at[34]); MULADD(at[13], at[33]); MULADD(at[14], at[32]);
- COMBA_STORE(C->dp[14]);
- /* 15 */
- COMBA_FORWARD;
- MULADD(at[0], at[47]); MULADD(at[1], at[46]); MULADD(at[2], at[45]); MULADD(at[3], at[44]); MULADD(at[4], at[43]); MULADD(at[5], at[42]); MULADD(at[6], at[41]); MULADD(at[7], at[40]); MULADD(at[8], at[39]); MULADD(at[9], at[38]); MULADD(at[10], at[37]); MULADD(at[11], at[36]); MULADD(at[12], at[35]); MULADD(at[13], at[34]); MULADD(at[14], at[33]); MULADD(at[15], at[32]);
- COMBA_STORE(C->dp[15]);
- /* 16 */
- COMBA_FORWARD;
- MULADD(at[0], at[48]); MULADD(at[1], at[47]); MULADD(at[2], at[46]); MULADD(at[3], at[45]); MULADD(at[4], at[44]); MULADD(at[5], at[43]); MULADD(at[6], at[42]); MULADD(at[7], at[41]); MULADD(at[8], at[40]); MULADD(at[9], at[39]); MULADD(at[10], at[38]); MULADD(at[11], at[37]); MULADD(at[12], at[36]); MULADD(at[13], at[35]); MULADD(at[14], at[34]); MULADD(at[15], at[33]); MULADD(at[16], at[32]);
- COMBA_STORE(C->dp[16]);
- /* 17 */
- COMBA_FORWARD;
- MULADD(at[0], at[49]); MULADD(at[1], at[48]); MULADD(at[2], at[47]); MULADD(at[3], at[46]); MULADD(at[4], at[45]); MULADD(at[5], at[44]); MULADD(at[6], at[43]); MULADD(at[7], at[42]); MULADD(at[8], at[41]); MULADD(at[9], at[40]); MULADD(at[10], at[39]); MULADD(at[11], at[38]); MULADD(at[12], at[37]); MULADD(at[13], at[36]); MULADD(at[14], at[35]); MULADD(at[15], at[34]); MULADD(at[16], at[33]); MULADD(at[17], at[32]);
- COMBA_STORE(C->dp[17]);
- /* 18 */
- COMBA_FORWARD;
- MULADD(at[0], at[50]); MULADD(at[1], at[49]); MULADD(at[2], at[48]); MULADD(at[3], at[47]); MULADD(at[4], at[46]); MULADD(at[5], at[45]); MULADD(at[6], at[44]); MULADD(at[7], at[43]); MULADD(at[8], at[42]); MULADD(at[9], at[41]); MULADD(at[10], at[40]); MULADD(at[11], at[39]); MULADD(at[12], at[38]); MULADD(at[13], at[37]); MULADD(at[14], at[36]); MULADD(at[15], at[35]); MULADD(at[16], at[34]); MULADD(at[17], at[33]); MULADD(at[18], at[32]);
- COMBA_STORE(C->dp[18]);
- /* 19 */
- COMBA_FORWARD;
- MULADD(at[0], at[51]); MULADD(at[1], at[50]); MULADD(at[2], at[49]); MULADD(at[3], at[48]); MULADD(at[4], at[47]); MULADD(at[5], at[46]); MULADD(at[6], at[45]); MULADD(at[7], at[44]); MULADD(at[8], at[43]); MULADD(at[9], at[42]); MULADD(at[10], at[41]); MULADD(at[11], at[40]); MULADD(at[12], at[39]); MULADD(at[13], at[38]); MULADD(at[14], at[37]); MULADD(at[15], at[36]); MULADD(at[16], at[35]); MULADD(at[17], at[34]); MULADD(at[18], at[33]); MULADD(at[19], at[32]);
- COMBA_STORE(C->dp[19]);
- /* 20 */
- COMBA_FORWARD;
- MULADD(at[0], at[52]); MULADD(at[1], at[51]); MULADD(at[2], at[50]); MULADD(at[3], at[49]); MULADD(at[4], at[48]); MULADD(at[5], at[47]); MULADD(at[6], at[46]); MULADD(at[7], at[45]); MULADD(at[8], at[44]); MULADD(at[9], at[43]); MULADD(at[10], at[42]); MULADD(at[11], at[41]); MULADD(at[12], at[40]); MULADD(at[13], at[39]); MULADD(at[14], at[38]); MULADD(at[15], at[37]); MULADD(at[16], at[36]); MULADD(at[17], at[35]); MULADD(at[18], at[34]); MULADD(at[19], at[33]); MULADD(at[20], at[32]);
- COMBA_STORE(C->dp[20]);
- /* 21 */
- COMBA_FORWARD;
- MULADD(at[0], at[53]); MULADD(at[1], at[52]); MULADD(at[2], at[51]); MULADD(at[3], at[50]); MULADD(at[4], at[49]); MULADD(at[5], at[48]); MULADD(at[6], at[47]); MULADD(at[7], at[46]); MULADD(at[8], at[45]); MULADD(at[9], at[44]); MULADD(at[10], at[43]); MULADD(at[11], at[42]); MULADD(at[12], at[41]); MULADD(at[13], at[40]); MULADD(at[14], at[39]); MULADD(at[15], at[38]); MULADD(at[16], at[37]); MULADD(at[17], at[36]); MULADD(at[18], at[35]); MULADD(at[19], at[34]); MULADD(at[20], at[33]); MULADD(at[21], at[32]);
- COMBA_STORE(C->dp[21]);
- /* 22 */
- COMBA_FORWARD;
- MULADD(at[0], at[54]); MULADD(at[1], at[53]); MULADD(at[2], at[52]); MULADD(at[3], at[51]); MULADD(at[4], at[50]); MULADD(at[5], at[49]); MULADD(at[6], at[48]); MULADD(at[7], at[47]); MULADD(at[8], at[46]); MULADD(at[9], at[45]); MULADD(at[10], at[44]); MULADD(at[11], at[43]); MULADD(at[12], at[42]); MULADD(at[13], at[41]); MULADD(at[14], at[40]); MULADD(at[15], at[39]); MULADD(at[16], at[38]); MULADD(at[17], at[37]); MULADD(at[18], at[36]); MULADD(at[19], at[35]); MULADD(at[20], at[34]); MULADD(at[21], at[33]); MULADD(at[22], at[32]);
- COMBA_STORE(C->dp[22]);
- /* 23 */
- COMBA_FORWARD;
- MULADD(at[0], at[55]); MULADD(at[1], at[54]); MULADD(at[2], at[53]); MULADD(at[3], at[52]); MULADD(at[4], at[51]); MULADD(at[5], at[50]); MULADD(at[6], at[49]); MULADD(at[7], at[48]); MULADD(at[8], at[47]); MULADD(at[9], at[46]); MULADD(at[10], at[45]); MULADD(at[11], at[44]); MULADD(at[12], at[43]); MULADD(at[13], at[42]); MULADD(at[14], at[41]); MULADD(at[15], at[40]); MULADD(at[16], at[39]); MULADD(at[17], at[38]); MULADD(at[18], at[37]); MULADD(at[19], at[36]); MULADD(at[20], at[35]); MULADD(at[21], at[34]); MULADD(at[22], at[33]); MULADD(at[23], at[32]);
- COMBA_STORE(C->dp[23]);
- /* 24 */
- COMBA_FORWARD;
- MULADD(at[0], at[56]); MULADD(at[1], at[55]); MULADD(at[2], at[54]); MULADD(at[3], at[53]); MULADD(at[4], at[52]); MULADD(at[5], at[51]); MULADD(at[6], at[50]); MULADD(at[7], at[49]); MULADD(at[8], at[48]); MULADD(at[9], at[47]); MULADD(at[10], at[46]); MULADD(at[11], at[45]); MULADD(at[12], at[44]); MULADD(at[13], at[43]); MULADD(at[14], at[42]); MULADD(at[15], at[41]); MULADD(at[16], at[40]); MULADD(at[17], at[39]); MULADD(at[18], at[38]); MULADD(at[19], at[37]); MULADD(at[20], at[36]); MULADD(at[21], at[35]); MULADD(at[22], at[34]); MULADD(at[23], at[33]); MULADD(at[24], at[32]);
- COMBA_STORE(C->dp[24]);
- /* 25 */
- COMBA_FORWARD;
- MULADD(at[0], at[57]); MULADD(at[1], at[56]); MULADD(at[2], at[55]); MULADD(at[3], at[54]); MULADD(at[4], at[53]); MULADD(at[5], at[52]); MULADD(at[6], at[51]); MULADD(at[7], at[50]); MULADD(at[8], at[49]); MULADD(at[9], at[48]); MULADD(at[10], at[47]); MULADD(at[11], at[46]); MULADD(at[12], at[45]); MULADD(at[13], at[44]); MULADD(at[14], at[43]); MULADD(at[15], at[42]); MULADD(at[16], at[41]); MULADD(at[17], at[40]); MULADD(at[18], at[39]); MULADD(at[19], at[38]); MULADD(at[20], at[37]); MULADD(at[21], at[36]); MULADD(at[22], at[35]); MULADD(at[23], at[34]); MULADD(at[24], at[33]); MULADD(at[25], at[32]);
- COMBA_STORE(C->dp[25]);
- /* 26 */
- COMBA_FORWARD;
- MULADD(at[0], at[58]); MULADD(at[1], at[57]); MULADD(at[2], at[56]); MULADD(at[3], at[55]); MULADD(at[4], at[54]); MULADD(at[5], at[53]); MULADD(at[6], at[52]); MULADD(at[7], at[51]); MULADD(at[8], at[50]); MULADD(at[9], at[49]); MULADD(at[10], at[48]); MULADD(at[11], at[47]); MULADD(at[12], at[46]); MULADD(at[13], at[45]); MULADD(at[14], at[44]); MULADD(at[15], at[43]); MULADD(at[16], at[42]); MULADD(at[17], at[41]); MULADD(at[18], at[40]); MULADD(at[19], at[39]); MULADD(at[20], at[38]); MULADD(at[21], at[37]); MULADD(at[22], at[36]); MULADD(at[23], at[35]); MULADD(at[24], at[34]); MULADD(at[25], at[33]); MULADD(at[26], at[32]);
- COMBA_STORE(C->dp[26]);
- /* 27 */
- COMBA_FORWARD;
- MULADD(at[0], at[59]); MULADD(at[1], at[58]); MULADD(at[2], at[57]); MULADD(at[3], at[56]); MULADD(at[4], at[55]); MULADD(at[5], at[54]); MULADD(at[6], at[53]); MULADD(at[7], at[52]); MULADD(at[8], at[51]); MULADD(at[9], at[50]); MULADD(at[10], at[49]); MULADD(at[11], at[48]); MULADD(at[12], at[47]); MULADD(at[13], at[46]); MULADD(at[14], at[45]); MULADD(at[15], at[44]); MULADD(at[16], at[43]); MULADD(at[17], at[42]); MULADD(at[18], at[41]); MULADD(at[19], at[40]); MULADD(at[20], at[39]); MULADD(at[21], at[38]); MULADD(at[22], at[37]); MULADD(at[23], at[36]); MULADD(at[24], at[35]); MULADD(at[25], at[34]); MULADD(at[26], at[33]); MULADD(at[27], at[32]);
- COMBA_STORE(C->dp[27]);
- /* 28 */
- COMBA_FORWARD;
- MULADD(at[0], at[60]); MULADD(at[1], at[59]); MULADD(at[2], at[58]); MULADD(at[3], at[57]); MULADD(at[4], at[56]); MULADD(at[5], at[55]); MULADD(at[6], at[54]); MULADD(at[7], at[53]); MULADD(at[8], at[52]); MULADD(at[9], at[51]); MULADD(at[10], at[50]); MULADD(at[11], at[49]); MULADD(at[12], at[48]); MULADD(at[13], at[47]); MULADD(at[14], at[46]); MULADD(at[15], at[45]); MULADD(at[16], at[44]); MULADD(at[17], at[43]); MULADD(at[18], at[42]); MULADD(at[19], at[41]); MULADD(at[20], at[40]); MULADD(at[21], at[39]); MULADD(at[22], at[38]); MULADD(at[23], at[37]); MULADD(at[24], at[36]); MULADD(at[25], at[35]); MULADD(at[26], at[34]); MULADD(at[27], at[33]); MULADD(at[28], at[32]);
- COMBA_STORE(C->dp[28]);
- /* 29 */
- COMBA_FORWARD;
- MULADD(at[0], at[61]); MULADD(at[1], at[60]); MULADD(at[2], at[59]); MULADD(at[3], at[58]); MULADD(at[4], at[57]); MULADD(at[5], at[56]); MULADD(at[6], at[55]); MULADD(at[7], at[54]); MULADD(at[8], at[53]); MULADD(at[9], at[52]); MULADD(at[10], at[51]); MULADD(at[11], at[50]); MULADD(at[12], at[49]); MULADD(at[13], at[48]); MULADD(at[14], at[47]); MULADD(at[15], at[46]); MULADD(at[16], at[45]); MULADD(at[17], at[44]); MULADD(at[18], at[43]); MULADD(at[19], at[42]); MULADD(at[20], at[41]); MULADD(at[21], at[40]); MULADD(at[22], at[39]); MULADD(at[23], at[38]); MULADD(at[24], at[37]); MULADD(at[25], at[36]); MULADD(at[26], at[35]); MULADD(at[27], at[34]); MULADD(at[28], at[33]); MULADD(at[29], at[32]);
- COMBA_STORE(C->dp[29]);
- /* 30 */
- COMBA_FORWARD;
- MULADD(at[0], at[62]); MULADD(at[1], at[61]); MULADD(at[2], at[60]); MULADD(at[3], at[59]); MULADD(at[4], at[58]); MULADD(at[5], at[57]); MULADD(at[6], at[56]); MULADD(at[7], at[55]); MULADD(at[8], at[54]); MULADD(at[9], at[53]); MULADD(at[10], at[52]); MULADD(at[11], at[51]); MULADD(at[12], at[50]); MULADD(at[13], at[49]); MULADD(at[14], at[48]); MULADD(at[15], at[47]); MULADD(at[16], at[46]); MULADD(at[17], at[45]); MULADD(at[18], at[44]); MULADD(at[19], at[43]); MULADD(at[20], at[42]); MULADD(at[21], at[41]); MULADD(at[22], at[40]); MULADD(at[23], at[39]); MULADD(at[24], at[38]); MULADD(at[25], at[37]); MULADD(at[26], at[36]); MULADD(at[27], at[35]); MULADD(at[28], at[34]); MULADD(at[29], at[33]); MULADD(at[30], at[32]);
- COMBA_STORE(C->dp[30]);
- /* 31 */
- COMBA_FORWARD;
- MULADD(at[0], at[63]); MULADD(at[1], at[62]); MULADD(at[2], at[61]); MULADD(at[3], at[60]); MULADD(at[4], at[59]); MULADD(at[5], at[58]); MULADD(at[6], at[57]); MULADD(at[7], at[56]); MULADD(at[8], at[55]); MULADD(at[9], at[54]); MULADD(at[10], at[53]); MULADD(at[11], at[52]); MULADD(at[12], at[51]); MULADD(at[13], at[50]); MULADD(at[14], at[49]); MULADD(at[15], at[48]); MULADD(at[16], at[47]); MULADD(at[17], at[46]); MULADD(at[18], at[45]); MULADD(at[19], at[44]); MULADD(at[20], at[43]); MULADD(at[21], at[42]); MULADD(at[22], at[41]); MULADD(at[23], at[40]); MULADD(at[24], at[39]); MULADD(at[25], at[38]); MULADD(at[26], at[37]); MULADD(at[27], at[36]); MULADD(at[28], at[35]); MULADD(at[29], at[34]); MULADD(at[30], at[33]); MULADD(at[31], at[32]);
- COMBA_STORE(C->dp[31]);
- /* 32 */
- COMBA_FORWARD;
- MULADD(at[1], at[63]); MULADD(at[2], at[62]); MULADD(at[3], at[61]); MULADD(at[4], at[60]); MULADD(at[5], at[59]); MULADD(at[6], at[58]); MULADD(at[7], at[57]); MULADD(at[8], at[56]); MULADD(at[9], at[55]); MULADD(at[10], at[54]); MULADD(at[11], at[53]); MULADD(at[12], at[52]); MULADD(at[13], at[51]); MULADD(at[14], at[50]); MULADD(at[15], at[49]); MULADD(at[16], at[48]); MULADD(at[17], at[47]); MULADD(at[18], at[46]); MULADD(at[19], at[45]); MULADD(at[20], at[44]); MULADD(at[21], at[43]); MULADD(at[22], at[42]); MULADD(at[23], at[41]); MULADD(at[24], at[40]); MULADD(at[25], at[39]); MULADD(at[26], at[38]); MULADD(at[27], at[37]); MULADD(at[28], at[36]); MULADD(at[29], at[35]); MULADD(at[30], at[34]); MULADD(at[31], at[33]);
- COMBA_STORE(C->dp[32]);
- /* 33 */
- COMBA_FORWARD;
- MULADD(at[2], at[63]); MULADD(at[3], at[62]); MULADD(at[4], at[61]); MULADD(at[5], at[60]); MULADD(at[6], at[59]); MULADD(at[7], at[58]); MULADD(at[8], at[57]); MULADD(at[9], at[56]); MULADD(at[10], at[55]); MULADD(at[11], at[54]); MULADD(at[12], at[53]); MULADD(at[13], at[52]); MULADD(at[14], at[51]); MULADD(at[15], at[50]); MULADD(at[16], at[49]); MULADD(at[17], at[48]); MULADD(at[18], at[47]); MULADD(at[19], at[46]); MULADD(at[20], at[45]); MULADD(at[21], at[44]); MULADD(at[22], at[43]); MULADD(at[23], at[42]); MULADD(at[24], at[41]); MULADD(at[25], at[40]); MULADD(at[26], at[39]); MULADD(at[27], at[38]); MULADD(at[28], at[37]); MULADD(at[29], at[36]); MULADD(at[30], at[35]); MULADD(at[31], at[34]);
- COMBA_STORE(C->dp[33]);
- /* 34 */
- COMBA_FORWARD;
- MULADD(at[3], at[63]); MULADD(at[4], at[62]); MULADD(at[5], at[61]); MULADD(at[6], at[60]); MULADD(at[7], at[59]); MULADD(at[8], at[58]); MULADD(at[9], at[57]); MULADD(at[10], at[56]); MULADD(at[11], at[55]); MULADD(at[12], at[54]); MULADD(at[13], at[53]); MULADD(at[14], at[52]); MULADD(at[15], at[51]); MULADD(at[16], at[50]); MULADD(at[17], at[49]); MULADD(at[18], at[48]); MULADD(at[19], at[47]); MULADD(at[20], at[46]); MULADD(at[21], at[45]); MULADD(at[22], at[44]); MULADD(at[23], at[43]); MULADD(at[24], at[42]); MULADD(at[25], at[41]); MULADD(at[26], at[40]); MULADD(at[27], at[39]); MULADD(at[28], at[38]); MULADD(at[29], at[37]); MULADD(at[30], at[36]); MULADD(at[31], at[35]);
- COMBA_STORE(C->dp[34]);
- /* 35 */
- COMBA_FORWARD;
- MULADD(at[4], at[63]); MULADD(at[5], at[62]); MULADD(at[6], at[61]); MULADD(at[7], at[60]); MULADD(at[8], at[59]); MULADD(at[9], at[58]); MULADD(at[10], at[57]); MULADD(at[11], at[56]); MULADD(at[12], at[55]); MULADD(at[13], at[54]); MULADD(at[14], at[53]); MULADD(at[15], at[52]); MULADD(at[16], at[51]); MULADD(at[17], at[50]); MULADD(at[18], at[49]); MULADD(at[19], at[48]); MULADD(at[20], at[47]); MULADD(at[21], at[46]); MULADD(at[22], at[45]); MULADD(at[23], at[44]); MULADD(at[24], at[43]); MULADD(at[25], at[42]); MULADD(at[26], at[41]); MULADD(at[27], at[40]); MULADD(at[28], at[39]); MULADD(at[29], at[38]); MULADD(at[30], at[37]); MULADD(at[31], at[36]);
- COMBA_STORE(C->dp[35]);
- /* 36 */
- COMBA_FORWARD;
- MULADD(at[5], at[63]); MULADD(at[6], at[62]); MULADD(at[7], at[61]); MULADD(at[8], at[60]); MULADD(at[9], at[59]); MULADD(at[10], at[58]); MULADD(at[11], at[57]); MULADD(at[12], at[56]); MULADD(at[13], at[55]); MULADD(at[14], at[54]); MULADD(at[15], at[53]); MULADD(at[16], at[52]); MULADD(at[17], at[51]); MULADD(at[18], at[50]); MULADD(at[19], at[49]); MULADD(at[20], at[48]); MULADD(at[21], at[47]); MULADD(at[22], at[46]); MULADD(at[23], at[45]); MULADD(at[24], at[44]); MULADD(at[25], at[43]); MULADD(at[26], at[42]); MULADD(at[27], at[41]); MULADD(at[28], at[40]); MULADD(at[29], at[39]); MULADD(at[30], at[38]); MULADD(at[31], at[37]);
- COMBA_STORE(C->dp[36]);
- /* 37 */
- COMBA_FORWARD;
- MULADD(at[6], at[63]); MULADD(at[7], at[62]); MULADD(at[8], at[61]); MULADD(at[9], at[60]); MULADD(at[10], at[59]); MULADD(at[11], at[58]); MULADD(at[12], at[57]); MULADD(at[13], at[56]); MULADD(at[14], at[55]); MULADD(at[15], at[54]); MULADD(at[16], at[53]); MULADD(at[17], at[52]); MULADD(at[18], at[51]); MULADD(at[19], at[50]); MULADD(at[20], at[49]); MULADD(at[21], at[48]); MULADD(at[22], at[47]); MULADD(at[23], at[46]); MULADD(at[24], at[45]); MULADD(at[25], at[44]); MULADD(at[26], at[43]); MULADD(at[27], at[42]); MULADD(at[28], at[41]); MULADD(at[29], at[40]); MULADD(at[30], at[39]); MULADD(at[31], at[38]);
- COMBA_STORE(C->dp[37]);
- /* 38 */
- COMBA_FORWARD;
- MULADD(at[7], at[63]); MULADD(at[8], at[62]); MULADD(at[9], at[61]); MULADD(at[10], at[60]); MULADD(at[11], at[59]); MULADD(at[12], at[58]); MULADD(at[13], at[57]); MULADD(at[14], at[56]); MULADD(at[15], at[55]); MULADD(at[16], at[54]); MULADD(at[17], at[53]); MULADD(at[18], at[52]); MULADD(at[19], at[51]); MULADD(at[20], at[50]); MULADD(at[21], at[49]); MULADD(at[22], at[48]); MULADD(at[23], at[47]); MULADD(at[24], at[46]); MULADD(at[25], at[45]); MULADD(at[26], at[44]); MULADD(at[27], at[43]); MULADD(at[28], at[42]); MULADD(at[29], at[41]); MULADD(at[30], at[40]); MULADD(at[31], at[39]);
- COMBA_STORE(C->dp[38]);
+ COMBA_CLEAR;
+ /* 0 */
+ MULADD(at[0], at[32]);
+ COMBA_STORE(C->dp[0]);
+ /* 1 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[33]); MULADD(at[1], at[32]);
+ COMBA_STORE(C->dp[1]);
+ /* 2 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[34]); MULADD(at[1], at[33]); MULADD(at[2], at[32]);
+ COMBA_STORE(C->dp[2]);
+ /* 3 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[35]); MULADD(at[1], at[34]); MULADD(at[2], at[33]); MULADD(at[3], at[32]);
+ COMBA_STORE(C->dp[3]);
+ /* 4 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[36]); MULADD(at[1], at[35]); MULADD(at[2], at[34]); MULADD(at[3], at[33]); MULADD(at[4], at[32]);
+ COMBA_STORE(C->dp[4]);
+ /* 5 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[37]); MULADD(at[1], at[36]); MULADD(at[2], at[35]); MULADD(at[3], at[34]); MULADD(at[4], at[33]); MULADD(at[5], at[32]);
+ COMBA_STORE(C->dp[5]);
+ /* 6 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[38]); MULADD(at[1], at[37]); MULADD(at[2], at[36]); MULADD(at[3], at[35]); MULADD(at[4], at[34]); MULADD(at[5], at[33]); MULADD(at[6], at[32]);
+ COMBA_STORE(C->dp[6]);
+ /* 7 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[39]); MULADD(at[1], at[38]); MULADD(at[2], at[37]); MULADD(at[3], at[36]); MULADD(at[4], at[35]); MULADD(at[5], at[34]); MULADD(at[6], at[33]); MULADD(at[7], at[32]);
+ COMBA_STORE(C->dp[7]);
+ /* 8 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[40]); MULADD(at[1], at[39]); MULADD(at[2], at[38]); MULADD(at[3], at[37]); MULADD(at[4], at[36]); MULADD(at[5], at[35]); MULADD(at[6], at[34]); MULADD(at[7], at[33]); MULADD(at[8], at[32]);
+ COMBA_STORE(C->dp[8]);
+ /* 9 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[41]); MULADD(at[1], at[40]); MULADD(at[2], at[39]); MULADD(at[3], at[38]); MULADD(at[4], at[37]); MULADD(at[5], at[36]); MULADD(at[6], at[35]); MULADD(at[7], at[34]); MULADD(at[8], at[33]); MULADD(at[9], at[32]);
+ COMBA_STORE(C->dp[9]);
+ /* 10 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[42]); MULADD(at[1], at[41]); MULADD(at[2], at[40]); MULADD(at[3], at[39]); MULADD(at[4], at[38]); MULADD(at[5], at[37]); MULADD(at[6], at[36]); MULADD(at[7], at[35]); MULADD(at[8], at[34]); MULADD(at[9], at[33]); MULADD(at[10], at[32]);
+ COMBA_STORE(C->dp[10]);
+ /* 11 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[43]); MULADD(at[1], at[42]); MULADD(at[2], at[41]); MULADD(at[3], at[40]); MULADD(at[4], at[39]); MULADD(at[5], at[38]); MULADD(at[6], at[37]); MULADD(at[7], at[36]); MULADD(at[8], at[35]); MULADD(at[9], at[34]); MULADD(at[10], at[33]); MULADD(at[11], at[32]);
+ COMBA_STORE(C->dp[11]);
+ /* 12 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[44]); MULADD(at[1], at[43]); MULADD(at[2], at[42]); MULADD(at[3], at[41]); MULADD(at[4], at[40]); MULADD(at[5], at[39]); MULADD(at[6], at[38]); MULADD(at[7], at[37]); MULADD(at[8], at[36]); MULADD(at[9], at[35]); MULADD(at[10], at[34]); MULADD(at[11], at[33]); MULADD(at[12], at[32]);
+ COMBA_STORE(C->dp[12]);
+ /* 13 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[45]); MULADD(at[1], at[44]); MULADD(at[2], at[43]); MULADD(at[3], at[42]); MULADD(at[4], at[41]); MULADD(at[5], at[40]); MULADD(at[6], at[39]); MULADD(at[7], at[38]); MULADD(at[8], at[37]); MULADD(at[9], at[36]); MULADD(at[10], at[35]); MULADD(at[11], at[34]); MULADD(at[12], at[33]); MULADD(at[13], at[32]);
+ COMBA_STORE(C->dp[13]);
+ /* 14 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[46]); MULADD(at[1], at[45]); MULADD(at[2], at[44]); MULADD(at[3], at[43]); MULADD(at[4], at[42]); MULADD(at[5], at[41]); MULADD(at[6], at[40]); MULADD(at[7], at[39]); MULADD(at[8], at[38]); MULADD(at[9], at[37]); MULADD(at[10], at[36]); MULADD(at[11], at[35]); MULADD(at[12], at[34]); MULADD(at[13], at[33]); MULADD(at[14], at[32]);
+ COMBA_STORE(C->dp[14]);
+ /* 15 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[47]); MULADD(at[1], at[46]); MULADD(at[2], at[45]); MULADD(at[3], at[44]); MULADD(at[4], at[43]); MULADD(at[5], at[42]); MULADD(at[6], at[41]); MULADD(at[7], at[40]); MULADD(at[8], at[39]); MULADD(at[9], at[38]); MULADD(at[10], at[37]); MULADD(at[11], at[36]); MULADD(at[12], at[35]); MULADD(at[13], at[34]); MULADD(at[14], at[33]); MULADD(at[15], at[32]);
+ COMBA_STORE(C->dp[15]);
+ /* 16 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[48]); MULADD(at[1], at[47]); MULADD(at[2], at[46]); MULADD(at[3], at[45]); MULADD(at[4], at[44]); MULADD(at[5], at[43]); MULADD(at[6], at[42]); MULADD(at[7], at[41]); MULADD(at[8], at[40]); MULADD(at[9], at[39]); MULADD(at[10], at[38]); MULADD(at[11], at[37]); MULADD(at[12], at[36]); MULADD(at[13], at[35]); MULADD(at[14], at[34]); MULADD(at[15], at[33]); MULADD(at[16], at[32]);
+ COMBA_STORE(C->dp[16]);
+ /* 17 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[49]); MULADD(at[1], at[48]); MULADD(at[2], at[47]); MULADD(at[3], at[46]); MULADD(at[4], at[45]); MULADD(at[5], at[44]); MULADD(at[6], at[43]); MULADD(at[7], at[42]); MULADD(at[8], at[41]); MULADD(at[9], at[40]); MULADD(at[10], at[39]); MULADD(at[11], at[38]); MULADD(at[12], at[37]); MULADD(at[13], at[36]); MULADD(at[14], at[35]); MULADD(at[15], at[34]); MULADD(at[16], at[33]); MULADD(at[17], at[32]);
+ COMBA_STORE(C->dp[17]);
+ /* 18 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[50]); MULADD(at[1], at[49]); MULADD(at[2], at[48]); MULADD(at[3], at[47]); MULADD(at[4], at[46]); MULADD(at[5], at[45]); MULADD(at[6], at[44]); MULADD(at[7], at[43]); MULADD(at[8], at[42]); MULADD(at[9], at[41]); MULADD(at[10], at[40]); MULADD(at[11], at[39]); MULADD(at[12], at[38]); MULADD(at[13], at[37]); MULADD(at[14], at[36]); MULADD(at[15], at[35]); MULADD(at[16], at[34]); MULADD(at[17], at[33]); MULADD(at[18], at[32]);
+ COMBA_STORE(C->dp[18]);
+ /* 19 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[51]); MULADD(at[1], at[50]); MULADD(at[2], at[49]); MULADD(at[3], at[48]); MULADD(at[4], at[47]); MULADD(at[5], at[46]); MULADD(at[6], at[45]); MULADD(at[7], at[44]); MULADD(at[8], at[43]); MULADD(at[9], at[42]); MULADD(at[10], at[41]); MULADD(at[11], at[40]); MULADD(at[12], at[39]); MULADD(at[13], at[38]); MULADD(at[14], at[37]); MULADD(at[15], at[36]); MULADD(at[16], at[35]); MULADD(at[17], at[34]); MULADD(at[18], at[33]); MULADD(at[19], at[32]);
+ COMBA_STORE(C->dp[19]);
+ /* 20 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[52]); MULADD(at[1], at[51]); MULADD(at[2], at[50]); MULADD(at[3], at[49]); MULADD(at[4], at[48]); MULADD(at[5], at[47]); MULADD(at[6], at[46]); MULADD(at[7], at[45]); MULADD(at[8], at[44]); MULADD(at[9], at[43]); MULADD(at[10], at[42]); MULADD(at[11], at[41]); MULADD(at[12], at[40]); MULADD(at[13], at[39]); MULADD(at[14], at[38]); MULADD(at[15], at[37]); MULADD(at[16], at[36]); MULADD(at[17], at[35]); MULADD(at[18], at[34]); MULADD(at[19], at[33]); MULADD(at[20], at[32]);
+ COMBA_STORE(C->dp[20]);
+ /* 21 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[53]); MULADD(at[1], at[52]); MULADD(at[2], at[51]); MULADD(at[3], at[50]); MULADD(at[4], at[49]); MULADD(at[5], at[48]); MULADD(at[6], at[47]); MULADD(at[7], at[46]); MULADD(at[8], at[45]); MULADD(at[9], at[44]); MULADD(at[10], at[43]); MULADD(at[11], at[42]); MULADD(at[12], at[41]); MULADD(at[13], at[40]); MULADD(at[14], at[39]); MULADD(at[15], at[38]); MULADD(at[16], at[37]); MULADD(at[17], at[36]); MULADD(at[18], at[35]); MULADD(at[19], at[34]); MULADD(at[20], at[33]); MULADD(at[21], at[32]);
+ COMBA_STORE(C->dp[21]);
+ /* 22 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[54]); MULADD(at[1], at[53]); MULADD(at[2], at[52]); MULADD(at[3], at[51]); MULADD(at[4], at[50]); MULADD(at[5], at[49]); MULADD(at[6], at[48]); MULADD(at[7], at[47]); MULADD(at[8], at[46]); MULADD(at[9], at[45]); MULADD(at[10], at[44]); MULADD(at[11], at[43]); MULADD(at[12], at[42]); MULADD(at[13], at[41]); MULADD(at[14], at[40]); MULADD(at[15], at[39]); MULADD(at[16], at[38]); MULADD(at[17], at[37]); MULADD(at[18], at[36]); MULADD(at[19], at[35]); MULADD(at[20], at[34]); MULADD(at[21], at[33]); MULADD(at[22], at[32]);
+ COMBA_STORE(C->dp[22]);
+ /* 23 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[55]); MULADD(at[1], at[54]); MULADD(at[2], at[53]); MULADD(at[3], at[52]); MULADD(at[4], at[51]); MULADD(at[5], at[50]); MULADD(at[6], at[49]); MULADD(at[7], at[48]); MULADD(at[8], at[47]); MULADD(at[9], at[46]); MULADD(at[10], at[45]); MULADD(at[11], at[44]); MULADD(at[12], at[43]); MULADD(at[13], at[42]); MULADD(at[14], at[41]); MULADD(at[15], at[40]); MULADD(at[16], at[39]); MULADD(at[17], at[38]); MULADD(at[18], at[37]); MULADD(at[19], at[36]); MULADD(at[20], at[35]); MULADD(at[21], at[34]); MULADD(at[22], at[33]); MULADD(at[23], at[32]);
+ COMBA_STORE(C->dp[23]);
+ /* 24 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[56]); MULADD(at[1], at[55]); MULADD(at[2], at[54]); MULADD(at[3], at[53]); MULADD(at[4], at[52]); MULADD(at[5], at[51]); MULADD(at[6], at[50]); MULADD(at[7], at[49]); MULADD(at[8], at[48]); MULADD(at[9], at[47]); MULADD(at[10], at[46]); MULADD(at[11], at[45]); MULADD(at[12], at[44]); MULADD(at[13], at[43]); MULADD(at[14], at[42]); MULADD(at[15], at[41]); MULADD(at[16], at[40]); MULADD(at[17], at[39]); MULADD(at[18], at[38]); MULADD(at[19], at[37]); MULADD(at[20], at[36]); MULADD(at[21], at[35]); MULADD(at[22], at[34]); MULADD(at[23], at[33]); MULADD(at[24], at[32]);
+ COMBA_STORE(C->dp[24]);
+ /* 25 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[57]); MULADD(at[1], at[56]); MULADD(at[2], at[55]); MULADD(at[3], at[54]); MULADD(at[4], at[53]); MULADD(at[5], at[52]); MULADD(at[6], at[51]); MULADD(at[7], at[50]); MULADD(at[8], at[49]); MULADD(at[9], at[48]); MULADD(at[10], at[47]); MULADD(at[11], at[46]); MULADD(at[12], at[45]); MULADD(at[13], at[44]); MULADD(at[14], at[43]); MULADD(at[15], at[42]); MULADD(at[16], at[41]); MULADD(at[17], at[40]); MULADD(at[18], at[39]); MULADD(at[19], at[38]); MULADD(at[20], at[37]); MULADD(at[21], at[36]); MULADD(at[22], at[35]); MULADD(at[23], at[34]); MULADD(at[24], at[33]); MULADD(at[25], at[32]);
+ COMBA_STORE(C->dp[25]);
+ /* 26 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[58]); MULADD(at[1], at[57]); MULADD(at[2], at[56]); MULADD(at[3], at[55]); MULADD(at[4], at[54]); MULADD(at[5], at[53]); MULADD(at[6], at[52]); MULADD(at[7], at[51]); MULADD(at[8], at[50]); MULADD(at[9], at[49]); MULADD(at[10], at[48]); MULADD(at[11], at[47]); MULADD(at[12], at[46]); MULADD(at[13], at[45]); MULADD(at[14], at[44]); MULADD(at[15], at[43]); MULADD(at[16], at[42]); MULADD(at[17], at[41]); MULADD(at[18], at[40]); MULADD(at[19], at[39]); MULADD(at[20], at[38]); MULADD(at[21], at[37]); MULADD(at[22], at[36]); MULADD(at[23], at[35]); MULADD(at[24], at[34]); MULADD(at[25], at[33]); MULADD(at[26], at[32]);
+ COMBA_STORE(C->dp[26]);
+ /* 27 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[59]); MULADD(at[1], at[58]); MULADD(at[2], at[57]); MULADD(at[3], at[56]); MULADD(at[4], at[55]); MULADD(at[5], at[54]); MULADD(at[6], at[53]); MULADD(at[7], at[52]); MULADD(at[8], at[51]); MULADD(at[9], at[50]); MULADD(at[10], at[49]); MULADD(at[11], at[48]); MULADD(at[12], at[47]); MULADD(at[13], at[46]); MULADD(at[14], at[45]); MULADD(at[15], at[44]); MULADD(at[16], at[43]); MULADD(at[17], at[42]); MULADD(at[18], at[41]); MULADD(at[19], at[40]); MULADD(at[20], at[39]); MULADD(at[21], at[38]); MULADD(at[22], at[37]); MULADD(at[23], at[36]); MULADD(at[24], at[35]); MULADD(at[25], at[34]); MULADD(at[26], at[33]); MULADD(at[27], at[32]);
+ COMBA_STORE(C->dp[27]);
+ /* 28 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[60]); MULADD(at[1], at[59]); MULADD(at[2], at[58]); MULADD(at[3], at[57]); MULADD(at[4], at[56]); MULADD(at[5], at[55]); MULADD(at[6], at[54]); MULADD(at[7], at[53]); MULADD(at[8], at[52]); MULADD(at[9], at[51]); MULADD(at[10], at[50]); MULADD(at[11], at[49]); MULADD(at[12], at[48]); MULADD(at[13], at[47]); MULADD(at[14], at[46]); MULADD(at[15], at[45]); MULADD(at[16], at[44]); MULADD(at[17], at[43]); MULADD(at[18], at[42]); MULADD(at[19], at[41]); MULADD(at[20], at[40]); MULADD(at[21], at[39]); MULADD(at[22], at[38]); MULADD(at[23], at[37]); MULADD(at[24], at[36]); MULADD(at[25], at[35]); MULADD(at[26], at[34]); MULADD(at[27], at[33]); MULADD(at[28], at[32]);
+ COMBA_STORE(C->dp[28]);
+ /* 29 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[61]); MULADD(at[1], at[60]); MULADD(at[2], at[59]); MULADD(at[3], at[58]); MULADD(at[4], at[57]); MULADD(at[5], at[56]); MULADD(at[6], at[55]); MULADD(at[7], at[54]); MULADD(at[8], at[53]); MULADD(at[9], at[52]); MULADD(at[10], at[51]); MULADD(at[11], at[50]); MULADD(at[12], at[49]); MULADD(at[13], at[48]); MULADD(at[14], at[47]); MULADD(at[15], at[46]); MULADD(at[16], at[45]); MULADD(at[17], at[44]); MULADD(at[18], at[43]); MULADD(at[19], at[42]); MULADD(at[20], at[41]); MULADD(at[21], at[40]); MULADD(at[22], at[39]); MULADD(at[23], at[38]); MULADD(at[24], at[37]); MULADD(at[25], at[36]); MULADD(at[26], at[35]); MULADD(at[27], at[34]); MULADD(at[28], at[33]); MULADD(at[29], at[32]);
+ COMBA_STORE(C->dp[29]);
+ /* 30 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[62]); MULADD(at[1], at[61]); MULADD(at[2], at[60]); MULADD(at[3], at[59]); MULADD(at[4], at[58]); MULADD(at[5], at[57]); MULADD(at[6], at[56]); MULADD(at[7], at[55]); MULADD(at[8], at[54]); MULADD(at[9], at[53]); MULADD(at[10], at[52]); MULADD(at[11], at[51]); MULADD(at[12], at[50]); MULADD(at[13], at[49]); MULADD(at[14], at[48]); MULADD(at[15], at[47]); MULADD(at[16], at[46]); MULADD(at[17], at[45]); MULADD(at[18], at[44]); MULADD(at[19], at[43]); MULADD(at[20], at[42]); MULADD(at[21], at[41]); MULADD(at[22], at[40]); MULADD(at[23], at[39]); MULADD(at[24], at[38]); MULADD(at[25], at[37]); MULADD(at[26], at[36]); MULADD(at[27], at[35]); MULADD(at[28], at[34]); MULADD(at[29], at[33]); MULADD(at[30], at[32]);
+ COMBA_STORE(C->dp[30]);
+ /* 31 */
+ COMBA_FORWARD;
+ MULADD(at[0], at[63]); MULADD(at[1], at[62]); MULADD(at[2], at[61]); MULADD(at[3], at[60]); MULADD(at[4], at[59]); MULADD(at[5], at[58]); MULADD(at[6], at[57]); MULADD(at[7], at[56]); MULADD(at[8], at[55]); MULADD(at[9], at[54]); MULADD(at[10], at[53]); MULADD(at[11], at[52]); MULADD(at[12], at[51]); MULADD(at[13], at[50]); MULADD(at[14], at[49]); MULADD(at[15], at[48]); MULADD(at[16], at[47]); MULADD(at[17], at[46]); MULADD(at[18], at[45]); MULADD(at[19], at[44]); MULADD(at[20], at[43]); MULADD(at[21], at[42]); MULADD(at[22], at[41]); MULADD(at[23], at[40]); MULADD(at[24], at[39]); MULADD(at[25], at[38]); MULADD(at[26], at[37]); MULADD(at[27], at[36]); MULADD(at[28], at[35]); MULADD(at[29], at[34]); MULADD(at[30], at[33]); MULADD(at[31], at[32]);
+ COMBA_STORE(C->dp[31]);
+ /* 32 */
+ COMBA_FORWARD;
+ MULADD(at[1], at[63]); MULADD(at[2], at[62]); MULADD(at[3], at[61]); MULADD(at[4], at[60]); MULADD(at[5], at[59]); MULADD(at[6], at[58]); MULADD(at[7], at[57]); MULADD(at[8], at[56]); MULADD(at[9], at[55]); MULADD(at[10], at[54]); MULADD(at[11], at[53]); MULADD(at[12], at[52]); MULADD(at[13], at[51]); MULADD(at[14], at[50]); MULADD(at[15], at[49]); MULADD(at[16], at[48]); MULADD(at[17], at[47]); MULADD(at[18], at[46]); MULADD(at[19], at[45]); MULADD(at[20], at[44]); MULADD(at[21], at[43]); MULADD(at[22], at[42]); MULADD(at[23], at[41]); MULADD(at[24], at[40]); MULADD(at[25], at[39]); MULADD(at[26], at[38]); MULADD(at[27], at[37]); MULADD(at[28], at[36]); MULADD(at[29], at[35]); MULADD(at[30], at[34]); MULADD(at[31], at[33]);
+ COMBA_STORE(C->dp[32]);
+ /* 33 */
+ COMBA_FORWARD;
+ MULADD(at[2], at[63]); MULADD(at[3], at[62]); MULADD(at[4], at[61]); MULADD(at[5], at[60]); MULADD(at[6], at[59]); MULADD(at[7], at[58]); MULADD(at[8], at[57]); MULADD(at[9], at[56]); MULADD(at[10], at[55]); MULADD(at[11], at[54]); MULADD(at[12], at[53]); MULADD(at[13], at[52]); MULADD(at[14], at[51]); MULADD(at[15], at[50]); MULADD(at[16], at[49]); MULADD(at[17], at[48]); MULADD(at[18], at[47]); MULADD(at[19], at[46]); MULADD(at[20], at[45]); MULADD(at[21], at[44]); MULADD(at[22], at[43]); MULADD(at[23], at[42]); MULADD(at[24], at[41]); MULADD(at[25], at[40]); MULADD(at[26], at[39]); MULADD(at[27], at[38]); MULADD(at[28], at[37]); MULADD(at[29], at[36]); MULADD(at[30], at[35]); MULADD(at[31], at[34]);
+ COMBA_STORE(C->dp[33]);
+ /* 34 */
+ COMBA_FORWARD;
+ MULADD(at[3], at[63]); MULADD(at[4], at[62]); MULADD(at[5], at[61]); MULADD(at[6], at[60]); MULADD(at[7], at[59]); MULADD(at[8], at[58]); MULADD(at[9], at[57]); MULADD(at[10], at[56]); MULADD(at[11], at[55]); MULADD(at[12], at[54]); MULADD(at[13], at[53]); MULADD(at[14], at[52]); MULADD(at[15], at[51]); MULADD(at[16], at[50]); MULADD(at[17], at[49]); MULADD(at[18], at[48]); MULADD(at[19], at[47]); MULADD(at[20], at[46]); MULADD(at[21], at[45]); MULADD(at[22], at[44]); MULADD(at[23], at[43]); MULADD(at[24], at[42]); MULADD(at[25], at[41]); MULADD(at[26], at[40]); MULADD(at[27], at[39]); MULADD(at[28], at[38]); MULADD(at[29], at[37]); MULADD(at[30], at[36]); MULADD(at[31], at[35]);
+ COMBA_STORE(C->dp[34]);
+ /* 35 */
+ COMBA_FORWARD;
+ MULADD(at[4], at[63]); MULADD(at[5], at[62]); MULADD(at[6], at[61]); MULADD(at[7], at[60]); MULADD(at[8], at[59]); MULADD(at[9], at[58]); MULADD(at[10], at[57]); MULADD(at[11], at[56]); MULADD(at[12], at[55]); MULADD(at[13], at[54]); MULADD(at[14], at[53]); MULADD(at[15], at[52]); MULADD(at[16], at[51]); MULADD(at[17], at[50]); MULADD(at[18], at[49]); MULADD(at[19], at[48]); MULADD(at[20], at[47]); MULADD(at[21], at[46]); MULADD(at[22], at[45]); MULADD(at[23], at[44]); MULADD(at[24], at[43]); MULADD(at[25], at[42]); MULADD(at[26], at[41]); MULADD(at[27], at[40]); MULADD(at[28], at[39]); MULADD(at[29], at[38]); MULADD(at[30], at[37]); MULADD(at[31], at[36]);
+ COMBA_STORE(C->dp[35]);
+ /* 36 */
+ COMBA_FORWARD;
+ MULADD(at[5], at[63]); MULADD(at[6], at[62]); MULADD(at[7], at[61]); MULADD(at[8], at[60]); MULADD(at[9], at[59]); MULADD(at[10], at[58]); MULADD(at[11], at[57]); MULADD(at[12], at[56]); MULADD(at[13], at[55]); MULADD(at[14], at[54]); MULADD(at[15], at[53]); MULADD(at[16], at[52]); MULADD(at[17], at[51]); MULADD(at[18], at[50]); MULADD(at[19], at[49]); MULADD(at[20], at[48]); MULADD(at[21], at[47]); MULADD(at[22], at[46]); MULADD(at[23], at[45]); MULADD(at[24], at[44]); MULADD(at[25], at[43]); MULADD(at[26], at[42]); MULADD(at[27], at[41]); MULADD(at[28], at[40]); MULADD(at[29], at[39]); MULADD(at[30], at[38]); MULADD(at[31], at[37]);
+ COMBA_STORE(C->dp[36]);
+ /* 37 */
+ COMBA_FORWARD;
+ MULADD(at[6], at[63]); MULADD(at[7], at[62]); MULADD(at[8], at[61]); MULADD(at[9], at[60]); MULADD(at[10], at[59]); MULADD(at[11], at[58]); MULADD(at[12], at[57]); MULADD(at[13], at[56]); MULADD(at[14], at[55]); MULADD(at[15], at[54]); MULADD(at[16], at[53]); MULADD(at[17], at[52]); MULADD(at[18], at[51]); MULADD(at[19], at[50]); MULADD(at[20], at[49]); MULADD(at[21], at[48]); MULADD(at[22], at[47]); MULADD(at[23], at[46]); MULADD(at[24], at[45]); MULADD(at[25], at[44]); MULADD(at[26], at[43]); MULADD(at[27], at[42]); MULADD(at[28], at[41]); MULADD(at[29], at[40]); MULADD(at[30], at[39]); MULADD(at[31], at[38]);
+ COMBA_STORE(C->dp[37]);
+ /* 38 */
+ COMBA_FORWARD;
+ MULADD(at[7], at[63]); MULADD(at[8], at[62]); MULADD(at[9], at[61]); MULADD(at[10], at[60]); MULADD(at[11], at[59]); MULADD(at[12], at[58]); MULADD(at[13], at[57]); MULADD(at[14], at[56]); MULADD(at[15], at[55]); MULADD(at[16], at[54]); MULADD(at[17], at[53]); MULADD(at[18], at[52]); MULADD(at[19], at[51]); MULADD(at[20], at[50]); MULADD(at[21], at[49]); MULADD(at[22], at[48]); MULADD(at[23], at[47]); MULADD(at[24], at[46]); MULADD(at[25], at[45]); MULADD(at[26], at[44]); MULADD(at[27], at[43]); MULADD(at[28], at[42]); MULADD(at[29], at[41]); MULADD(at[30], at[40]); MULADD(at[31], at[39]);
+ COMBA_STORE(C->dp[38]);
- /* early out at 40 digits, 40*32==1280, or two 640 bit operands */
- if (out_size <= 40) { COMBA_STORE2(C->dp[39]); C->used = 40; C->sign = A->sign ^ B->sign; pstm_clamp(C); COMBA_FINI; return PSTM_OKAY; }
+ /* early out at 40 digits, 40*32==1280, or two 640 bit operands */
+ if (out_size <= 40)
+ {
+ COMBA_STORE2(C->dp[39]); C->used = 40; C->sign = A->sign ^ B->sign; pstm_clamp(C); COMBA_FINI; return PSTM_OKAY;
+ }
- /* 39 */
- COMBA_FORWARD;
- MULADD(at[8], at[63]); MULADD(at[9], at[62]); MULADD(at[10], at[61]); MULADD(at[11], at[60]); MULADD(at[12], at[59]); MULADD(at[13], at[58]); MULADD(at[14], at[57]); MULADD(at[15], at[56]); MULADD(at[16], at[55]); MULADD(at[17], at[54]); MULADD(at[18], at[53]); MULADD(at[19], at[52]); MULADD(at[20], at[51]); MULADD(at[21], at[50]); MULADD(at[22], at[49]); MULADD(at[23], at[48]); MULADD(at[24], at[47]); MULADD(at[25], at[46]); MULADD(at[26], at[45]); MULADD(at[27], at[44]); MULADD(at[28], at[43]); MULADD(at[29], at[42]); MULADD(at[30], at[41]); MULADD(at[31], at[40]);
- COMBA_STORE(C->dp[39]);
- /* 40 */
- COMBA_FORWARD;
- MULADD(at[9], at[63]); MULADD(at[10], at[62]); MULADD(at[11], at[61]); MULADD(at[12], at[60]); MULADD(at[13], at[59]); MULADD(at[14], at[58]); MULADD(at[15], at[57]); MULADD(at[16], at[56]); MULADD(at[17], at[55]); MULADD(at[18], at[54]); MULADD(at[19], at[53]); MULADD(at[20], at[52]); MULADD(at[21], at[51]); MULADD(at[22], at[50]); MULADD(at[23], at[49]); MULADD(at[24], at[48]); MULADD(at[25], at[47]); MULADD(at[26], at[46]); MULADD(at[27], at[45]); MULADD(at[28], at[44]); MULADD(at[29], at[43]); MULADD(at[30], at[42]); MULADD(at[31], at[41]);
- COMBA_STORE(C->dp[40]);
- /* 41 */
- COMBA_FORWARD;
- MULADD(at[10], at[63]); MULADD(at[11], at[62]); MULADD(at[12], at[61]); MULADD(at[13], at[60]); MULADD(at[14], at[59]); MULADD(at[15], at[58]); MULADD(at[16], at[57]); MULADD(at[17], at[56]); MULADD(at[18], at[55]); MULADD(at[19], at[54]); MULADD(at[20], at[53]); MULADD(at[21], at[52]); MULADD(at[22], at[51]); MULADD(at[23], at[50]); MULADD(at[24], at[49]); MULADD(at[25], at[48]); MULADD(at[26], at[47]); MULADD(at[27], at[46]); MULADD(at[28], at[45]); MULADD(at[29], at[44]); MULADD(at[30], at[43]); MULADD(at[31], at[42]);
- COMBA_STORE(C->dp[41]);
- /* 42 */
- COMBA_FORWARD;
- MULADD(at[11], at[63]); MULADD(at[12], at[62]); MULADD(at[13], at[61]); MULADD(at[14], at[60]); MULADD(at[15], at[59]); MULADD(at[16], at[58]); MULADD(at[17], at[57]); MULADD(at[18], at[56]); MULADD(at[19], at[55]); MULADD(at[20], at[54]); MULADD(at[21], at[53]); MULADD(at[22], at[52]); MULADD(at[23], at[51]); MULADD(at[24], at[50]); MULADD(at[25], at[49]); MULADD(at[26], at[48]); MULADD(at[27], at[47]); MULADD(at[28], at[46]); MULADD(at[29], at[45]); MULADD(at[30], at[44]); MULADD(at[31], at[43]);
- COMBA_STORE(C->dp[42]);
- /* 43 */
- COMBA_FORWARD;
- MULADD(at[12], at[63]); MULADD(at[13], at[62]); MULADD(at[14], at[61]); MULADD(at[15], at[60]); MULADD(at[16], at[59]); MULADD(at[17], at[58]); MULADD(at[18], at[57]); MULADD(at[19], at[56]); MULADD(at[20], at[55]); MULADD(at[21], at[54]); MULADD(at[22], at[53]); MULADD(at[23], at[52]); MULADD(at[24], at[51]); MULADD(at[25], at[50]); MULADD(at[26], at[49]); MULADD(at[27], at[48]); MULADD(at[28], at[47]); MULADD(at[29], at[46]); MULADD(at[30], at[45]); MULADD(at[31], at[44]);
- COMBA_STORE(C->dp[43]);
- /* 44 */
- COMBA_FORWARD;
- MULADD(at[13], at[63]); MULADD(at[14], at[62]); MULADD(at[15], at[61]); MULADD(at[16], at[60]); MULADD(at[17], at[59]); MULADD(at[18], at[58]); MULADD(at[19], at[57]); MULADD(at[20], at[56]); MULADD(at[21], at[55]); MULADD(at[22], at[54]); MULADD(at[23], at[53]); MULADD(at[24], at[52]); MULADD(at[25], at[51]); MULADD(at[26], at[50]); MULADD(at[27], at[49]); MULADD(at[28], at[48]); MULADD(at[29], at[47]); MULADD(at[30], at[46]); MULADD(at[31], at[45]);
- COMBA_STORE(C->dp[44]);
- /* 45 */
- COMBA_FORWARD;
- MULADD(at[14], at[63]); MULADD(at[15], at[62]); MULADD(at[16], at[61]); MULADD(at[17], at[60]); MULADD(at[18], at[59]); MULADD(at[19], at[58]); MULADD(at[20], at[57]); MULADD(at[21], at[56]); MULADD(at[22], at[55]); MULADD(at[23], at[54]); MULADD(at[24], at[53]); MULADD(at[25], at[52]); MULADD(at[26], at[51]); MULADD(at[27], at[50]); MULADD(at[28], at[49]); MULADD(at[29], at[48]); MULADD(at[30], at[47]); MULADD(at[31], at[46]);
- COMBA_STORE(C->dp[45]);
- /* 46 */
- COMBA_FORWARD;
- MULADD(at[15], at[63]); MULADD(at[16], at[62]); MULADD(at[17], at[61]); MULADD(at[18], at[60]); MULADD(at[19], at[59]); MULADD(at[20], at[58]); MULADD(at[21], at[57]); MULADD(at[22], at[56]); MULADD(at[23], at[55]); MULADD(at[24], at[54]); MULADD(at[25], at[53]); MULADD(at[26], at[52]); MULADD(at[27], at[51]); MULADD(at[28], at[50]); MULADD(at[29], at[49]); MULADD(at[30], at[48]); MULADD(at[31], at[47]);
- COMBA_STORE(C->dp[46]);
+ /* 39 */
+ COMBA_FORWARD;
+ MULADD(at[8], at[63]); MULADD(at[9], at[62]); MULADD(at[10], at[61]); MULADD(at[11], at[60]); MULADD(at[12], at[59]); MULADD(at[13], at[58]); MULADD(at[14], at[57]); MULADD(at[15], at[56]); MULADD(at[16], at[55]); MULADD(at[17], at[54]); MULADD(at[18], at[53]); MULADD(at[19], at[52]); MULADD(at[20], at[51]); MULADD(at[21], at[50]); MULADD(at[22], at[49]); MULADD(at[23], at[48]); MULADD(at[24], at[47]); MULADD(at[25], at[46]); MULADD(at[26], at[45]); MULADD(at[27], at[44]); MULADD(at[28], at[43]); MULADD(at[29], at[42]); MULADD(at[30], at[41]); MULADD(at[31], at[40]);
+ COMBA_STORE(C->dp[39]);
+ /* 40 */
+ COMBA_FORWARD;
+ MULADD(at[9], at[63]); MULADD(at[10], at[62]); MULADD(at[11], at[61]); MULADD(at[12], at[60]); MULADD(at[13], at[59]); MULADD(at[14], at[58]); MULADD(at[15], at[57]); MULADD(at[16], at[56]); MULADD(at[17], at[55]); MULADD(at[18], at[54]); MULADD(at[19], at[53]); MULADD(at[20], at[52]); MULADD(at[21], at[51]); MULADD(at[22], at[50]); MULADD(at[23], at[49]); MULADD(at[24], at[48]); MULADD(at[25], at[47]); MULADD(at[26], at[46]); MULADD(at[27], at[45]); MULADD(at[28], at[44]); MULADD(at[29], at[43]); MULADD(at[30], at[42]); MULADD(at[31], at[41]);
+ COMBA_STORE(C->dp[40]);
+ /* 41 */
+ COMBA_FORWARD;
+ MULADD(at[10], at[63]); MULADD(at[11], at[62]); MULADD(at[12], at[61]); MULADD(at[13], at[60]); MULADD(at[14], at[59]); MULADD(at[15], at[58]); MULADD(at[16], at[57]); MULADD(at[17], at[56]); MULADD(at[18], at[55]); MULADD(at[19], at[54]); MULADD(at[20], at[53]); MULADD(at[21], at[52]); MULADD(at[22], at[51]); MULADD(at[23], at[50]); MULADD(at[24], at[49]); MULADD(at[25], at[48]); MULADD(at[26], at[47]); MULADD(at[27], at[46]); MULADD(at[28], at[45]); MULADD(at[29], at[44]); MULADD(at[30], at[43]); MULADD(at[31], at[42]);
+ COMBA_STORE(C->dp[41]);
+ /* 42 */
+ COMBA_FORWARD;
+ MULADD(at[11], at[63]); MULADD(at[12], at[62]); MULADD(at[13], at[61]); MULADD(at[14], at[60]); MULADD(at[15], at[59]); MULADD(at[16], at[58]); MULADD(at[17], at[57]); MULADD(at[18], at[56]); MULADD(at[19], at[55]); MULADD(at[20], at[54]); MULADD(at[21], at[53]); MULADD(at[22], at[52]); MULADD(at[23], at[51]); MULADD(at[24], at[50]); MULADD(at[25], at[49]); MULADD(at[26], at[48]); MULADD(at[27], at[47]); MULADD(at[28], at[46]); MULADD(at[29], at[45]); MULADD(at[30], at[44]); MULADD(at[31], at[43]);
+ COMBA_STORE(C->dp[42]);
+ /* 43 */
+ COMBA_FORWARD;
+ MULADD(at[12], at[63]); MULADD(at[13], at[62]); MULADD(at[14], at[61]); MULADD(at[15], at[60]); MULADD(at[16], at[59]); MULADD(at[17], at[58]); MULADD(at[18], at[57]); MULADD(at[19], at[56]); MULADD(at[20], at[55]); MULADD(at[21], at[54]); MULADD(at[22], at[53]); MULADD(at[23], at[52]); MULADD(at[24], at[51]); MULADD(at[25], at[50]); MULADD(at[26], at[49]); MULADD(at[27], at[48]); MULADD(at[28], at[47]); MULADD(at[29], at[46]); MULADD(at[30], at[45]); MULADD(at[31], at[44]);
+ COMBA_STORE(C->dp[43]);
+ /* 44 */
+ COMBA_FORWARD;
+ MULADD(at[13], at[63]); MULADD(at[14], at[62]); MULADD(at[15], at[61]); MULADD(at[16], at[60]); MULADD(at[17], at[59]); MULADD(at[18], at[58]); MULADD(at[19], at[57]); MULADD(at[20], at[56]); MULADD(at[21], at[55]); MULADD(at[22], at[54]); MULADD(at[23], at[53]); MULADD(at[24], at[52]); MULADD(at[25], at[51]); MULADD(at[26], at[50]); MULADD(at[27], at[49]); MULADD(at[28], at[48]); MULADD(at[29], at[47]); MULADD(at[30], at[46]); MULADD(at[31], at[45]);
+ COMBA_STORE(C->dp[44]);
+ /* 45 */
+ COMBA_FORWARD;
+ MULADD(at[14], at[63]); MULADD(at[15], at[62]); MULADD(at[16], at[61]); MULADD(at[17], at[60]); MULADD(at[18], at[59]); MULADD(at[19], at[58]); MULADD(at[20], at[57]); MULADD(at[21], at[56]); MULADD(at[22], at[55]); MULADD(at[23], at[54]); MULADD(at[24], at[53]); MULADD(at[25], at[52]); MULADD(at[26], at[51]); MULADD(at[27], at[50]); MULADD(at[28], at[49]); MULADD(at[29], at[48]); MULADD(at[30], at[47]); MULADD(at[31], at[46]);
+ COMBA_STORE(C->dp[45]);
+ /* 46 */
+ COMBA_FORWARD;
+ MULADD(at[15], at[63]); MULADD(at[16], at[62]); MULADD(at[17], at[61]); MULADD(at[18], at[60]); MULADD(at[19], at[59]); MULADD(at[20], at[58]); MULADD(at[21], at[57]); MULADD(at[22], at[56]); MULADD(at[23], at[55]); MULADD(at[24], at[54]); MULADD(at[25], at[53]); MULADD(at[26], at[52]); MULADD(at[27], at[51]); MULADD(at[28], at[50]); MULADD(at[29], at[49]); MULADD(at[30], at[48]); MULADD(at[31], at[47]);
+ COMBA_STORE(C->dp[46]);
- /* early out at 48 digits, 48*32==1536, or two 768 bit operands */
- if (out_size <= 48) { COMBA_STORE2(C->dp[47]); C->used = 48; C->sign = A->sign ^ B->sign; pstm_clamp(C); COMBA_FINI; return PSTM_OKAY; }
+ /* early out at 48 digits, 48*32==1536, or two 768 bit operands */
+ if (out_size <= 48)
+ {
+ COMBA_STORE2(C->dp[47]); C->used = 48; C->sign = A->sign ^ B->sign; pstm_clamp(C); COMBA_FINI; return PSTM_OKAY;
+ }
- /* 47 */
- COMBA_FORWARD;
- MULADD(at[16], at[63]); MULADD(at[17], at[62]); MULADD(at[18], at[61]); MULADD(at[19], at[60]); MULADD(at[20], at[59]); MULADD(at[21], at[58]); MULADD(at[22], at[57]); MULADD(at[23], at[56]); MULADD(at[24], at[55]); MULADD(at[25], at[54]); MULADD(at[26], at[53]); MULADD(at[27], at[52]); MULADD(at[28], at[51]); MULADD(at[29], at[50]); MULADD(at[30], at[49]); MULADD(at[31], at[48]);
- COMBA_STORE(C->dp[47]);
- /* 48 */
- COMBA_FORWARD;
- MULADD(at[17], at[63]); MULADD(at[18], at[62]); MULADD(at[19], at[61]); MULADD(at[20], at[60]); MULADD(at[21], at[59]); MULADD(at[22], at[58]); MULADD(at[23], at[57]); MULADD(at[24], at[56]); MULADD(at[25], at[55]); MULADD(at[26], at[54]); MULADD(at[27], at[53]); MULADD(at[28], at[52]); MULADD(at[29], at[51]); MULADD(at[30], at[50]); MULADD(at[31], at[49]);
- COMBA_STORE(C->dp[48]);
- /* 49 */
- COMBA_FORWARD;
- MULADD(at[18], at[63]); MULADD(at[19], at[62]); MULADD(at[20], at[61]); MULADD(at[21], at[60]); MULADD(at[22], at[59]); MULADD(at[23], at[58]); MULADD(at[24], at[57]); MULADD(at[25], at[56]); MULADD(at[26], at[55]); MULADD(at[27], at[54]); MULADD(at[28], at[53]); MULADD(at[29], at[52]); MULADD(at[30], at[51]); MULADD(at[31], at[50]);
- COMBA_STORE(C->dp[49]);
- /* 50 */
- COMBA_FORWARD;
- MULADD(at[19], at[63]); MULADD(at[20], at[62]); MULADD(at[21], at[61]); MULADD(at[22], at[60]); MULADD(at[23], at[59]); MULADD(at[24], at[58]); MULADD(at[25], at[57]); MULADD(at[26], at[56]); MULADD(at[27], at[55]); MULADD(at[28], at[54]); MULADD(at[29], at[53]); MULADD(at[30], at[52]); MULADD(at[31], at[51]);
- COMBA_STORE(C->dp[50]);
- /* 51 */
- COMBA_FORWARD;
- MULADD(at[20], at[63]); MULADD(at[21], at[62]); MULADD(at[22], at[61]); MULADD(at[23], at[60]); MULADD(at[24], at[59]); MULADD(at[25], at[58]); MULADD(at[26], at[57]); MULADD(at[27], at[56]); MULADD(at[28], at[55]); MULADD(at[29], at[54]); MULADD(at[30], at[53]); MULADD(at[31], at[52]);
- COMBA_STORE(C->dp[51]);
- /* 52 */
- COMBA_FORWARD;
- MULADD(at[21], at[63]); MULADD(at[22], at[62]); MULADD(at[23], at[61]); MULADD(at[24], at[60]); MULADD(at[25], at[59]); MULADD(at[26], at[58]); MULADD(at[27], at[57]); MULADD(at[28], at[56]); MULADD(at[29], at[55]); MULADD(at[30], at[54]); MULADD(at[31], at[53]);
- COMBA_STORE(C->dp[52]);
- /* 53 */
- COMBA_FORWARD;
- MULADD(at[22], at[63]); MULADD(at[23], at[62]); MULADD(at[24], at[61]); MULADD(at[25], at[60]); MULADD(at[26], at[59]); MULADD(at[27], at[58]); MULADD(at[28], at[57]); MULADD(at[29], at[56]); MULADD(at[30], at[55]); MULADD(at[31], at[54]);
- COMBA_STORE(C->dp[53]);
- /* 54 */
- COMBA_FORWARD;
- MULADD(at[23], at[63]); MULADD(at[24], at[62]); MULADD(at[25], at[61]); MULADD(at[26], at[60]); MULADD(at[27], at[59]); MULADD(at[28], at[58]); MULADD(at[29], at[57]); MULADD(at[30], at[56]); MULADD(at[31], at[55]);
- COMBA_STORE(C->dp[54]);
+ /* 47 */
+ COMBA_FORWARD;
+ MULADD(at[16], at[63]); MULADD(at[17], at[62]); MULADD(at[18], at[61]); MULADD(at[19], at[60]); MULADD(at[20], at[59]); MULADD(at[21], at[58]); MULADD(at[22], at[57]); MULADD(at[23], at[56]); MULADD(at[24], at[55]); MULADD(at[25], at[54]); MULADD(at[26], at[53]); MULADD(at[27], at[52]); MULADD(at[28], at[51]); MULADD(at[29], at[50]); MULADD(at[30], at[49]); MULADD(at[31], at[48]);
+ COMBA_STORE(C->dp[47]);
+ /* 48 */
+ COMBA_FORWARD;
+ MULADD(at[17], at[63]); MULADD(at[18], at[62]); MULADD(at[19], at[61]); MULADD(at[20], at[60]); MULADD(at[21], at[59]); MULADD(at[22], at[58]); MULADD(at[23], at[57]); MULADD(at[24], at[56]); MULADD(at[25], at[55]); MULADD(at[26], at[54]); MULADD(at[27], at[53]); MULADD(at[28], at[52]); MULADD(at[29], at[51]); MULADD(at[30], at[50]); MULADD(at[31], at[49]);
+ COMBA_STORE(C->dp[48]);
+ /* 49 */
+ COMBA_FORWARD;
+ MULADD(at[18], at[63]); MULADD(at[19], at[62]); MULADD(at[20], at[61]); MULADD(at[21], at[60]); MULADD(at[22], at[59]); MULADD(at[23], at[58]); MULADD(at[24], at[57]); MULADD(at[25], at[56]); MULADD(at[26], at[55]); MULADD(at[27], at[54]); MULADD(at[28], at[53]); MULADD(at[29], at[52]); MULADD(at[30], at[51]); MULADD(at[31], at[50]);
+ COMBA_STORE(C->dp[49]);
+ /* 50 */
+ COMBA_FORWARD;
+ MULADD(at[19], at[63]); MULADD(at[20], at[62]); MULADD(at[21], at[61]); MULADD(at[22], at[60]); MULADD(at[23], at[59]); MULADD(at[24], at[58]); MULADD(at[25], at[57]); MULADD(at[26], at[56]); MULADD(at[27], at[55]); MULADD(at[28], at[54]); MULADD(at[29], at[53]); MULADD(at[30], at[52]); MULADD(at[31], at[51]);
+ COMBA_STORE(C->dp[50]);
+ /* 51 */
+ COMBA_FORWARD;
+ MULADD(at[20], at[63]); MULADD(at[21], at[62]); MULADD(at[22], at[61]); MULADD(at[23], at[60]); MULADD(at[24], at[59]); MULADD(at[25], at[58]); MULADD(at[26], at[57]); MULADD(at[27], at[56]); MULADD(at[28], at[55]); MULADD(at[29], at[54]); MULADD(at[30], at[53]); MULADD(at[31], at[52]);
+ COMBA_STORE(C->dp[51]);
+ /* 52 */
+ COMBA_FORWARD;
+ MULADD(at[21], at[63]); MULADD(at[22], at[62]); MULADD(at[23], at[61]); MULADD(at[24], at[60]); MULADD(at[25], at[59]); MULADD(at[26], at[58]); MULADD(at[27], at[57]); MULADD(at[28], at[56]); MULADD(at[29], at[55]); MULADD(at[30], at[54]); MULADD(at[31], at[53]);
+ COMBA_STORE(C->dp[52]);
+ /* 53 */
+ COMBA_FORWARD;
+ MULADD(at[22], at[63]); MULADD(at[23], at[62]); MULADD(at[24], at[61]); MULADD(at[25], at[60]); MULADD(at[26], at[59]); MULADD(at[27], at[58]); MULADD(at[28], at[57]); MULADD(at[29], at[56]); MULADD(at[30], at[55]); MULADD(at[31], at[54]);
+ COMBA_STORE(C->dp[53]);
+ /* 54 */
+ COMBA_FORWARD;
+ MULADD(at[23], at[63]); MULADD(at[24], at[62]); MULADD(at[25], at[61]); MULADD(at[26], at[60]); MULADD(at[27], at[59]); MULADD(at[28], at[58]); MULADD(at[29], at[57]); MULADD(at[30], at[56]); MULADD(at[31], at[55]);
+ COMBA_STORE(C->dp[54]);
- /* early out at 56 digits, 56*32==1792, or two 896 bit operands */
- if (out_size <= 56) { COMBA_STORE2(C->dp[55]); C->used = 56; C->sign = A->sign ^ B->sign; pstm_clamp(C); COMBA_FINI; return PSTM_OKAY; }
+ /* early out at 56 digits, 56*32==1792, or two 896 bit operands */
+ if (out_size <= 56)
+ {
+ COMBA_STORE2(C->dp[55]); C->used = 56; C->sign = A->sign ^ B->sign; pstm_clamp(C); COMBA_FINI; return PSTM_OKAY;
+ }
- /* 55 */
- COMBA_FORWARD;
- MULADD(at[24], at[63]); MULADD(at[25], at[62]); MULADD(at[26], at[61]); MULADD(at[27], at[60]); MULADD(at[28], at[59]); MULADD(at[29], at[58]); MULADD(at[30], at[57]); MULADD(at[31], at[56]);
- COMBA_STORE(C->dp[55]);
- /* 56 */
- COMBA_FORWARD;
- MULADD(at[25], at[63]); MULADD(at[26], at[62]); MULADD(at[27], at[61]); MULADD(at[28], at[60]); MULADD(at[29], at[59]); MULADD(at[30], at[58]); MULADD(at[31], at[57]);
- COMBA_STORE(C->dp[56]);
- /* 57 */
- COMBA_FORWARD;
- MULADD(at[26], at[63]); MULADD(at[27], at[62]); MULADD(at[28], at[61]); MULADD(at[29], at[60]); MULADD(at[30], at[59]); MULADD(at[31], at[58]);
- COMBA_STORE(C->dp[57]);
- /* 58 */
- COMBA_FORWARD;
- MULADD(at[27], at[63]); MULADD(at[28], at[62]); MULADD(at[29], at[61]); MULADD(at[30], at[60]); MULADD(at[31], at[59]);
- COMBA_STORE(C->dp[58]);
- /* 59 */
- COMBA_FORWARD;
- MULADD(at[28], at[63]); MULADD(at[29], at[62]); MULADD(at[30], at[61]); MULADD(at[31], at[60]);
- COMBA_STORE(C->dp[59]);
- /* 60 */
- COMBA_FORWARD;
- MULADD(at[29], at[63]); MULADD(at[30], at[62]); MULADD(at[31], at[61]);
- COMBA_STORE(C->dp[60]);
- /* 61 */
- COMBA_FORWARD;
- MULADD(at[30], at[63]); MULADD(at[31], at[62]);
- COMBA_STORE(C->dp[61]);
- /* 62 */
- COMBA_FORWARD;
- MULADD(at[31], at[63]);
- COMBA_STORE(C->dp[62]);
- COMBA_STORE2(C->dp[63]);
- C->used = 64;
- C->sign = A->sign ^ B->sign;
- pstm_clamp(C);
- COMBA_FINI;
- return PSTM_OKAY;
+ /* 55 */
+ COMBA_FORWARD;
+ MULADD(at[24], at[63]); MULADD(at[25], at[62]); MULADD(at[26], at[61]); MULADD(at[27], at[60]); MULADD(at[28], at[59]); MULADD(at[29], at[58]); MULADD(at[30], at[57]); MULADD(at[31], at[56]);
+ COMBA_STORE(C->dp[55]);
+ /* 56 */
+ COMBA_FORWARD;
+ MULADD(at[25], at[63]); MULADD(at[26], at[62]); MULADD(at[27], at[61]); MULADD(at[28], at[60]); MULADD(at[29], at[59]); MULADD(at[30], at[58]); MULADD(at[31], at[57]);
+ COMBA_STORE(C->dp[56]);
+ /* 57 */
+ COMBA_FORWARD;
+ MULADD(at[26], at[63]); MULADD(at[27], at[62]); MULADD(at[28], at[61]); MULADD(at[29], at[60]); MULADD(at[30], at[59]); MULADD(at[31], at[58]);
+ COMBA_STORE(C->dp[57]);
+ /* 58 */
+ COMBA_FORWARD;
+ MULADD(at[27], at[63]); MULADD(at[28], at[62]); MULADD(at[29], at[61]); MULADD(at[30], at[60]); MULADD(at[31], at[59]);
+ COMBA_STORE(C->dp[58]);
+ /* 59 */
+ COMBA_FORWARD;
+ MULADD(at[28], at[63]); MULADD(at[29], at[62]); MULADD(at[30], at[61]); MULADD(at[31], at[60]);
+ COMBA_STORE(C->dp[59]);
+ /* 60 */
+ COMBA_FORWARD;
+ MULADD(at[29], at[63]); MULADD(at[30], at[62]); MULADD(at[31], at[61]);
+ COMBA_STORE(C->dp[60]);
+ /* 61 */
+ COMBA_FORWARD;
+ MULADD(at[30], at[63]); MULADD(at[31], at[62]);
+ COMBA_STORE(C->dp[61]);
+ /* 62 */
+ COMBA_FORWARD;
+ MULADD(at[31], at[63]);
+ COMBA_STORE(C->dp[62]);
+ COMBA_STORE2(C->dp[63]);
+ C->used = 64;
+ C->sign = A->sign ^ B->sign;
+ pstm_clamp(C);
+ COMBA_FINI;
+ return PSTM_OKAY;
}
-#endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */
+# endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */
/******************************************************************************/
int32 pstm_mul_comba(psPool_t *pool, const pstm_int *A, const pstm_int *B, pstm_int *C,
- pstm_digit *paD, uint16_t paDlen)
+ pstm_digit *paD, psSize_t paDlen)
{
-#ifdef USE_1024_KEY_SPEED_OPTIMIZATIONS
- if (A->used == 16 && B->used == 16) {
- return pstm_mul_comba16(A, B, C);
- } else {
-#ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS
- if (A->used == 32 && B->used == 32) {
- return pstm_mul_comba32(A, B, C);
- }
-#endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */
- return pstm_mul_comba_gen(pool, A, B, C, paD, paDlen);
- }
-#else
-#ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS
- if (A->used == 32 && B->used == 32) {
- return pstm_mul_comba32(A, B, C);
- }
-#endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */
- return pstm_mul_comba_gen(pool, A, B, C, paD, paDlen);
-#endif
+# ifdef USE_1024_KEY_SPEED_OPTIMIZATIONS
+ if (A->used == 16 && B->used == 16)
+ {
+ return pstm_mul_comba16(A, B, C);
+ }
+ else
+ {
+# ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS
+ if (A->used == 32 && B->used == 32)
+ {
+ return pstm_mul_comba32(A, B, C);
+ }
+# endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */
+ return pstm_mul_comba_gen(pool, A, B, C, paD, paDlen);
+ }
+# else
+# ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS
+ if (A->used == 32 && B->used == 32)
+ {
+ return pstm_mul_comba32(A, B, C);
+ }
+# endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */
+ return pstm_mul_comba_gen(pool, A, B, C, paD, paDlen);
+# endif
}
#endif /* defined(USE_MATRIX_RSA) || defined(USE_MATRIX_ECC) */
diff --git a/crypto/math/pstm_sqr_comba.c b/crypto/math/pstm_sqr_comba.c
index e337767..0b02b25 100644
--- a/crypto/math/pstm_sqr_comba.c
+++ b/crypto/math/pstm_sqr_comba.c
@@ -1,1106 +1,1134 @@
/**
- * @file pstm_sqr_comba.c
- * @version $Format:%h%d$
+ * @file pstm_sqr_comba.c
+ * @version $Format:%h%d$
*
- * Multiprecision Squaring with Comba technique.
+ * Multiprecision Squaring with Comba technique.
*/
/*
- * Copyright (c) 2013-2016 INSIDE Secure Corporation
- * Copyright (c) PeerSec Networks, 2002-2011
- * All Rights Reserved
+ * Copyright (c) 2013-2017 INSIDE Secure Corporation
+ * Copyright (c) PeerSec Networks, 2002-2011
+ * All Rights Reserved
*
- * The latest version of this code is available at http://www.matrixssl.org
+ * The latest version of this code is available at http://www.matrixssl.org
*
- * This software is open source; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
*
- * This General Public License does NOT permit incorporating this software
- * into proprietary programs. If you are unable to comply with the GPL, a
- * commercial license for this software may be purchased from INSIDE at
- * http://www.insidesecure.com/
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
*
- * This program is distributed in WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * http://www.gnu.org/copyleft/gpl.html
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
*/
/******************************************************************************/
-#include "../cryptoApi.h"
+#include "../cryptoImpl.h"
#if defined(USE_MATRIX_RSA) || defined(USE_MATRIX_ECC) || defined(USE_MATRIX_DH)
/******************************************************************************/
-#if defined(PSTM_X86)
+# if defined(PSTM_X86)
/* x86-32 optimized for 32 bit platforms. For 64 bit mode use X86_64 instead */
-#if !defined(__GNUC__) || !defined(__i386__)
-#error "PSTM_X86 option requires GCC and 32 bit mode x86 processor"
-#endif
-//#pragma message ("Using 32 bit x86 Assembly Optimizations")
+# if !defined(__GNUC__) || !defined(__i386__)
+# error "PSTM_X86 option requires GCC and 32 bit mode x86 processor"
+# endif
+/* #pragma message ("Using 32 bit x86 Assembly Optimizations") */
-#define COMBA_START
+# define COMBA_START
-#define CLEAR_CARRY \
- c0 = c1 = c2 = 0;
+# define CLEAR_CARRY \
+ c0 = c1 = c2 = 0;
-#define COMBA_STORE(x) \
- x = c0;
+# define COMBA_STORE(x) \
+ x = c0;
-#define COMBA_STORE2(x) \
- x = c1;
+# define COMBA_STORE2(x) \
+ x = c1;
-#define CARRY_FORWARD \
- do { c0 = c1; c1 = c2; c2 = 0; } while (0);
+# define CARRY_FORWARD \
+ do { c0 = c1; c1 = c2; c2 = 0; } while (0);
-#define COMBA_FINI
+# define COMBA_FINI
-#define SQRADD(i, j) \
-asm( \
- "movl %6,%%eax \n\t" \
- "mull %%eax \n\t" \
- "addl %%eax,%0 \n\t" \
- "adcl %%edx,%1 \n\t" \
- "adcl $0,%2 \n\t" \
- :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i) :"%eax","%edx","cc");
+# define SQRADD(i, j) \
+ asm ( \
+ "movl %6,%%eax \n\t" \
+ "mull %%eax \n\t" \
+ "addl %%eax,%0 \n\t" \
+ "adcl %%edx,%1 \n\t" \
+ "adcl $0,%2 \n\t" \
+ : "=r" (c0), "=r" (c1), "=r" (c2) : "0" (c0), "1" (c1), "2" (c2), "m" (i) : "%eax", "%edx", "cc");
-#define SQRADD2(i, j) \
-asm( \
- "movl %6,%%eax \n\t" \
- "mull %7 \n\t" \
- "addl %%eax,%0 \n\t" \
- "adcl %%edx,%1 \n\t" \
- "adcl $0,%2 \n\t" \
- "addl %%eax,%0 \n\t" \
- "adcl %%edx,%1 \n\t" \
- "adcl $0,%2 \n\t" \
- :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","cc");
+# define SQRADD2(i, j) \
+ asm ( \
+ "movl %6,%%eax \n\t" \
+ "mull %7 \n\t" \
+ "addl %%eax,%0 \n\t" \
+ "adcl %%edx,%1 \n\t" \
+ "adcl $0,%2 \n\t" \
+ "addl %%eax,%0 \n\t" \
+ "adcl %%edx,%1 \n\t" \
+ "adcl $0,%2 \n\t" \
+ : "=r" (c0), "=r" (c1), "=r" (c2) : "0" (c0), "1" (c1), "2" (c2), "m" (i), "m" (j) : "%eax", "%edx", "cc");
-#define SQRADDSC(i, j) \
-asm( \
- "movl %6,%%eax \n\t" \
- "mull %7 \n\t" \
- "movl %%eax,%0 \n\t" \
- "movl %%edx,%1 \n\t" \
- "xorl %2,%2 \n\t" \
- :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%eax","%edx","cc");
+# define SQRADDSC(i, j) \
+ asm ( \
+ "movl %6,%%eax \n\t" \
+ "mull %7 \n\t" \
+ "movl %%eax,%0 \n\t" \
+ "movl %%edx,%1 \n\t" \
+ "xorl %2,%2 \n\t" \
+ : "=r" (sc0), "=r" (sc1), "=r" (sc2) : "0" (sc0), "1" (sc1), "2" (sc2), "g" (i), "g" (j) : "%eax", "%edx", "cc");
-#define SQRADDAC(i, j) \
-asm( \
- "movl %6,%%eax \n\t" \
- "mull %7 \n\t" \
- "addl %%eax,%0 \n\t" \
- "adcl %%edx,%1 \n\t" \
- "adcl $0,%2 \n\t" \
- :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%eax","%edx","cc");
+# define SQRADDAC(i, j) \
+ asm ( \
+ "movl %6,%%eax \n\t" \
+ "mull %7 \n\t" \
+ "addl %%eax,%0 \n\t" \
+ "adcl %%edx,%1 \n\t" \
+ "adcl $0,%2 \n\t" \
+ : "=r" (sc0), "=r" (sc1), "=r" (sc2) : "0" (sc0), "1" (sc1), "2" (sc2), "g" (i), "g" (j) : "%eax", "%edx", "cc");
-#define SQRADDDB \
-asm( \
- "addl %6,%0 \n\t" \
- "adcl %7,%1 \n\t" \
- "adcl %8,%2 \n\t" \
- "addl %6,%0 \n\t" \
- "adcl %7,%1 \n\t" \
- "adcl %8,%2 \n\t" \
- :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(sc0), "r"(sc1), "r"(sc2) : "cc");
+# define SQRADDDB \
+ asm ( \
+ "addl %6,%0 \n\t" \
+ "adcl %7,%1 \n\t" \
+ "adcl %8,%2 \n\t" \
+ "addl %6,%0 \n\t" \
+ "adcl %7,%1 \n\t" \
+ "adcl %8,%2 \n\t" \
+ : "=r" (c0), "=r" (c1), "=r" (c2) : "0" (c0), "1" (c1), "2" (c2), "r" (sc0), "r" (sc1), "r" (sc2) : "cc");
/******************************************************************************/
-#elif defined(PSTM_X86_64)
+# elif defined(PSTM_X86_64)
/* x86-64 optimized */
-#if !defined(__GNUC__) || !defined(__x86_64__) || !defined(PSTM_64BIT)
-#error "PSTM_X86_64 option requires PSTM_64BIT, GCC and 64 bit mode x86 processor"
-#endif
-//#pragma message ("Using 64 bit x86_64 Assembly Optimizations")
+# if !defined(__GNUC__) || !defined(__x86_64__) || !defined(PSTM_64BIT)
+# error "PSTM_X86_64 option requires PSTM_64BIT, GCC and 64 bit mode x86 processor"
+# endif
+/* #pragma message ("Using 64 bit x86_64 Assembly Optimizations") */
-#define COMBA_START
+# define COMBA_START
-#define CLEAR_CARRY \
-c0 = c1 = c2 = 0;
+# define CLEAR_CARRY \
+ c0 = c1 = c2 = 0;
-#define COMBA_STORE(x) \
-x = c0;
+# define COMBA_STORE(x) \
+ x = c0;
-#define COMBA_STORE2(x) \
-x = c1;
+# define COMBA_STORE2(x) \
+ x = c1;
-#define CARRY_FORWARD \
-do { c0 = c1; c1 = c2; c2 = 0; } while (0);
+# define CARRY_FORWARD \
+ do { c0 = c1; c1 = c2; c2 = 0; } while (0);
-#define COMBA_FINI
+# define COMBA_FINI
-#define SQRADD(i, j) \
-asm( \
- "movq %6,%%rax \n\t" \
- "mulq %%rax \n\t" \
- "addq %%rax,%0 \n\t" \
- "adcq %%rdx,%1 \n\t" \
- "adcq $0,%2 \n\t" \
- :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i) :"%rax","%rdx","cc");
+# define SQRADD(i, j) \
+ asm ( \
+ "movq %6,%%rax \n\t" \
+ "mulq %%rax \n\t" \
+ "addq %%rax,%0 \n\t" \
+ "adcq %%rdx,%1 \n\t" \
+ "adcq $0,%2 \n\t" \
+ : "=r" (c0), "=r" (c1), "=r" (c2) : "0" (c0), "1" (c1), "2" (c2), "g" (i) : "%rax", "%rdx", "cc");
-#define SQRADD2(i, j) \
-asm( \
- "movq %6,%%rax \n\t" \
- "mulq %7 \n\t" \
- "addq %%rax,%0 \n\t" \
- "adcq %%rdx,%1 \n\t" \
- "adcq $0,%2 \n\t" \
- "addq %%rax,%0 \n\t" \
- "adcq %%rdx,%1 \n\t" \
- "adcq $0,%2 \n\t" \
- :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","cc");
+# define SQRADD2(i, j) \
+ asm ( \
+ "movq %6,%%rax \n\t" \
+ "mulq %7 \n\t" \
+ "addq %%rax,%0 \n\t" \
+ "adcq %%rdx,%1 \n\t" \
+ "adcq $0,%2 \n\t" \
+ "addq %%rax,%0 \n\t" \
+ "adcq %%rdx,%1 \n\t" \
+ "adcq $0,%2 \n\t" \
+ : "=r" (c0), "=r" (c1), "=r" (c2) : "0" (c0), "1" (c1), "2" (c2), "g" (i), "g" (j) : "%rax", "%rdx", "cc");
-#define SQRADDSC(i, j) \
-asm( \
- "movq %6,%%rax \n\t" \
- "mulq %7 \n\t" \
- "movq %%rax,%0 \n\t" \
- "movq %%rdx,%1 \n\t" \
- "xorq %2,%2 \n\t" \
- :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%rax","%rdx","cc");
+# define SQRADDSC(i, j) \
+ asm ( \
+ "movq %6,%%rax \n\t" \
+ "mulq %7 \n\t" \
+ "movq %%rax,%0 \n\t" \
+ "movq %%rdx,%1 \n\t" \
+ "xorq %2,%2 \n\t" \
+ : "=r" (sc0), "=r" (sc1), "=r" (sc2) : "0" (sc0), "1" (sc1), "2" (sc2), "g" (i), "g" (j) : "%rax", "%rdx", "cc");
-#define SQRADDAC(i, j) \
-asm( \
- "movq %6,%%rax \n\t" \
- "mulq %7 \n\t" \
- "addq %%rax,%0 \n\t" \
- "adcq %%rdx,%1 \n\t" \
- "adcq $0,%2 \n\t" \
- :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%rax","%rdx","cc");
+# define SQRADDAC(i, j) \
+ asm ( \
+ "movq %6,%%rax \n\t" \
+ "mulq %7 \n\t" \
+ "addq %%rax,%0 \n\t" \
+ "adcq %%rdx,%1 \n\t" \
+ "adcq $0,%2 \n\t" \
+ : "=r" (sc0), "=r" (sc1), "=r" (sc2) : "0" (sc0), "1" (sc1), "2" (sc2), "g" (i), "g" (j) : "%rax", "%rdx", "cc");
-#define SQRADDDB \
-asm( \
- "addq %6,%0 \n\t" \
- "adcq %7,%1 \n\t" \
- "adcq %8,%2 \n\t" \
- "addq %6,%0 \n\t" \
- "adcq %7,%1 \n\t" \
- "adcq %8,%2 \n\t" \
- :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(sc0), "r"(sc1), "r"(sc2) : "cc");
+# define SQRADDDB \
+ asm ( \
+ "addq %6,%0 \n\t" \
+ "adcq %7,%1 \n\t" \
+ "adcq %8,%2 \n\t" \
+ "addq %6,%0 \n\t" \
+ "adcq %7,%1 \n\t" \
+ "adcq %8,%2 \n\t" \
+ : "=r" (c0), "=r" (c1), "=r" (c2) : "0" (c0), "1" (c1), "2" (c2), "r" (sc0), "r" (sc1), "r" (sc2) : "cc");
/******************************************************************************/
-#elif defined(PSTM_ARM)
+# elif defined(PSTM_ARM)
/* ARM code */
-//#pragma message ("Using 32 bit ARM Assembly Optimizations")
+/* #pragma message ("Using 32 bit ARM Assembly Optimizations") */
-#define COMBA_START
+# define COMBA_START
-#define CLEAR_CARRY \
-c0 = c1 = c2 = 0;
+# define CLEAR_CARRY \
+ c0 = c1 = c2 = 0;
-#define COMBA_STORE(x) \
-x = c0;
+# define COMBA_STORE(x) \
+ x = c0;
-#define COMBA_STORE2(x) \
-x = c1;
+# define COMBA_STORE2(x) \
+ x = c1;
-#define CARRY_FORWARD \
-do { c0 = c1; c1 = c2; c2 = 0; } while (0);
+# define CARRY_FORWARD \
+ do { c0 = c1; c1 = c2; c2 = 0; } while (0);
-#define COMBA_FINI
+# define COMBA_FINI
/* multiplies point i and j, updates carry "c1" and digit c2 */
-#define SQRADD(i, j) \
-asm( \
-" UMULL r0,r1,%6,%6 \n\t" \
-" ADDS %0,%0,r0 \n\t" \
-" ADCS %1,%1,r1 \n\t" \
-" ADC %2,%2,#0 \n\t" \
-:"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i) : "r0", "r1", "cc");
+# define SQRADD(i, j) \
+ asm ( \
+ " UMULL r0,r1,%6,%6 \n\t" \
+ " ADDS %0,%0,r0 \n\t" \
+ " ADCS %1,%1,r1 \n\t" \
+ " ADC %2,%2,#0 \n\t" \
+ : "=r" (c0), "=r" (c1), "=r" (c2) : "0" (c0), "1" (c1), "2" (c2), "r" (i) : "r0", "r1", "cc");
/* for squaring some of the terms are doubled... */
-#define SQRADD2(i, j) \
-asm( \
-" UMULL r0,r1,%6,%7 \n\t" \
-" ADDS %0,%0,r0 \n\t" \
-" ADCS %1,%1,r1 \n\t" \
-" ADC %2,%2,#0 \n\t" \
-" ADDS %0,%0,r0 \n\t" \
-" ADCS %1,%1,r1 \n\t" \
-" ADC %2,%2,#0 \n\t" \
-:"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j) : "r0", "r1", "cc");
+# define SQRADD2(i, j) \
+ asm ( \
+ " UMULL r0,r1,%6,%7 \n\t" \
+ " ADDS %0,%0,r0 \n\t" \
+ " ADCS %1,%1,r1 \n\t" \
+ " ADC %2,%2,#0 \n\t" \
+ " ADDS %0,%0,r0 \n\t" \
+ " ADCS %1,%1,r1 \n\t" \
+ " ADC %2,%2,#0 \n\t" \
+ : "=r" (c0), "=r" (c1), "=r" (c2) : "0" (c0), "1" (c1), "2" (c2), "r" (i), "r" (j) : "r0", "r1", "cc");
-#define SQRADDSC(i, j) \
-asm( \
-" UMULL %0,%1,%6,%7 \n\t" \
-" SUB %2,%2,%2 \n\t" \
-:"=r"(sc0), "=r"(sc1), "=r"(sc2) : "0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j) : "cc");
+# define SQRADDSC(i, j) \
+ asm ( \
+ " UMULL %0,%1,%6,%7 \n\t" \
+ " SUB %2,%2,%2 \n\t" \
+ : "=r" (sc0), "=r" (sc1), "=r" (sc2) : "0" (sc0), "1" (sc1), "2" (sc2), "r" (i), "r" (j) : "cc");
-#define SQRADDAC(i, j) \
-asm( \
-" UMULL r0,r1,%6,%7 \n\t" \
-" ADDS %0,%0,r0 \n\t" \
-" ADCS %1,%1,r1 \n\t" \
-" ADC %2,%2,#0 \n\t" \
-:"=r"(sc0), "=r"(sc1), "=r"(sc2) : "0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j) : "r0", "r1", "cc");
+# define SQRADDAC(i, j) \
+ asm ( \
+ " UMULL r0,r1,%6,%7 \n\t" \
+ " ADDS %0,%0,r0 \n\t" \
+ " ADCS %1,%1,r1 \n\t" \
+ " ADC %2,%2,#0 \n\t" \
+ : "=r" (sc0), "=r" (sc1), "=r" (sc2) : "0" (sc0), "1" (sc1), "2" (sc2), "r" (i), "r" (j) : "r0", "r1", "cc");
-#define SQRADDDB \
-asm( \
-" ADDS %0,%0,%3 \n\t" \
-" ADCS %1,%1,%4 \n\t" \
-" ADC %2,%2,%5 \n\t" \
-" ADDS %0,%0,%3 \n\t" \
-" ADCS %1,%1,%4 \n\t" \
-" ADC %2,%2,%5 \n\t" \
-:"=r"(c0), "=r"(c1), "=r"(c2) : "r"(sc0), "r"(sc1), "r"(sc2), "0"(c0), "1"(c1), "2"(c2) : "cc");
+# define SQRADDDB \
+ asm ( \
+ " ADDS %0,%0,%3 \n\t" \
+ " ADCS %1,%1,%4 \n\t" \
+ " ADC %2,%2,%5 \n\t" \
+ " ADDS %0,%0,%3 \n\t" \
+ " ADCS %1,%1,%4 \n\t" \
+ " ADC %2,%2,%5 \n\t" \
+ : "=r" (c0), "=r" (c1), "=r" (c2) : "r" (sc0), "r" (sc1), "r" (sc2), "0" (c0), "1" (c1), "2" (c2) : "cc");
/******************************************************************************/
-#elif defined(PSTM_MIPS)
+# elif defined(PSTM_MIPS)
/* MIPS32 */
-//#pragma message ("Using 32 bit MIPS Assembly Optimizations")
+/* #pragma message ("Using 32 bit MIPS Assembly Optimizations") */
-#define COMBA_START
+# define COMBA_START
-#define CLEAR_CARRY \
-c0 = c1 = c2 = 0;
+# define CLEAR_CARRY \
+ c0 = c1 = c2 = 0;
-#define COMBA_STORE(x) \
-x = c0;
+# define COMBA_STORE(x) \
+ x = c0;
-#define COMBA_STORE2(x) \
-x = c1;
+# define COMBA_STORE2(x) \
+ x = c1;
-#define CARRY_FORWARD \
-do { c0 = c1; c1 = c2; c2 = 0; } while (0);
+# define CARRY_FORWARD \
+ do { c0 = c1; c1 = c2; c2 = 0; } while (0);
-#define COMBA_FINI
+# define COMBA_FINI
/* multiplies point i and j, updates carry "c1" and digit c2 */
-#define SQRADD(i, j) \
-asm( \
- " multu %6,%6 \n\t" \
- " mflo $12 \n\t" \
- " mfhi $13 \n\t" \
- " addu %0,%0,$12 \n\t" \
- " sltu $12,%0,$12 \n\t" \
- " addu %1,%1,$13 \n\t" \
- " sltu $13,%1,$13 \n\t" \
- " addu %1,%1,$12 \n\t" \
- " sltu $12,%1,$12 \n\t" \
- " addu %2,%2,$13 \n\t" \
- " addu %2,%2,$12 \n\t" \
- :"=r"(c0), "=r"(c1), "=r"(c2):"0"(c0), "1"(c1), "2"(c2), "r"(i):"$12","$13");
+# define SQRADD(i, j) \
+ asm ( \
+ " multu %6,%6 \n\t" \
+ " mflo $12 \n\t" \
+ " mfhi $13 \n\t" \
+ " addu %0,%0,$12 \n\t" \
+ " sltu $12,%0,$12 \n\t" \
+ " addu %1,%1,$13 \n\t" \
+ " sltu $13,%1,$13 \n\t" \
+ " addu %1,%1,$12 \n\t" \
+ " sltu $12,%1,$12 \n\t" \
+ " addu %2,%2,$13 \n\t" \
+ " addu %2,%2,$12 \n\t" \
+ : "=r" (c0), "=r" (c1), "=r" (c2) : "0" (c0), "1" (c1), "2" (c2), "r" (i) : "$12", "$13");
/* for squaring some of the terms are doubled... */
-#define SQRADD2(i, j) \
-asm( \
- " multu %6,%7 \n\t" \
- " mflo $12 \n\t" \
- " mfhi $13 \n\t" \
- \
- " addu %0,%0,$12 \n\t" \
- " sltu $14,%0,$12 \n\t" \
- " addu %1,%1,$13 \n\t" \
- " sltu $15,%1,$13 \n\t" \
- " addu %1,%1,$14 \n\t" \
- " sltu $14,%1,$14 \n\t" \
- " addu %2,%2,$15 \n\t" \
- " addu %2,%2,$14 \n\t" \
- \
- " addu %0,%0,$12 \n\t" \
- " sltu $14,%0,$12 \n\t" \
- " addu %1,%1,$13 \n\t" \
- " sltu $15,%1,$13 \n\t" \
- " addu %1,%1,$14 \n\t" \
- " sltu $14,%1,$14 \n\t" \
- " addu %2,%2,$15 \n\t" \
- " addu %2,%2,$14 \n\t" \
- :"=r"(c0), "=r"(c1), "=r"(c2):"0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j):"$12", "$13", "$14", "$15");
+# define SQRADD2(i, j) \
+ asm ( \
+ " multu %6,%7 \n\t" \
+ " mflo $12 \n\t" \
+ " mfhi $13 \n\t" \
+ \
+ " addu %0,%0,$12 \n\t" \
+ " sltu $14,%0,$12 \n\t" \
+ " addu %1,%1,$13 \n\t" \
+ " sltu $15,%1,$13 \n\t" \
+ " addu %1,%1,$14 \n\t" \
+ " sltu $14,%1,$14 \n\t" \
+ " addu %2,%2,$15 \n\t" \
+ " addu %2,%2,$14 \n\t" \
+ \
+ " addu %0,%0,$12 \n\t" \
+ " sltu $14,%0,$12 \n\t" \
+ " addu %1,%1,$13 \n\t" \
+ " sltu $15,%1,$13 \n\t" \
+ " addu %1,%1,$14 \n\t" \
+ " sltu $14,%1,$14 \n\t" \
+ " addu %2,%2,$15 \n\t" \
+ " addu %2,%2,$14 \n\t" \
+ : "=r" (c0), "=r" (c1), "=r" (c2) : "0" (c0), "1" (c1), "2" (c2), "r" (i), "r" (j) : "$12", "$13", "$14", "$15");
-#define SQRADDSC(i, j) \
-asm( \
- " multu %6,%7 \n\t" \
- " mflo %0 \n\t" \
- " mfhi %1 \n\t" \
- " xor %2,%2,%2 \n\t" \
- :"=r"(sc0), "=r"(sc1), "=r"(sc2):"0"(sc0), "1"(sc1), "2"(sc2), "r"(i),"r"(j) : "cc");
+# define SQRADDSC(i, j) \
+ asm ( \
+ " multu %6,%7 \n\t" \
+ " mflo %0 \n\t" \
+ " mfhi %1 \n\t" \
+ " xor %2,%2,%2 \n\t" \
+ : "=r" (sc0), "=r" (sc1), "=r" (sc2) : "0" (sc0), "1" (sc1), "2" (sc2), "r" (i), "r" (j) : "cc");
-#define SQRADDAC(i, j) \
-asm( \
- " multu %6,%7 \n\t" \
- " mflo $12 \n\t" \
- " mfhi $13 \n\t" \
- " addu %0,%0,$12 \n\t" \
- " sltu $12,%0,$12 \n\t" \
- " addu %1,%1,$13 \n\t" \
- " sltu $13,%1,$13 \n\t" \
- " addu %1,%1,$12 \n\t" \
- " sltu $12,%1,$12 \n\t" \
- " addu %2,%2,$13 \n\t" \
- " addu %2,%2,$12 \n\t" \
- :"=r"(sc0), "=r"(sc1), "=r"(sc2):"0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j):"$12", "$13", "$14");
+# define SQRADDAC(i, j) \
+ asm ( \
+ " multu %6,%7 \n\t" \
+ " mflo $12 \n\t" \
+ " mfhi $13 \n\t" \
+ " addu %0,%0,$12 \n\t" \
+ " sltu $12,%0,$12 \n\t" \
+ " addu %1,%1,$13 \n\t" \
+ " sltu $13,%1,$13 \n\t" \
+ " addu %1,%1,$12 \n\t" \
+ " sltu $12,%1,$12 \n\t" \
+ " addu %2,%2,$13 \n\t" \
+ " addu %2,%2,$12 \n\t" \
+ : "=r" (sc0), "=r" (sc1), "=r" (sc2) : "0" (sc0), "1" (sc1), "2" (sc2), "r" (i), "r" (j) : "$12", "$13", "$14");
-#define SQRADDDB \
-asm( \
- " addu %0,%0,%3 \n\t" \
- " sltu $10,%0,%3 \n\t" \
- " addu %1,%1,$10 \n\t" \
- " sltu $10,%1,$10 \n\t" \
- " addu %1,%1,%4 \n\t" \
- " sltu $11,%1,%4 \n\t" \
- " addu %2,%2,$10 \n\t" \
- " addu %2,%2,$11 \n\t" \
- " addu %2,%2,%5 \n\t" \
- \
- " addu %0,%0,%3 \n\t" \
- " sltu $10,%0,%3 \n\t" \
- " addu %1,%1,$10 \n\t" \
- " sltu $10,%1,$10 \n\t" \
- " addu %1,%1,%4 \n\t" \
- " sltu $11,%1,%4 \n\t" \
- " addu %2,%2,$10 \n\t" \
- " addu %2,%2,$11 \n\t" \
- " addu %2,%2,%5 \n\t" \
- :"=r"(c0), "=r"(c1), "=r"(c2) : "r"(sc0), "r"(sc1), "r"(sc2), "0"(c0), "1"(c1), "2"(c2) : "$10", "$11");
+# define SQRADDDB \
+ asm ( \
+ " addu %0,%0,%3 \n\t" \
+ " sltu $10,%0,%3 \n\t" \
+ " addu %1,%1,$10 \n\t" \
+ " sltu $10,%1,$10 \n\t" \
+ " addu %1,%1,%4 \n\t" \
+ " sltu $11,%1,%4 \n\t" \
+ " addu %2,%2,$10 \n\t" \
+ " addu %2,%2,$11 \n\t" \
+ " addu %2,%2,%5 \n\t" \
+ \
+ " addu %0,%0,%3 \n\t" \
+ " sltu $10,%0,%3 \n\t" \
+ " addu %1,%1,$10 \n\t" \
+ " sltu $10,%1,$10 \n\t" \
+ " addu %1,%1,%4 \n\t" \
+ " sltu $11,%1,%4 \n\t" \
+ " addu %2,%2,$10 \n\t" \
+ " addu %2,%2,$11 \n\t" \
+ " addu %2,%2,%5 \n\t" \
+ : "=r" (c0), "=r" (c1), "=r" (c2) : "r" (sc0), "r" (sc1), "r" (sc2), "0" (c0), "1" (c1), "2" (c2) : "$10", "$11");
-#else
+# else
/******************************************************************************/
-#define PSTM_ISO
+# define PSTM_ISO
/* ISO C portable code */
-#define COMBA_START
+# define COMBA_START
-#define CLEAR_CARRY \
- c0 = c1 = c2 = 0;
+# define CLEAR_CARRY \
+ c0 = c1 = c2 = 0;
-#define COMBA_STORE(x) \
- x = c0;
+# define COMBA_STORE(x) \
+ x = c0;
-#define COMBA_STORE2(x) \
- x = c1;
+# define COMBA_STORE2(x) \
+ x = c1;
-#define CARRY_FORWARD \
- do { c0 = c1; c1 = c2; c2 = 0; } while (0);
+# define CARRY_FORWARD \
+ do { c0 = c1; c1 = c2; c2 = 0; } while (0);
-#define COMBA_FINI
+# define COMBA_FINI
/* multiplies point i and j, updates carry "c1" and digit c2 */
-#define SQRADD(i, j) \
- do { pstm_word t; \
- t = c0 + ((pstm_word)i) * ((pstm_word)j); c0 = (pstm_digit)t; \
- t = c1 + (t >> DIGIT_BIT); \
- c1 = (pstm_digit)t; c2 += (pstm_digit)(t >> DIGIT_BIT); \
- } while (0);
+# define SQRADD(i, j) \
+ do { pstm_word t; \
+ t = c0 + ((pstm_word) i) * ((pstm_word) j); c0 = (pstm_digit) t; \
+ t = c1 + (t >> DIGIT_BIT); \
+ c1 = (pstm_digit) t; c2 += (pstm_digit) (t >> DIGIT_BIT); \
+ } while (0);
/* for squaring some of the terms are doubled... */
-#define SQRADD2(i, j) \
- do { pstm_word t; \
- t = ((pstm_word)i) * ((pstm_word)j); \
- tt = (pstm_word)c0 + t; c0 = (pstm_digit)tt; \
- tt = (pstm_word)c1 + (tt >> DIGIT_BIT); \
- c1 = (pstm_digit)tt; c2 += (pstm_digit)(tt >> DIGIT_BIT); \
- tt = (pstm_word)c0 + t; c0 = (pstm_digit)tt; \
- tt = (pstm_word)c1 + (tt >> DIGIT_BIT); \
- c1 = (pstm_digit)tt; c2 += (pstm_digit)(tt >> DIGIT_BIT); \
- } while (0);
+# define SQRADD2(i, j) \
+ do { pstm_word t; \
+ t = ((pstm_word) i) * ((pstm_word) j); \
+ tt = (pstm_word) c0 + t; c0 = (pstm_digit) tt; \
+ tt = (pstm_word) c1 + (tt >> DIGIT_BIT); \
+ c1 = (pstm_digit) tt; c2 += (pstm_digit) (tt >> DIGIT_BIT); \
+ tt = (pstm_word) c0 + t; c0 = (pstm_digit) tt; \
+ tt = (pstm_word) c1 + (tt >> DIGIT_BIT); \
+ c1 = (pstm_digit) tt; c2 += (pstm_digit) (tt >> DIGIT_BIT); \
+ } while (0);
-#define SQRADDSC(i, j) \
- do { pstm_word t; \
- t = ((pstm_word)i) * ((pstm_word)j); \
- sc0 = (pstm_digit)t; sc1 = (pstm_digit)(t >> DIGIT_BIT); sc2 = 0; \
- } while (0);
+# define SQRADDSC(i, j) \
+ do { pstm_word t; \
+ t = ((pstm_word) i) * ((pstm_word) j); \
+ sc0 = (pstm_digit) t; sc1 = (pstm_digit) (t >> DIGIT_BIT); sc2 = 0; \
+ } while (0);
-#define SQRADDAC(i, j) \
- do { pstm_word t; \
- t = ((pstm_word)sc0) + ((pstm_word)i) * ((pstm_word)j); \
- sc0 = (pstm_digit)t; \
- t = ((pstm_word)sc1) + (t >> DIGIT_BIT); sc1 = (pstm_digit)t; \
- sc2 += (pstm_digit)(t >> DIGIT_BIT); \
- } while (0);
+# define SQRADDAC(i, j) \
+ do { pstm_word t; \
+ t = ((pstm_word) sc0) + ((pstm_word) i) * ((pstm_word) j); \
+ sc0 = (pstm_digit) t; \
+ t = ((pstm_word) sc1) + (t >> DIGIT_BIT); sc1 = (pstm_digit) t; \
+ sc2 += (pstm_digit) (t >> DIGIT_BIT); \
+ } while (0);
-#define SQRADDDB \
- do { pstm_word t; \
- t = ((pstm_word)sc0) + ((pstm_word)sc0) + ((pstm_word)c0); \
- c0 = (pstm_digit)t; \
- t = ((pstm_word)sc1) + ((pstm_word)sc1) + c1 + (t >> DIGIT_BIT); \
- c1 = (pstm_digit)t; \
- c2 = c2 + sc2 + sc2 + (pstm_digit)(t >> DIGIT_BIT); \
- } while (0);
+# define SQRADDDB \
+ do { pstm_word t; \
+ t = ((pstm_word) sc0) + ((pstm_word) sc0) + ((pstm_word) c0); \
+ c0 = (pstm_digit) t; \
+ t = ((pstm_word) sc1) + ((pstm_word) sc1) + c1 + (t >> DIGIT_BIT); \
+ c1 = (pstm_digit) t; \
+ c2 = c2 + sc2 + sc2 + (pstm_digit) (t >> DIGIT_BIT); \
+ } while (0);
-#endif /* ISO_C */
+# endif /* ISO_C */
/******************************************************************************/
/*
- Non-unrolled comba squarer
+ Non-unrolled comba squarer
*/
static int32_t pstm_sqr_comba_gen(psPool_t *pool, const pstm_int *A,
- pstm_int *B, pstm_digit *paD, uint16_t paDlen)
+ pstm_int *B, pstm_digit *paD, psSize_t paDlen)
{
- int16 paDfail, pa;
- int32 ix, iz;
- pstm_digit c0, c1, c2, *dst;
-#ifdef PSTM_ISO
- pstm_word tt;
-#endif
+ int16 paDfail, pa;
+ int32 ix, iz;
+ pstm_digit c0, c1, c2, *dst;
- paDfail = 0;
- /* get size of output and trim */
- pa = A->used + A->used;
+# ifdef PSTM_ISO
+ pstm_word tt;
+# endif
- /* number of output digits to produce */
- COMBA_START;
- CLEAR_CARRY;
+ paDfail = 0;
+ /* get size of output and trim */
+ pa = A->used + A->used;
+
+ /* number of output digits to produce */
+ COMBA_START;
+ CLEAR_CARRY;
/*
- If b is not large enough grow it and continue
-*/
- if (B->alloc < pa) {
- if (pstm_grow(B, pa) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- }
- if (paD != NULL) {
- if (paDlen < (sizeof(pstm_digit) * pa)) {
- paDfail = 1; /* have a paD, but it's not big enough */
- if ((dst = psMalloc(pool, sizeof(pstm_digit) * pa)) == NULL) {
- return PS_MEM_FAIL;
- }
- memset(dst, 0x0, sizeof(pstm_digit) * pa);
- } else {
- dst = paD;
- memset(dst, 0x0, paDlen);
- }
- } else {
- if ((dst = psMalloc(pool, sizeof(pstm_digit) * pa)) == NULL) {
- return PS_MEM_FAIL;
- }
- memset(dst, 0x0, sizeof(pstm_digit) * pa);
- }
-
- for (ix = 0; ix < pa; ix++) {
- int32 tx, ty, iy;
- pstm_digit *tmpy, *tmpx;
-
- /* get offsets into the two bignums */
- ty = min(A->used-1, ix);
- tx = ix - ty;
-
- /* setup temp aliases */
- tmpx = A->dp + tx;
- tmpy = A->dp + ty;
-/*
- This is the number of times the loop will iterate
- while (tx++ < a->used && ty-- >= 0) { ... }
-*/
- iy = min(A->used-tx, ty+1);
-/*
- now for squaring, tx can never equal ty. We halve the distance since
- they approach at a rate of 2x and we have to round because odd cases
- need to be executed
-*/
- iy = min(iy, (ty-tx+1)>>1);
-
- /* forward carries */
- CARRY_FORWARD;
-
- /* execute loop */
- for (iz = 0; iz < iy; iz++) {
- SQRADD2(*tmpx++, *tmpy--);
- }
-
- /* even columns have the square term in them */
- if ((ix&1) == 0) {
- SQRADD(A->dp[ix>>1], A->dp[ix>>1]);
- }
-
- /* store it */
- COMBA_STORE(dst[ix]);
- }
-
- COMBA_FINI;
-/*
- setup dest
+ If b is not large enough grow it and continue
*/
- iz = B->used;
- B->used = pa;
- {
- pstm_digit *tmpc;
- tmpc = B->dp;
- for (ix = 0; ix < pa; ix++) {
- *tmpc++ = dst[ix];
- }
- /* clear unused digits (that existed in the old copy of c) */
- for (; ix < iz; ix++) {
- *tmpc++ = 0;
- }
- }
- pstm_clamp(B);
+ if (B->alloc < pa)
+ {
+ if (pstm_grow(B, pa) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ }
+ if (paD != NULL)
+ {
+ if (paDlen < (sizeof(pstm_digit) * pa))
+ {
+ paDfail = 1; /* have a paD, but it's not big enough */
+ if ((dst = psMalloc(pool, sizeof(pstm_digit) * pa)) == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ memset(dst, 0x0, sizeof(pstm_digit) * pa);
+ }
+ else
+ {
+ dst = paD;
+ memset(dst, 0x0, paDlen);
+ }
+ }
+ else
+ {
+ if ((dst = psMalloc(pool, sizeof(pstm_digit) * pa)) == NULL)
+ {
+ return PS_MEM_FAIL;
+ }
+ memset(dst, 0x0, sizeof(pstm_digit) * pa);
+ }
- if ((paD == NULL) || paDfail == 1) {
- psFree(dst, pool);
- }
- return PS_SUCCESS;
+ for (ix = 0; ix < pa; ix++)
+ {
+ int32 tx, ty, iy;
+ pstm_digit *tmpy, *tmpx;
+
+ /* get offsets into the two bignums */
+ ty = min(A->used - 1, ix);
+ tx = ix - ty;
+
+ /* setup temp aliases */
+ tmpx = A->dp + tx;
+ tmpy = A->dp + ty;
+/*
+ This is the number of times the loop will iterate
+ while (tx++ < a->used && ty-- >= 0) { ... }
+ */
+ iy = min(A->used - tx, ty + 1);
+/*
+ now for squaring, tx can never equal ty. We halve the distance since
+ they approach at a rate of 2x and we have to round because odd cases
+ need to be executed
+ */
+ iy = min(iy, (ty - tx + 1) >> 1);
+
+ /* forward carries */
+ CARRY_FORWARD;
+
+ /* execute loop */
+ for (iz = 0; iz < iy; iz++)
+ {
+ SQRADD2(*tmpx++, *tmpy--);
+ }
+
+ /* even columns have the square term in them */
+ if ((ix & 1) == 0)
+ {
+ SQRADD(A->dp[ix >> 1], A->dp[ix >> 1]);
+ }
+
+ /* store it */
+ COMBA_STORE(dst[ix]);
+ }
+
+ COMBA_FINI;
+/*
+ setup dest
+ */
+ iz = B->used;
+ B->used = pa;
+ {
+ pstm_digit *tmpc;
+ tmpc = B->dp;
+ for (ix = 0; ix < pa; ix++)
+ {
+ *tmpc++ = dst[ix];
+ }
+ /* clear unused digits (that existed in the old copy of c) */
+ for (; ix < iz; ix++)
+ {
+ *tmpc++ = 0;
+ }
+ }
+ pstm_clamp(B);
+
+ if ((paD == NULL) || paDfail == 1)
+ {
+ psFree(dst, pool);
+ }
+ return PS_SUCCESS;
}
/******************************************************************************/
/*
- Unrolled Comba loop for 1024 bit keys
+ Unrolled Comba loop for 1024 bit keys
*/
-#ifdef USE_1024_KEY_SPEED_OPTIMIZATIONS
+# ifdef USE_1024_KEY_SPEED_OPTIMIZATIONS
static int32_t pstm_sqr_comba16(const pstm_int *A, pstm_int *B)
{
- pstm_digit *a, b[32], c0, c1, c2, sc0, sc1, sc2;
-#ifdef PSTM_ISO
- pstm_word tt;
-#endif
+ pstm_digit *a, b[32], c0, c1, c2, sc0, sc1, sc2;
- if (B->alloc < 32) {
- if (pstm_grow(B, 32) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- }
- a = A->dp;
- sc0 = sc1 = sc2 = 0;
+# ifdef PSTM_ISO
+ pstm_word tt;
+# endif
- COMBA_START;
+ if (B->alloc < 32)
+ {
+ if (pstm_grow(B, 32) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ }
+ a = A->dp;
+ sc0 = sc1 = sc2 = 0;
- /* clear carries */
- CLEAR_CARRY;
+ COMBA_START;
- /* output 0 */
- SQRADD(a[0],a[0]);
- COMBA_STORE(b[0]);
+ /* clear carries */
+ CLEAR_CARRY;
- /* output 1 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[1]);
- COMBA_STORE(b[1]);
+ /* output 0 */
+ SQRADD(a[0], a[0]);
+ COMBA_STORE(b[0]);
- /* output 2 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
- COMBA_STORE(b[2]);
+ /* output 1 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[1]);
+ COMBA_STORE(b[1]);
- /* output 3 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
- COMBA_STORE(b[3]);
+ /* output 2 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
+ COMBA_STORE(b[2]);
- /* output 4 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
- COMBA_STORE(b[4]);
+ /* output 3 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
+ COMBA_STORE(b[3]);
- /* output 5 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB;
- COMBA_STORE(b[5]);
+ /* output 4 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
+ COMBA_STORE(b[4]);
- /* output 6 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]);
- COMBA_STORE(b[6]);
+ /* output 5 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB;
+ COMBA_STORE(b[5]);
- /* output 7 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB;
- COMBA_STORE(b[7]);
+ /* output 6 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]);
+ COMBA_STORE(b[6]);
- /* output 8 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]);
- COMBA_STORE(b[8]);
+ /* output 7 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB;
+ COMBA_STORE(b[7]);
- /* output 9 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB;
- COMBA_STORE(b[9]);
+ /* output 8 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]);
+ COMBA_STORE(b[8]);
- /* output 10 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]);
- COMBA_STORE(b[10]);
+ /* output 9 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB;
+ COMBA_STORE(b[9]);
- /* output 11 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB;
- COMBA_STORE(b[11]);
+ /* output 10 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]);
+ COMBA_STORE(b[10]);
- /* output 12 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]);
- COMBA_STORE(b[12]);
+ /* output 11 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB;
+ COMBA_STORE(b[11]);
- /* output 13 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB;
- COMBA_STORE(b[13]);
+ /* output 12 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]);
+ COMBA_STORE(b[12]);
- /* output 14 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]);
- COMBA_STORE(b[14]);
+ /* output 13 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB;
+ COMBA_STORE(b[13]);
- /* output 15 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB;
- COMBA_STORE(b[15]);
+ /* output 14 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]);
+ COMBA_STORE(b[14]);
- /* output 16 */
- CARRY_FORWARD;
- SQRADDSC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]);
- COMBA_STORE(b[16]);
+ /* output 15 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB;
+ COMBA_STORE(b[15]);
- /* output 17 */
- CARRY_FORWARD;
- SQRADDSC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB;
- COMBA_STORE(b[17]);
+ /* output 16 */
+ CARRY_FORWARD;
+ SQRADDSC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]);
+ COMBA_STORE(b[16]);
- /* output 18 */
- CARRY_FORWARD;
- SQRADDSC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]);
- COMBA_STORE(b[18]);
+ /* output 17 */
+ CARRY_FORWARD;
+ SQRADDSC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB;
+ COMBA_STORE(b[17]);
- /* output 19 */
- CARRY_FORWARD;
- SQRADDSC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB;
- COMBA_STORE(b[19]);
+ /* output 18 */
+ CARRY_FORWARD;
+ SQRADDSC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]);
+ COMBA_STORE(b[18]);
- /* output 20 */
- CARRY_FORWARD;
- SQRADDSC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]);
- COMBA_STORE(b[20]);
+ /* output 19 */
+ CARRY_FORWARD;
+ SQRADDSC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB;
+ COMBA_STORE(b[19]);
- /* output 21 */
- CARRY_FORWARD;
- SQRADDSC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB;
- COMBA_STORE(b[21]);
+ /* output 20 */
+ CARRY_FORWARD;
+ SQRADDSC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]);
+ COMBA_STORE(b[20]);
- /* output 22 */
- CARRY_FORWARD;
- SQRADDSC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]);
- COMBA_STORE(b[22]);
+ /* output 21 */
+ CARRY_FORWARD;
+ SQRADDSC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB;
+ COMBA_STORE(b[21]);
- /* output 23 */
- CARRY_FORWARD;
- SQRADDSC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB;
- COMBA_STORE(b[23]);
+ /* output 22 */
+ CARRY_FORWARD;
+ SQRADDSC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]);
+ COMBA_STORE(b[22]);
- /* output 24 */
- CARRY_FORWARD;
- SQRADDSC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]);
- COMBA_STORE(b[24]);
+ /* output 23 */
+ CARRY_FORWARD;
+ SQRADDSC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB;
+ COMBA_STORE(b[23]);
- /* output 25 */
- CARRY_FORWARD;
- SQRADDSC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB;
- COMBA_STORE(b[25]);
+ /* output 24 */
+ CARRY_FORWARD;
+ SQRADDSC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]);
+ COMBA_STORE(b[24]);
- /* output 26 */
- CARRY_FORWARD;
- SQRADD2(a[11], a[15]); SQRADD2(a[12], a[14]); SQRADD(a[13], a[13]);
- COMBA_STORE(b[26]);
+ /* output 25 */
+ CARRY_FORWARD;
+ SQRADDSC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB;
+ COMBA_STORE(b[25]);
- /* output 27 */
- CARRY_FORWARD;
- SQRADD2(a[12], a[15]); SQRADD2(a[13], a[14]);
- COMBA_STORE(b[27]);
+ /* output 26 */
+ CARRY_FORWARD;
+ SQRADD2(a[11], a[15]); SQRADD2(a[12], a[14]); SQRADD(a[13], a[13]);
+ COMBA_STORE(b[26]);
- /* output 28 */
- CARRY_FORWARD;
- SQRADD2(a[13], a[15]); SQRADD(a[14], a[14]);
- COMBA_STORE(b[28]);
+ /* output 27 */
+ CARRY_FORWARD;
+ SQRADD2(a[12], a[15]); SQRADD2(a[13], a[14]);
+ COMBA_STORE(b[27]);
- /* output 29 */
- CARRY_FORWARD;
- SQRADD2(a[14], a[15]);
- COMBA_STORE(b[29]);
+ /* output 28 */
+ CARRY_FORWARD;
+ SQRADD2(a[13], a[15]); SQRADD(a[14], a[14]);
+ COMBA_STORE(b[28]);
- /* output 30 */
- CARRY_FORWARD;
- SQRADD(a[15], a[15]);
- COMBA_STORE(b[30]);
- COMBA_STORE2(b[31]);
- COMBA_FINI;
+ /* output 29 */
+ CARRY_FORWARD;
+ SQRADD2(a[14], a[15]);
+ COMBA_STORE(b[29]);
- B->used = 32;
- B->sign = PSTM_ZPOS;
- memcpy(B->dp, b, 32 * sizeof(pstm_digit));
- pstm_clamp(B);
- return PSTM_OKAY;
+ /* output 30 */
+ CARRY_FORWARD;
+ SQRADD(a[15], a[15]);
+ COMBA_STORE(b[30]);
+ COMBA_STORE2(b[31]);
+ COMBA_FINI;
+
+ B->used = 32;
+ B->sign = PSTM_ZPOS;
+ memcpy(B->dp, b, 32 * sizeof(pstm_digit));
+ pstm_clamp(B);
+ return PSTM_OKAY;
}
-#endif /* USE_1024_KEY_SPEED_OPTIMIZATIONS */
+# endif /* USE_1024_KEY_SPEED_OPTIMIZATIONS */
-#ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS
+# ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS
static int32_t pstm_sqr_comba32(const pstm_int *A, pstm_int *B)
{
- pstm_digit *a, b[64], c0, c1, c2, sc0, sc1, sc2;
-#ifdef PSTM_ISO
- pstm_word tt;
-#endif
-
- if (B->alloc < 64) {
- if (pstm_grow(B, 64) != PSTM_OKAY) {
- return PS_MEM_FAIL;
- }
- }
- sc0 = sc1 = sc2 = 0;
- a = A->dp;
- COMBA_START;
-
- /* clear carries */
- CLEAR_CARRY;
-
- /* output 0 */
- SQRADD(a[0],a[0]);
- COMBA_STORE(b[0]);
-
- /* output 1 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[1]);
- COMBA_STORE(b[1]);
-
- /* output 2 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
- COMBA_STORE(b[2]);
-
- /* output 3 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
- COMBA_STORE(b[3]);
-
- /* output 4 */
- CARRY_FORWARD;
- SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
- COMBA_STORE(b[4]);
-
- /* output 5 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB;
- COMBA_STORE(b[5]);
-
- /* output 6 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]);
- COMBA_STORE(b[6]);
-
- /* output 7 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB;
- COMBA_STORE(b[7]);
-
- /* output 8 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]);
- COMBA_STORE(b[8]);
-
- /* output 9 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB;
- COMBA_STORE(b[9]);
-
- /* output 10 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]);
- COMBA_STORE(b[10]);
-
- /* output 11 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB;
- COMBA_STORE(b[11]);
-
- /* output 12 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]);
- COMBA_STORE(b[12]);
-
- /* output 13 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB;
- COMBA_STORE(b[13]);
-
- /* output 14 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]);
- COMBA_STORE(b[14]);
-
- /* output 15 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB;
- COMBA_STORE(b[15]);
-
- /* output 16 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[16]); SQRADDAC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]);
- COMBA_STORE(b[16]);
-
- /* output 17 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[17]); SQRADDAC(a[1], a[16]); SQRADDAC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB;
- COMBA_STORE(b[17]);
-
- /* output 18 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[18]); SQRADDAC(a[1], a[17]); SQRADDAC(a[2], a[16]); SQRADDAC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]);
- COMBA_STORE(b[18]);
-
- /* output 19 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[19]); SQRADDAC(a[1], a[18]); SQRADDAC(a[2], a[17]); SQRADDAC(a[3], a[16]); SQRADDAC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB;
- COMBA_STORE(b[19]);
-
- /* output 20 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[20]); SQRADDAC(a[1], a[19]); SQRADDAC(a[2], a[18]); SQRADDAC(a[3], a[17]); SQRADDAC(a[4], a[16]); SQRADDAC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]);
- COMBA_STORE(b[20]);
-
- /* output 21 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[21]); SQRADDAC(a[1], a[20]); SQRADDAC(a[2], a[19]); SQRADDAC(a[3], a[18]); SQRADDAC(a[4], a[17]); SQRADDAC(a[5], a[16]); SQRADDAC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB;
- COMBA_STORE(b[21]);
-
- /* output 22 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[22]); SQRADDAC(a[1], a[21]); SQRADDAC(a[2], a[20]); SQRADDAC(a[3], a[19]); SQRADDAC(a[4], a[18]); SQRADDAC(a[5], a[17]); SQRADDAC(a[6], a[16]); SQRADDAC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]);
- COMBA_STORE(b[22]);
-
- /* output 23 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[23]); SQRADDAC(a[1], a[22]); SQRADDAC(a[2], a[21]); SQRADDAC(a[3], a[20]); SQRADDAC(a[4], a[19]); SQRADDAC(a[5], a[18]); SQRADDAC(a[6], a[17]); SQRADDAC(a[7], a[16]); SQRADDAC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB;
- COMBA_STORE(b[23]);
-
- /* output 24 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[24]); SQRADDAC(a[1], a[23]); SQRADDAC(a[2], a[22]); SQRADDAC(a[3], a[21]); SQRADDAC(a[4], a[20]); SQRADDAC(a[5], a[19]); SQRADDAC(a[6], a[18]); SQRADDAC(a[7], a[17]); SQRADDAC(a[8], a[16]); SQRADDAC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]);
- COMBA_STORE(b[24]);
-
- /* output 25 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[25]); SQRADDAC(a[1], a[24]); SQRADDAC(a[2], a[23]); SQRADDAC(a[3], a[22]); SQRADDAC(a[4], a[21]); SQRADDAC(a[5], a[20]); SQRADDAC(a[6], a[19]); SQRADDAC(a[7], a[18]); SQRADDAC(a[8], a[17]); SQRADDAC(a[9], a[16]); SQRADDAC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB;
- COMBA_STORE(b[25]);
-
- /* output 26 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[26]); SQRADDAC(a[1], a[25]); SQRADDAC(a[2], a[24]); SQRADDAC(a[3], a[23]); SQRADDAC(a[4], a[22]); SQRADDAC(a[5], a[21]); SQRADDAC(a[6], a[20]); SQRADDAC(a[7], a[19]); SQRADDAC(a[8], a[18]); SQRADDAC(a[9], a[17]); SQRADDAC(a[10], a[16]); SQRADDAC(a[11], a[15]); SQRADDAC(a[12], a[14]); SQRADDDB; SQRADD(a[13], a[13]);
- COMBA_STORE(b[26]);
-
- /* output 27 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[27]); SQRADDAC(a[1], a[26]); SQRADDAC(a[2], a[25]); SQRADDAC(a[3], a[24]); SQRADDAC(a[4], a[23]); SQRADDAC(a[5], a[22]); SQRADDAC(a[6], a[21]); SQRADDAC(a[7], a[20]); SQRADDAC(a[8], a[19]); SQRADDAC(a[9], a[18]); SQRADDAC(a[10], a[17]); SQRADDAC(a[11], a[16]); SQRADDAC(a[12], a[15]); SQRADDAC(a[13], a[14]); SQRADDDB;
- COMBA_STORE(b[27]);
-
- /* output 28 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[28]); SQRADDAC(a[1], a[27]); SQRADDAC(a[2], a[26]); SQRADDAC(a[3], a[25]); SQRADDAC(a[4], a[24]); SQRADDAC(a[5], a[23]); SQRADDAC(a[6], a[22]); SQRADDAC(a[7], a[21]); SQRADDAC(a[8], a[20]); SQRADDAC(a[9], a[19]); SQRADDAC(a[10], a[18]); SQRADDAC(a[11], a[17]); SQRADDAC(a[12], a[16]); SQRADDAC(a[13], a[15]); SQRADDDB; SQRADD(a[14], a[14]);
- COMBA_STORE(b[28]);
-
- /* output 29 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[29]); SQRADDAC(a[1], a[28]); SQRADDAC(a[2], a[27]); SQRADDAC(a[3], a[26]); SQRADDAC(a[4], a[25]); SQRADDAC(a[5], a[24]); SQRADDAC(a[6], a[23]); SQRADDAC(a[7], a[22]); SQRADDAC(a[8], a[21]); SQRADDAC(a[9], a[20]); SQRADDAC(a[10], a[19]); SQRADDAC(a[11], a[18]); SQRADDAC(a[12], a[17]); SQRADDAC(a[13], a[16]); SQRADDAC(a[14], a[15]); SQRADDDB;
- COMBA_STORE(b[29]);
-
- /* output 30 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[30]); SQRADDAC(a[1], a[29]); SQRADDAC(a[2], a[28]); SQRADDAC(a[3], a[27]); SQRADDAC(a[4], a[26]); SQRADDAC(a[5], a[25]); SQRADDAC(a[6], a[24]); SQRADDAC(a[7], a[23]); SQRADDAC(a[8], a[22]); SQRADDAC(a[9], a[21]); SQRADDAC(a[10], a[20]); SQRADDAC(a[11], a[19]); SQRADDAC(a[12], a[18]); SQRADDAC(a[13], a[17]); SQRADDAC(a[14], a[16]); SQRADDDB; SQRADD(a[15], a[15]);
- COMBA_STORE(b[30]);
-
- /* output 31 */
- CARRY_FORWARD;
- SQRADDSC(a[0], a[31]); SQRADDAC(a[1], a[30]); SQRADDAC(a[2], a[29]); SQRADDAC(a[3], a[28]); SQRADDAC(a[4], a[27]); SQRADDAC(a[5], a[26]); SQRADDAC(a[6], a[25]); SQRADDAC(a[7], a[24]); SQRADDAC(a[8], a[23]); SQRADDAC(a[9], a[22]); SQRADDAC(a[10], a[21]); SQRADDAC(a[11], a[20]); SQRADDAC(a[12], a[19]); SQRADDAC(a[13], a[18]); SQRADDAC(a[14], a[17]); SQRADDAC(a[15], a[16]); SQRADDDB;
- COMBA_STORE(b[31]);
-
- /* output 32 */
- CARRY_FORWARD;
- SQRADDSC(a[1], a[31]); SQRADDAC(a[2], a[30]); SQRADDAC(a[3], a[29]); SQRADDAC(a[4], a[28]); SQRADDAC(a[5], a[27]); SQRADDAC(a[6], a[26]); SQRADDAC(a[7], a[25]); SQRADDAC(a[8], a[24]); SQRADDAC(a[9], a[23]); SQRADDAC(a[10], a[22]); SQRADDAC(a[11], a[21]); SQRADDAC(a[12], a[20]); SQRADDAC(a[13], a[19]); SQRADDAC(a[14], a[18]); SQRADDAC(a[15], a[17]); SQRADDDB; SQRADD(a[16], a[16]);
- COMBA_STORE(b[32]);
-
- /* output 33 */
- CARRY_FORWARD;
- SQRADDSC(a[2], a[31]); SQRADDAC(a[3], a[30]); SQRADDAC(a[4], a[29]); SQRADDAC(a[5], a[28]); SQRADDAC(a[6], a[27]); SQRADDAC(a[7], a[26]); SQRADDAC(a[8], a[25]); SQRADDAC(a[9], a[24]); SQRADDAC(a[10], a[23]); SQRADDAC(a[11], a[22]); SQRADDAC(a[12], a[21]); SQRADDAC(a[13], a[20]); SQRADDAC(a[14], a[19]); SQRADDAC(a[15], a[18]); SQRADDAC(a[16], a[17]); SQRADDDB;
- COMBA_STORE(b[33]);
-
- /* output 34 */
- CARRY_FORWARD;
- SQRADDSC(a[3], a[31]); SQRADDAC(a[4], a[30]); SQRADDAC(a[5], a[29]); SQRADDAC(a[6], a[28]); SQRADDAC(a[7], a[27]); SQRADDAC(a[8], a[26]); SQRADDAC(a[9], a[25]); SQRADDAC(a[10], a[24]); SQRADDAC(a[11], a[23]); SQRADDAC(a[12], a[22]); SQRADDAC(a[13], a[21]); SQRADDAC(a[14], a[20]); SQRADDAC(a[15], a[19]); SQRADDAC(a[16], a[18]); SQRADDDB; SQRADD(a[17], a[17]);
- COMBA_STORE(b[34]);
-
- /* output 35 */
- CARRY_FORWARD;
- SQRADDSC(a[4], a[31]); SQRADDAC(a[5], a[30]); SQRADDAC(a[6], a[29]); SQRADDAC(a[7], a[28]); SQRADDAC(a[8], a[27]); SQRADDAC(a[9], a[26]); SQRADDAC(a[10], a[25]); SQRADDAC(a[11], a[24]); SQRADDAC(a[12], a[23]); SQRADDAC(a[13], a[22]); SQRADDAC(a[14], a[21]); SQRADDAC(a[15], a[20]); SQRADDAC(a[16], a[19]); SQRADDAC(a[17], a[18]); SQRADDDB;
- COMBA_STORE(b[35]);
-
- /* output 36 */
- CARRY_FORWARD;
- SQRADDSC(a[5], a[31]); SQRADDAC(a[6], a[30]); SQRADDAC(a[7], a[29]); SQRADDAC(a[8], a[28]); SQRADDAC(a[9], a[27]); SQRADDAC(a[10], a[26]); SQRADDAC(a[11], a[25]); SQRADDAC(a[12], a[24]); SQRADDAC(a[13], a[23]); SQRADDAC(a[14], a[22]); SQRADDAC(a[15], a[21]); SQRADDAC(a[16], a[20]); SQRADDAC(a[17], a[19]); SQRADDDB; SQRADD(a[18], a[18]);
- COMBA_STORE(b[36]);
-
- /* output 37 */
- CARRY_FORWARD;
- SQRADDSC(a[6], a[31]); SQRADDAC(a[7], a[30]); SQRADDAC(a[8], a[29]); SQRADDAC(a[9], a[28]); SQRADDAC(a[10], a[27]); SQRADDAC(a[11], a[26]); SQRADDAC(a[12], a[25]); SQRADDAC(a[13], a[24]); SQRADDAC(a[14], a[23]); SQRADDAC(a[15], a[22]); SQRADDAC(a[16], a[21]); SQRADDAC(a[17], a[20]); SQRADDAC(a[18], a[19]); SQRADDDB;
- COMBA_STORE(b[37]);
-
- /* output 38 */
- CARRY_FORWARD;
- SQRADDSC(a[7], a[31]); SQRADDAC(a[8], a[30]); SQRADDAC(a[9], a[29]); SQRADDAC(a[10], a[28]); SQRADDAC(a[11], a[27]); SQRADDAC(a[12], a[26]); SQRADDAC(a[13], a[25]); SQRADDAC(a[14], a[24]); SQRADDAC(a[15], a[23]); SQRADDAC(a[16], a[22]); SQRADDAC(a[17], a[21]); SQRADDAC(a[18], a[20]); SQRADDDB; SQRADD(a[19], a[19]);
- COMBA_STORE(b[38]);
-
- /* output 39 */
- CARRY_FORWARD;
- SQRADDSC(a[8], a[31]); SQRADDAC(a[9], a[30]); SQRADDAC(a[10], a[29]); SQRADDAC(a[11], a[28]); SQRADDAC(a[12], a[27]); SQRADDAC(a[13], a[26]); SQRADDAC(a[14], a[25]); SQRADDAC(a[15], a[24]); SQRADDAC(a[16], a[23]); SQRADDAC(a[17], a[22]); SQRADDAC(a[18], a[21]); SQRADDAC(a[19], a[20]); SQRADDDB;
- COMBA_STORE(b[39]);
-
- /* output 40 */
- CARRY_FORWARD;
- SQRADDSC(a[9], a[31]); SQRADDAC(a[10], a[30]); SQRADDAC(a[11], a[29]); SQRADDAC(a[12], a[28]); SQRADDAC(a[13], a[27]); SQRADDAC(a[14], a[26]); SQRADDAC(a[15], a[25]); SQRADDAC(a[16], a[24]); SQRADDAC(a[17], a[23]); SQRADDAC(a[18], a[22]); SQRADDAC(a[19], a[21]); SQRADDDB; SQRADD(a[20], a[20]);
- COMBA_STORE(b[40]);
-
- /* output 41 */
- CARRY_FORWARD;
- SQRADDSC(a[10], a[31]); SQRADDAC(a[11], a[30]); SQRADDAC(a[12], a[29]); SQRADDAC(a[13], a[28]); SQRADDAC(a[14], a[27]); SQRADDAC(a[15], a[26]); SQRADDAC(a[16], a[25]); SQRADDAC(a[17], a[24]); SQRADDAC(a[18], a[23]); SQRADDAC(a[19], a[22]); SQRADDAC(a[20], a[21]); SQRADDDB;
- COMBA_STORE(b[41]);
-
- /* output 42 */
- CARRY_FORWARD;
- SQRADDSC(a[11], a[31]); SQRADDAC(a[12], a[30]); SQRADDAC(a[13], a[29]); SQRADDAC(a[14], a[28]); SQRADDAC(a[15], a[27]); SQRADDAC(a[16], a[26]); SQRADDAC(a[17], a[25]); SQRADDAC(a[18], a[24]); SQRADDAC(a[19], a[23]); SQRADDAC(a[20], a[22]); SQRADDDB; SQRADD(a[21], a[21]);
- COMBA_STORE(b[42]);
-
- /* output 43 */
- CARRY_FORWARD;
- SQRADDSC(a[12], a[31]); SQRADDAC(a[13], a[30]); SQRADDAC(a[14], a[29]); SQRADDAC(a[15], a[28]); SQRADDAC(a[16], a[27]); SQRADDAC(a[17], a[26]); SQRADDAC(a[18], a[25]); SQRADDAC(a[19], a[24]); SQRADDAC(a[20], a[23]); SQRADDAC(a[21], a[22]); SQRADDDB;
- COMBA_STORE(b[43]);
-
- /* output 44 */
- CARRY_FORWARD;
- SQRADDSC(a[13], a[31]); SQRADDAC(a[14], a[30]); SQRADDAC(a[15], a[29]); SQRADDAC(a[16], a[28]); SQRADDAC(a[17], a[27]); SQRADDAC(a[18], a[26]); SQRADDAC(a[19], a[25]); SQRADDAC(a[20], a[24]); SQRADDAC(a[21], a[23]); SQRADDDB; SQRADD(a[22], a[22]);
- COMBA_STORE(b[44]);
-
- /* output 45 */
- CARRY_FORWARD;
- SQRADDSC(a[14], a[31]); SQRADDAC(a[15], a[30]); SQRADDAC(a[16], a[29]); SQRADDAC(a[17], a[28]); SQRADDAC(a[18], a[27]); SQRADDAC(a[19], a[26]); SQRADDAC(a[20], a[25]); SQRADDAC(a[21], a[24]); SQRADDAC(a[22], a[23]); SQRADDDB;
- COMBA_STORE(b[45]);
-
- /* output 46 */
- CARRY_FORWARD;
- SQRADDSC(a[15], a[31]); SQRADDAC(a[16], a[30]); SQRADDAC(a[17], a[29]); SQRADDAC(a[18], a[28]); SQRADDAC(a[19], a[27]); SQRADDAC(a[20], a[26]); SQRADDAC(a[21], a[25]); SQRADDAC(a[22], a[24]); SQRADDDB; SQRADD(a[23], a[23]);
- COMBA_STORE(b[46]);
-
- /* output 47 */
- CARRY_FORWARD;
- SQRADDSC(a[16], a[31]); SQRADDAC(a[17], a[30]); SQRADDAC(a[18], a[29]); SQRADDAC(a[19], a[28]); SQRADDAC(a[20], a[27]); SQRADDAC(a[21], a[26]); SQRADDAC(a[22], a[25]); SQRADDAC(a[23], a[24]); SQRADDDB;
- COMBA_STORE(b[47]);
-
- /* output 48 */
- CARRY_FORWARD;
- SQRADDSC(a[17], a[31]); SQRADDAC(a[18], a[30]); SQRADDAC(a[19], a[29]); SQRADDAC(a[20], a[28]); SQRADDAC(a[21], a[27]); SQRADDAC(a[22], a[26]); SQRADDAC(a[23], a[25]); SQRADDDB; SQRADD(a[24], a[24]);
- COMBA_STORE(b[48]);
-
- /* output 49 */
- CARRY_FORWARD;
- SQRADDSC(a[18], a[31]); SQRADDAC(a[19], a[30]); SQRADDAC(a[20], a[29]); SQRADDAC(a[21], a[28]); SQRADDAC(a[22], a[27]); SQRADDAC(a[23], a[26]); SQRADDAC(a[24], a[25]); SQRADDDB;
- COMBA_STORE(b[49]);
-
- /* output 50 */
- CARRY_FORWARD;
- SQRADDSC(a[19], a[31]); SQRADDAC(a[20], a[30]); SQRADDAC(a[21], a[29]); SQRADDAC(a[22], a[28]); SQRADDAC(a[23], a[27]); SQRADDAC(a[24], a[26]); SQRADDDB; SQRADD(a[25], a[25]);
- COMBA_STORE(b[50]);
-
- /* output 51 */
- CARRY_FORWARD;
- SQRADDSC(a[20], a[31]); SQRADDAC(a[21], a[30]); SQRADDAC(a[22], a[29]); SQRADDAC(a[23], a[28]); SQRADDAC(a[24], a[27]); SQRADDAC(a[25], a[26]); SQRADDDB;
- COMBA_STORE(b[51]);
-
- /* output 52 */
- CARRY_FORWARD;
- SQRADDSC(a[21], a[31]); SQRADDAC(a[22], a[30]); SQRADDAC(a[23], a[29]); SQRADDAC(a[24], a[28]); SQRADDAC(a[25], a[27]); SQRADDDB; SQRADD(a[26], a[26]);
- COMBA_STORE(b[52]);
-
- /* output 53 */
- CARRY_FORWARD;
- SQRADDSC(a[22], a[31]); SQRADDAC(a[23], a[30]); SQRADDAC(a[24], a[29]); SQRADDAC(a[25], a[28]); SQRADDAC(a[26], a[27]); SQRADDDB;
- COMBA_STORE(b[53]);
-
- /* output 54 */
- CARRY_FORWARD;
- SQRADDSC(a[23], a[31]); SQRADDAC(a[24], a[30]); SQRADDAC(a[25], a[29]); SQRADDAC(a[26], a[28]); SQRADDDB; SQRADD(a[27], a[27]);
- COMBA_STORE(b[54]);
-
- /* output 55 */
- CARRY_FORWARD;
- SQRADDSC(a[24], a[31]); SQRADDAC(a[25], a[30]); SQRADDAC(a[26], a[29]); SQRADDAC(a[27], a[28]); SQRADDDB;
- COMBA_STORE(b[55]);
-
- /* output 56 */
- CARRY_FORWARD;
- SQRADDSC(a[25], a[31]); SQRADDAC(a[26], a[30]); SQRADDAC(a[27], a[29]); SQRADDDB; SQRADD(a[28], a[28]);
- COMBA_STORE(b[56]);
-
- /* output 57 */
- CARRY_FORWARD;
- SQRADDSC(a[26], a[31]); SQRADDAC(a[27], a[30]); SQRADDAC(a[28], a[29]); SQRADDDB;
- COMBA_STORE(b[57]);
-
- /* output 58 */
- CARRY_FORWARD;
- SQRADD2(a[27], a[31]); SQRADD2(a[28], a[30]); SQRADD(a[29], a[29]);
- COMBA_STORE(b[58]);
-
- /* output 59 */
- CARRY_FORWARD;
- SQRADD2(a[28], a[31]); SQRADD2(a[29], a[30]);
- COMBA_STORE(b[59]);
-
- /* output 60 */
- CARRY_FORWARD;
- SQRADD2(a[29], a[31]); SQRADD(a[30], a[30]);
- COMBA_STORE(b[60]);
-
- /* output 61 */
- CARRY_FORWARD;
- SQRADD2(a[30], a[31]);
- COMBA_STORE(b[61]);
-
- /* output 62 */
- CARRY_FORWARD;
- SQRADD(a[31], a[31]);
- COMBA_STORE(b[62]);
- COMBA_STORE2(b[63]);
- COMBA_FINI;
-
- B->used = 64;
- B->sign = PSTM_ZPOS;
- memcpy(B->dp, b, 64 * sizeof(pstm_digit));
- pstm_clamp(B);
- return PSTM_OKAY;
+ pstm_digit *a, b[64], c0, c1, c2, sc0, sc1, sc2;
+
+# ifdef PSTM_ISO
+ pstm_word tt;
+# endif
+
+ if (B->alloc < 64)
+ {
+ if (pstm_grow(B, 64) != PSTM_OKAY)
+ {
+ return PS_MEM_FAIL;
+ }
+ }
+ sc0 = sc1 = sc2 = 0;
+ a = A->dp;
+ COMBA_START;
+
+ /* clear carries */
+ CLEAR_CARRY;
+
+ /* output 0 */
+ SQRADD(a[0], a[0]);
+ COMBA_STORE(b[0]);
+
+ /* output 1 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[1]);
+ COMBA_STORE(b[1]);
+
+ /* output 2 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]);
+ COMBA_STORE(b[2]);
+
+ /* output 3 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]);
+ COMBA_STORE(b[3]);
+
+ /* output 4 */
+ CARRY_FORWARD;
+ SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]);
+ COMBA_STORE(b[4]);
+
+ /* output 5 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB;
+ COMBA_STORE(b[5]);
+
+ /* output 6 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]);
+ COMBA_STORE(b[6]);
+
+ /* output 7 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB;
+ COMBA_STORE(b[7]);
+
+ /* output 8 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]);
+ COMBA_STORE(b[8]);
+
+ /* output 9 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB;
+ COMBA_STORE(b[9]);
+
+ /* output 10 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]);
+ COMBA_STORE(b[10]);
+
+ /* output 11 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB;
+ COMBA_STORE(b[11]);
+
+ /* output 12 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]);
+ COMBA_STORE(b[12]);
+
+ /* output 13 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB;
+ COMBA_STORE(b[13]);
+
+ /* output 14 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]);
+ COMBA_STORE(b[14]);
+
+ /* output 15 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB;
+ COMBA_STORE(b[15]);
+
+ /* output 16 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[16]); SQRADDAC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]);
+ COMBA_STORE(b[16]);
+
+ /* output 17 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[17]); SQRADDAC(a[1], a[16]); SQRADDAC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB;
+ COMBA_STORE(b[17]);
+
+ /* output 18 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[18]); SQRADDAC(a[1], a[17]); SQRADDAC(a[2], a[16]); SQRADDAC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]);
+ COMBA_STORE(b[18]);
+
+ /* output 19 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[19]); SQRADDAC(a[1], a[18]); SQRADDAC(a[2], a[17]); SQRADDAC(a[3], a[16]); SQRADDAC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB;
+ COMBA_STORE(b[19]);
+
+ /* output 20 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[20]); SQRADDAC(a[1], a[19]); SQRADDAC(a[2], a[18]); SQRADDAC(a[3], a[17]); SQRADDAC(a[4], a[16]); SQRADDAC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]);
+ COMBA_STORE(b[20]);
+
+ /* output 21 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[21]); SQRADDAC(a[1], a[20]); SQRADDAC(a[2], a[19]); SQRADDAC(a[3], a[18]); SQRADDAC(a[4], a[17]); SQRADDAC(a[5], a[16]); SQRADDAC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB;
+ COMBA_STORE(b[21]);
+
+ /* output 22 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[22]); SQRADDAC(a[1], a[21]); SQRADDAC(a[2], a[20]); SQRADDAC(a[3], a[19]); SQRADDAC(a[4], a[18]); SQRADDAC(a[5], a[17]); SQRADDAC(a[6], a[16]); SQRADDAC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]);
+ COMBA_STORE(b[22]);
+
+ /* output 23 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[23]); SQRADDAC(a[1], a[22]); SQRADDAC(a[2], a[21]); SQRADDAC(a[3], a[20]); SQRADDAC(a[4], a[19]); SQRADDAC(a[5], a[18]); SQRADDAC(a[6], a[17]); SQRADDAC(a[7], a[16]); SQRADDAC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB;
+ COMBA_STORE(b[23]);
+
+ /* output 24 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[24]); SQRADDAC(a[1], a[23]); SQRADDAC(a[2], a[22]); SQRADDAC(a[3], a[21]); SQRADDAC(a[4], a[20]); SQRADDAC(a[5], a[19]); SQRADDAC(a[6], a[18]); SQRADDAC(a[7], a[17]); SQRADDAC(a[8], a[16]); SQRADDAC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]);
+ COMBA_STORE(b[24]);
+
+ /* output 25 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[25]); SQRADDAC(a[1], a[24]); SQRADDAC(a[2], a[23]); SQRADDAC(a[3], a[22]); SQRADDAC(a[4], a[21]); SQRADDAC(a[5], a[20]); SQRADDAC(a[6], a[19]); SQRADDAC(a[7], a[18]); SQRADDAC(a[8], a[17]); SQRADDAC(a[9], a[16]); SQRADDAC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB;
+ COMBA_STORE(b[25]);
+
+ /* output 26 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[26]); SQRADDAC(a[1], a[25]); SQRADDAC(a[2], a[24]); SQRADDAC(a[3], a[23]); SQRADDAC(a[4], a[22]); SQRADDAC(a[5], a[21]); SQRADDAC(a[6], a[20]); SQRADDAC(a[7], a[19]); SQRADDAC(a[8], a[18]); SQRADDAC(a[9], a[17]); SQRADDAC(a[10], a[16]); SQRADDAC(a[11], a[15]); SQRADDAC(a[12], a[14]); SQRADDDB; SQRADD(a[13], a[13]);
+ COMBA_STORE(b[26]);
+
+ /* output 27 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[27]); SQRADDAC(a[1], a[26]); SQRADDAC(a[2], a[25]); SQRADDAC(a[3], a[24]); SQRADDAC(a[4], a[23]); SQRADDAC(a[5], a[22]); SQRADDAC(a[6], a[21]); SQRADDAC(a[7], a[20]); SQRADDAC(a[8], a[19]); SQRADDAC(a[9], a[18]); SQRADDAC(a[10], a[17]); SQRADDAC(a[11], a[16]); SQRADDAC(a[12], a[15]); SQRADDAC(a[13], a[14]); SQRADDDB;
+ COMBA_STORE(b[27]);
+
+ /* output 28 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[28]); SQRADDAC(a[1], a[27]); SQRADDAC(a[2], a[26]); SQRADDAC(a[3], a[25]); SQRADDAC(a[4], a[24]); SQRADDAC(a[5], a[23]); SQRADDAC(a[6], a[22]); SQRADDAC(a[7], a[21]); SQRADDAC(a[8], a[20]); SQRADDAC(a[9], a[19]); SQRADDAC(a[10], a[18]); SQRADDAC(a[11], a[17]); SQRADDAC(a[12], a[16]); SQRADDAC(a[13], a[15]); SQRADDDB; SQRADD(a[14], a[14]);
+ COMBA_STORE(b[28]);
+
+ /* output 29 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[29]); SQRADDAC(a[1], a[28]); SQRADDAC(a[2], a[27]); SQRADDAC(a[3], a[26]); SQRADDAC(a[4], a[25]); SQRADDAC(a[5], a[24]); SQRADDAC(a[6], a[23]); SQRADDAC(a[7], a[22]); SQRADDAC(a[8], a[21]); SQRADDAC(a[9], a[20]); SQRADDAC(a[10], a[19]); SQRADDAC(a[11], a[18]); SQRADDAC(a[12], a[17]); SQRADDAC(a[13], a[16]); SQRADDAC(a[14], a[15]); SQRADDDB;
+ COMBA_STORE(b[29]);
+
+ /* output 30 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[30]); SQRADDAC(a[1], a[29]); SQRADDAC(a[2], a[28]); SQRADDAC(a[3], a[27]); SQRADDAC(a[4], a[26]); SQRADDAC(a[5], a[25]); SQRADDAC(a[6], a[24]); SQRADDAC(a[7], a[23]); SQRADDAC(a[8], a[22]); SQRADDAC(a[9], a[21]); SQRADDAC(a[10], a[20]); SQRADDAC(a[11], a[19]); SQRADDAC(a[12], a[18]); SQRADDAC(a[13], a[17]); SQRADDAC(a[14], a[16]); SQRADDDB; SQRADD(a[15], a[15]);
+ COMBA_STORE(b[30]);
+
+ /* output 31 */
+ CARRY_FORWARD;
+ SQRADDSC(a[0], a[31]); SQRADDAC(a[1], a[30]); SQRADDAC(a[2], a[29]); SQRADDAC(a[3], a[28]); SQRADDAC(a[4], a[27]); SQRADDAC(a[5], a[26]); SQRADDAC(a[6], a[25]); SQRADDAC(a[7], a[24]); SQRADDAC(a[8], a[23]); SQRADDAC(a[9], a[22]); SQRADDAC(a[10], a[21]); SQRADDAC(a[11], a[20]); SQRADDAC(a[12], a[19]); SQRADDAC(a[13], a[18]); SQRADDAC(a[14], a[17]); SQRADDAC(a[15], a[16]); SQRADDDB;
+ COMBA_STORE(b[31]);
+
+ /* output 32 */
+ CARRY_FORWARD;
+ SQRADDSC(a[1], a[31]); SQRADDAC(a[2], a[30]); SQRADDAC(a[3], a[29]); SQRADDAC(a[4], a[28]); SQRADDAC(a[5], a[27]); SQRADDAC(a[6], a[26]); SQRADDAC(a[7], a[25]); SQRADDAC(a[8], a[24]); SQRADDAC(a[9], a[23]); SQRADDAC(a[10], a[22]); SQRADDAC(a[11], a[21]); SQRADDAC(a[12], a[20]); SQRADDAC(a[13], a[19]); SQRADDAC(a[14], a[18]); SQRADDAC(a[15], a[17]); SQRADDDB; SQRADD(a[16], a[16]);
+ COMBA_STORE(b[32]);
+
+ /* output 33 */
+ CARRY_FORWARD;
+ SQRADDSC(a[2], a[31]); SQRADDAC(a[3], a[30]); SQRADDAC(a[4], a[29]); SQRADDAC(a[5], a[28]); SQRADDAC(a[6], a[27]); SQRADDAC(a[7], a[26]); SQRADDAC(a[8], a[25]); SQRADDAC(a[9], a[24]); SQRADDAC(a[10], a[23]); SQRADDAC(a[11], a[22]); SQRADDAC(a[12], a[21]); SQRADDAC(a[13], a[20]); SQRADDAC(a[14], a[19]); SQRADDAC(a[15], a[18]); SQRADDAC(a[16], a[17]); SQRADDDB;
+ COMBA_STORE(b[33]);
+
+ /* output 34 */
+ CARRY_FORWARD;
+ SQRADDSC(a[3], a[31]); SQRADDAC(a[4], a[30]); SQRADDAC(a[5], a[29]); SQRADDAC(a[6], a[28]); SQRADDAC(a[7], a[27]); SQRADDAC(a[8], a[26]); SQRADDAC(a[9], a[25]); SQRADDAC(a[10], a[24]); SQRADDAC(a[11], a[23]); SQRADDAC(a[12], a[22]); SQRADDAC(a[13], a[21]); SQRADDAC(a[14], a[20]); SQRADDAC(a[15], a[19]); SQRADDAC(a[16], a[18]); SQRADDDB; SQRADD(a[17], a[17]);
+ COMBA_STORE(b[34]);
+
+ /* output 35 */
+ CARRY_FORWARD;
+ SQRADDSC(a[4], a[31]); SQRADDAC(a[5], a[30]); SQRADDAC(a[6], a[29]); SQRADDAC(a[7], a[28]); SQRADDAC(a[8], a[27]); SQRADDAC(a[9], a[26]); SQRADDAC(a[10], a[25]); SQRADDAC(a[11], a[24]); SQRADDAC(a[12], a[23]); SQRADDAC(a[13], a[22]); SQRADDAC(a[14], a[21]); SQRADDAC(a[15], a[20]); SQRADDAC(a[16], a[19]); SQRADDAC(a[17], a[18]); SQRADDDB;
+ COMBA_STORE(b[35]);
+
+ /* output 36 */
+ CARRY_FORWARD;
+ SQRADDSC(a[5], a[31]); SQRADDAC(a[6], a[30]); SQRADDAC(a[7], a[29]); SQRADDAC(a[8], a[28]); SQRADDAC(a[9], a[27]); SQRADDAC(a[10], a[26]); SQRADDAC(a[11], a[25]); SQRADDAC(a[12], a[24]); SQRADDAC(a[13], a[23]); SQRADDAC(a[14], a[22]); SQRADDAC(a[15], a[21]); SQRADDAC(a[16], a[20]); SQRADDAC(a[17], a[19]); SQRADDDB; SQRADD(a[18], a[18]);
+ COMBA_STORE(b[36]);
+
+ /* output 37 */
+ CARRY_FORWARD;
+ SQRADDSC(a[6], a[31]); SQRADDAC(a[7], a[30]); SQRADDAC(a[8], a[29]); SQRADDAC(a[9], a[28]); SQRADDAC(a[10], a[27]); SQRADDAC(a[11], a[26]); SQRADDAC(a[12], a[25]); SQRADDAC(a[13], a[24]); SQRADDAC(a[14], a[23]); SQRADDAC(a[15], a[22]); SQRADDAC(a[16], a[21]); SQRADDAC(a[17], a[20]); SQRADDAC(a[18], a[19]); SQRADDDB;
+ COMBA_STORE(b[37]);
+
+ /* output 38 */
+ CARRY_FORWARD;
+ SQRADDSC(a[7], a[31]); SQRADDAC(a[8], a[30]); SQRADDAC(a[9], a[29]); SQRADDAC(a[10], a[28]); SQRADDAC(a[11], a[27]); SQRADDAC(a[12], a[26]); SQRADDAC(a[13], a[25]); SQRADDAC(a[14], a[24]); SQRADDAC(a[15], a[23]); SQRADDAC(a[16], a[22]); SQRADDAC(a[17], a[21]); SQRADDAC(a[18], a[20]); SQRADDDB; SQRADD(a[19], a[19]);
+ COMBA_STORE(b[38]);
+
+ /* output 39 */
+ CARRY_FORWARD;
+ SQRADDSC(a[8], a[31]); SQRADDAC(a[9], a[30]); SQRADDAC(a[10], a[29]); SQRADDAC(a[11], a[28]); SQRADDAC(a[12], a[27]); SQRADDAC(a[13], a[26]); SQRADDAC(a[14], a[25]); SQRADDAC(a[15], a[24]); SQRADDAC(a[16], a[23]); SQRADDAC(a[17], a[22]); SQRADDAC(a[18], a[21]); SQRADDAC(a[19], a[20]); SQRADDDB;
+ COMBA_STORE(b[39]);
+
+ /* output 40 */
+ CARRY_FORWARD;
+ SQRADDSC(a[9], a[31]); SQRADDAC(a[10], a[30]); SQRADDAC(a[11], a[29]); SQRADDAC(a[12], a[28]); SQRADDAC(a[13], a[27]); SQRADDAC(a[14], a[26]); SQRADDAC(a[15], a[25]); SQRADDAC(a[16], a[24]); SQRADDAC(a[17], a[23]); SQRADDAC(a[18], a[22]); SQRADDAC(a[19], a[21]); SQRADDDB; SQRADD(a[20], a[20]);
+ COMBA_STORE(b[40]);
+
+ /* output 41 */
+ CARRY_FORWARD;
+ SQRADDSC(a[10], a[31]); SQRADDAC(a[11], a[30]); SQRADDAC(a[12], a[29]); SQRADDAC(a[13], a[28]); SQRADDAC(a[14], a[27]); SQRADDAC(a[15], a[26]); SQRADDAC(a[16], a[25]); SQRADDAC(a[17], a[24]); SQRADDAC(a[18], a[23]); SQRADDAC(a[19], a[22]); SQRADDAC(a[20], a[21]); SQRADDDB;
+ COMBA_STORE(b[41]);
+
+ /* output 42 */
+ CARRY_FORWARD;
+ SQRADDSC(a[11], a[31]); SQRADDAC(a[12], a[30]); SQRADDAC(a[13], a[29]); SQRADDAC(a[14], a[28]); SQRADDAC(a[15], a[27]); SQRADDAC(a[16], a[26]); SQRADDAC(a[17], a[25]); SQRADDAC(a[18], a[24]); SQRADDAC(a[19], a[23]); SQRADDAC(a[20], a[22]); SQRADDDB; SQRADD(a[21], a[21]);
+ COMBA_STORE(b[42]);
+
+ /* output 43 */
+ CARRY_FORWARD;
+ SQRADDSC(a[12], a[31]); SQRADDAC(a[13], a[30]); SQRADDAC(a[14], a[29]); SQRADDAC(a[15], a[28]); SQRADDAC(a[16], a[27]); SQRADDAC(a[17], a[26]); SQRADDAC(a[18], a[25]); SQRADDAC(a[19], a[24]); SQRADDAC(a[20], a[23]); SQRADDAC(a[21], a[22]); SQRADDDB;
+ COMBA_STORE(b[43]);
+
+ /* output 44 */
+ CARRY_FORWARD;
+ SQRADDSC(a[13], a[31]); SQRADDAC(a[14], a[30]); SQRADDAC(a[15], a[29]); SQRADDAC(a[16], a[28]); SQRADDAC(a[17], a[27]); SQRADDAC(a[18], a[26]); SQRADDAC(a[19], a[25]); SQRADDAC(a[20], a[24]); SQRADDAC(a[21], a[23]); SQRADDDB; SQRADD(a[22], a[22]);
+ COMBA_STORE(b[44]);
+
+ /* output 45 */
+ CARRY_FORWARD;
+ SQRADDSC(a[14], a[31]); SQRADDAC(a[15], a[30]); SQRADDAC(a[16], a[29]); SQRADDAC(a[17], a[28]); SQRADDAC(a[18], a[27]); SQRADDAC(a[19], a[26]); SQRADDAC(a[20], a[25]); SQRADDAC(a[21], a[24]); SQRADDAC(a[22], a[23]); SQRADDDB;
+ COMBA_STORE(b[45]);
+
+ /* output 46 */
+ CARRY_FORWARD;
+ SQRADDSC(a[15], a[31]); SQRADDAC(a[16], a[30]); SQRADDAC(a[17], a[29]); SQRADDAC(a[18], a[28]); SQRADDAC(a[19], a[27]); SQRADDAC(a[20], a[26]); SQRADDAC(a[21], a[25]); SQRADDAC(a[22], a[24]); SQRADDDB; SQRADD(a[23], a[23]);
+ COMBA_STORE(b[46]);
+
+ /* output 47 */
+ CARRY_FORWARD;
+ SQRADDSC(a[16], a[31]); SQRADDAC(a[17], a[30]); SQRADDAC(a[18], a[29]); SQRADDAC(a[19], a[28]); SQRADDAC(a[20], a[27]); SQRADDAC(a[21], a[26]); SQRADDAC(a[22], a[25]); SQRADDAC(a[23], a[24]); SQRADDDB;
+ COMBA_STORE(b[47]);
+
+ /* output 48 */
+ CARRY_FORWARD;
+ SQRADDSC(a[17], a[31]); SQRADDAC(a[18], a[30]); SQRADDAC(a[19], a[29]); SQRADDAC(a[20], a[28]); SQRADDAC(a[21], a[27]); SQRADDAC(a[22], a[26]); SQRADDAC(a[23], a[25]); SQRADDDB; SQRADD(a[24], a[24]);
+ COMBA_STORE(b[48]);
+
+ /* output 49 */
+ CARRY_FORWARD;
+ SQRADDSC(a[18], a[31]); SQRADDAC(a[19], a[30]); SQRADDAC(a[20], a[29]); SQRADDAC(a[21], a[28]); SQRADDAC(a[22], a[27]); SQRADDAC(a[23], a[26]); SQRADDAC(a[24], a[25]); SQRADDDB;
+ COMBA_STORE(b[49]);
+
+ /* output 50 */
+ CARRY_FORWARD;
+ SQRADDSC(a[19], a[31]); SQRADDAC(a[20], a[30]); SQRADDAC(a[21], a[29]); SQRADDAC(a[22], a[28]); SQRADDAC(a[23], a[27]); SQRADDAC(a[24], a[26]); SQRADDDB; SQRADD(a[25], a[25]);
+ COMBA_STORE(b[50]);
+
+ /* output 51 */
+ CARRY_FORWARD;
+ SQRADDSC(a[20], a[31]); SQRADDAC(a[21], a[30]); SQRADDAC(a[22], a[29]); SQRADDAC(a[23], a[28]); SQRADDAC(a[24], a[27]); SQRADDAC(a[25], a[26]); SQRADDDB;
+ COMBA_STORE(b[51]);
+
+ /* output 52 */
+ CARRY_FORWARD;
+ SQRADDSC(a[21], a[31]); SQRADDAC(a[22], a[30]); SQRADDAC(a[23], a[29]); SQRADDAC(a[24], a[28]); SQRADDAC(a[25], a[27]); SQRADDDB; SQRADD(a[26], a[26]);
+ COMBA_STORE(b[52]);
+
+ /* output 53 */
+ CARRY_FORWARD;
+ SQRADDSC(a[22], a[31]); SQRADDAC(a[23], a[30]); SQRADDAC(a[24], a[29]); SQRADDAC(a[25], a[28]); SQRADDAC(a[26], a[27]); SQRADDDB;
+ COMBA_STORE(b[53]);
+
+ /* output 54 */
+ CARRY_FORWARD;
+ SQRADDSC(a[23], a[31]); SQRADDAC(a[24], a[30]); SQRADDAC(a[25], a[29]); SQRADDAC(a[26], a[28]); SQRADDDB; SQRADD(a[27], a[27]);
+ COMBA_STORE(b[54]);
+
+ /* output 55 */
+ CARRY_FORWARD;
+ SQRADDSC(a[24], a[31]); SQRADDAC(a[25], a[30]); SQRADDAC(a[26], a[29]); SQRADDAC(a[27], a[28]); SQRADDDB;
+ COMBA_STORE(b[55]);
+
+ /* output 56 */
+ CARRY_FORWARD;
+ SQRADDSC(a[25], a[31]); SQRADDAC(a[26], a[30]); SQRADDAC(a[27], a[29]); SQRADDDB; SQRADD(a[28], a[28]);
+ COMBA_STORE(b[56]);
+
+ /* output 57 */
+ CARRY_FORWARD;
+ SQRADDSC(a[26], a[31]); SQRADDAC(a[27], a[30]); SQRADDAC(a[28], a[29]); SQRADDDB;
+ COMBA_STORE(b[57]);
+
+ /* output 58 */
+ CARRY_FORWARD;
+ SQRADD2(a[27], a[31]); SQRADD2(a[28], a[30]); SQRADD(a[29], a[29]);
+ COMBA_STORE(b[58]);
+
+ /* output 59 */
+ CARRY_FORWARD;
+ SQRADD2(a[28], a[31]); SQRADD2(a[29], a[30]);
+ COMBA_STORE(b[59]);
+
+ /* output 60 */
+ CARRY_FORWARD;
+ SQRADD2(a[29], a[31]); SQRADD(a[30], a[30]);
+ COMBA_STORE(b[60]);
+
+ /* output 61 */
+ CARRY_FORWARD;
+ SQRADD2(a[30], a[31]);
+ COMBA_STORE(b[61]);
+
+ /* output 62 */
+ CARRY_FORWARD;
+ SQRADD(a[31], a[31]);
+ COMBA_STORE(b[62]);
+ COMBA_STORE2(b[63]);
+ COMBA_FINI;
+
+ B->used = 64;
+ B->sign = PSTM_ZPOS;
+ memcpy(B->dp, b, 64 * sizeof(pstm_digit));
+ pstm_clamp(B);
+ return PSTM_OKAY;
}
-#endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */
+# endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */
/******************************************************************************/
/**
- B = A**2.
- @param[in] pool Memory pool
- @param[in] A Base
- @param[out] B Result
- @param[in,out] paD Temporary storage
- @param[in] paDlen Number of items pointed to by paD
-*/
+ B = A**2.
+ @param[in] pool Memory pool
+ @param[in] A Base
+ @param[out] B Result
+ @param[in,out] paD Temporary storage
+ @param[in] paDlen Number of items pointed to by paD
+ */
int32_t pstm_sqr_comba(psPool_t *pool, const pstm_int *A, pstm_int *B,
- pstm_digit *paD, uint16_t paDlen)
+ pstm_digit *paD, psSize_t paDlen)
{
-#ifdef USE_1024_KEY_SPEED_OPTIMIZATIONS
- if (A->used == 16) {
- return pstm_sqr_comba16(A, B);
- } else {
-#ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS
- if (A->used == 32) {
- return pstm_sqr_comba32(A, B);
- }
-#endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */
- return pstm_sqr_comba_gen(pool, A, B, paD, paDlen);
- }
-#else
-#ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS
- if (A->used == 32) {
- return pstm_sqr_comba32(A, B);
- }
-#endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */
- return pstm_sqr_comba_gen(pool, A, B, paD, paDlen);
-#endif
+# ifdef USE_1024_KEY_SPEED_OPTIMIZATIONS
+ if (A->used == 16)
+ {
+ return pstm_sqr_comba16(A, B);
+ }
+ else
+ {
+# ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS
+ if (A->used == 32)
+ {
+ return pstm_sqr_comba32(A, B);
+ }
+# endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */
+ return pstm_sqr_comba_gen(pool, A, B, paD, paDlen);
+ }
+# else
+# ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS
+ if (A->used == 32)
+ {
+ return pstm_sqr_comba32(A, B);
+ }
+# endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */
+ return pstm_sqr_comba_gen(pool, A, B, paD, paDlen);
+# endif
}
#endif /* defined(USE_MATRIX_RSA) || defined(USE_MATRIX_ECC) */
diff --git a/crypto/math/pstm_str.c b/crypto/math/pstm_str.c
new file mode 100644
index 0000000..ddeb47a
--- /dev/null
+++ b/crypto/math/pstm_str.c
@@ -0,0 +1,104 @@
+/**
+ * @file pstm_str.c
+ * @version $Format:%h%d$
+ *
+ * Multiprecision number implementation.
+ */
+/*
+ * Copyright (c) 2017 INSIDE Secure Corporation
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#include "../cryptoImpl.h"
+#include "pstm.h"
+#include "pstm_str.h"
+
+#ifndef NO_PSTM_STR
+/* Static storage for pstm_str preallocated values. */
+const char *pstm_str_null = "(null)";
+const char *pstm_str_memfail = "(memory_error)";
+
+pstm_str pstm_str_from(psPool_t *pool, const pstm_int *a)
+{
+ static unsigned char hex[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+ };
+ char *b;
+ unsigned char *bh;
+ int neg;
+ uint16_t sz = pstm_unsigned_bin_size(a);
+ uint16_t i;
+ int32_t err;
+
+ if (a == NULL)
+ {
+ return PSTM_STR_NULL;
+ }
+ b = psMalloc(pool, sz * 2 + 4);
+ if (!b)
+ {
+ return PSTM_STR_MEMFAIL;
+ }
+ neg = a->sign == PSTM_NEG;
+ if (neg)
+ {
+ b[0] = '-';
+ b[1] = '0';
+ b[2] = sz > 0 ? 'x' : 0;
+ bh = (unsigned char *) &b[3];
+ bh[sz * 2] = 0;
+ }
+ else
+ {
+ b[0] = '0';
+ b[1] = sz > 0 ? 'x' : 0;
+ bh = (unsigned char *) &b[2];
+ bh[sz * 2] = 0;
+ }
+ err = pstm_to_unsigned_bin(pool, a, bh);
+ if (err < 0)
+ {
+ psFree(b, pool);
+ return PSTM_STR_MEMFAIL;
+ }
+ for (i = sz; i-- > 0; )
+ {
+ bh[i * 2 + 1] = hex[bh[i] & 15];
+ bh[i * 2] = hex[bh[i] / 16];
+ }
+ return b;
+}
+
+void pstm_str_free(psPool_t *pool, pstm_str str)
+{
+ if (str != PSTM_STR_NULL && str != PSTM_STR_MEMFAIL)
+ {
+ psFree(str, pool);
+ }
+}
+
+#endif /* NO_PSTM_STR */
+
diff --git a/crypto/math/pstm_str.h b/crypto/math/pstm_str.h
new file mode 100644
index 0000000..f15543e
--- /dev/null
+++ b/crypto/math/pstm_str.h
@@ -0,0 +1,72 @@
+/**
+ * @file pstm_str.h
+ * @version $Format:%h%d$
+ *
+ * Multiprecision number implementation: debug output.
+ */
+/*
+ * Copyright (c) 2017 INSIDE Secure Corporation
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#include "../cryptoApi.h"
+#include "pstm.h"
+
+/* Before defining pstm_str, ensure pstm has been processed.
+ In some configurations the pstm is disabled,
+ which also disables pstm_str. */
+#ifndef PSTM_AVAILABLE
+# undef NO_PSTM_STR
+# define NO_PSTM_STR
+#endif /* PSTM_AVAILABLE */
+
+#ifndef NO_PSTM_STR
+
+/* PSTM String: A string formatted version of number in PSTM.
+ PSTM string is (typically) dynamically allocated. */
+typedef char *pstm_str;
+
+/* Static PSTM String used when trying to format null pointer. */
+# define PSTM_STR_NULL ((char *) pstm_str_null)
+
+/* Static PSTM String used when memory allocation fails. */
+# define PSTM_STR_MEMFAIL ((char *) pstm_str_memfail)
+
+extern const char *pstm_str_null;
+extern const char *pstm_str_memfail;
+
+/* Construct pstm_str from pstm integer.
+ Even if the function fails, the result is printable with %s.
+ Failure can be observed by comparing pstm_str against
+ PSTM_STR_NULL and PSTM_STR_MEMFAIL. */
+pstm_str pstm_str_from(psPool_t *pool, const pstm_int *a);
+
+/* Free pstm_str.
+ It is safe to call this function with an errorneous pstm_str, i.e.
+ PSTM_STR_NULL or PSTM_STR_MEMFAIL. */
+void pstm_str_free(psPool_t *pool, pstm_str str);
+
+#endif /* NO_PSTM_STR */
+
diff --git a/crypto/math/pstmnt.c b/crypto/math/pstmnt.c
new file mode 100644
index 0000000..c5100e1
--- /dev/null
+++ b/crypto/math/pstmnt.c
@@ -0,0 +1,2614 @@
+/**
+ * @file pstmnt.c
+ * @version $Format:%h%d$
+ *
+ * Multiprecision number implementation: constant time montgomery.
+ */
+/*
+ * Copyright (c) 2017 INSIDE Secure Corporation
+ * All Rights Reserved
+ *
+ * The latest version of this code is available at http://www.matrixssl.org
+ *
+ * This software is open source; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This General Public License does NOT permit incorporating this software
+ * into proprietary programs. If you are unable to comply with the GPL, a
+ * commercial license for this software may be purchased from INSIDE at
+ * http://www.insidesecure.com/
+ *
+ * This program is distributed in WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/******************************************************************************/
+
+#include "../cryptoImpl.h"
+#include "pstmnt.h"
+
+#ifdef USE_CONSTANT_TIME_MODEXP
+
+# include
+
+/* Workarounds for C99 features */
+# if __STDC_VERSION__ < 199901L
+# define restrict /* define restrict to nothing if compiler is not sufficiently
+ new to support it. */
+# endif
+
+/* Additional internal definitions. */
+# define PSTMNT_HOT_FUNCTION /* Function is likely hot spot in computation. */
+
+/* Simple preprocessor macros. */
+# define PSTMNT_JOIN_(a, b) a ## b
+# define PSTMNT_JOIN(a, b) PSTMNT_JOIN_(a, b)
+
+/* Test condition during compilation. */
+# define PSTMNT_COMPILE_ASSERT(pstmnt_condition) \
+ extern int PSTMNT_JOIN(PSTMNT_COMPILE_ASSERT_at_, __LINE__) \
+ [1 - 2 * (!(pstmnt_condition))]
+
+/* Semantics: variants according to intent. */
+# define PSTMNT_ASSERT(x) assert(x)
+# define PSTMNT_PRECONDITION(x) assert(x)
+# define PSTMNT_POSTCONDITION(x) assert(x)
+
+/* Mark expected execution paths for compiler optimizations. */
+# ifndef PSTMNT_EXPECT
+# ifdef __GNUC__
+# define PSTMNT_EXPECT(value, usual_value) __builtin_expect(value, (usual_value))
+# else /* !__GNUC__ */
+# define PSTMNT_EXPECT(value, usual_value) (value)
+# endif /* __GNUC__ */
+# endif /* PSTMNT_EXPECT */
+
+/* Rename standard C API function calls.
+ (allows easy substitution with alternatives in non-standard C libraries.). */
+# ifndef PSTMNT_COPY
+# define PSTMNT_COPY(ptr_d, ptr, sz) memcpy((ptr_d), (ptr), (sz))
+# endif /* PSTMNT_COPY */
+# ifndef PSTMNT_MOVE
+# define PSTMNT_MOVE(ptr_d, ptr, sz) memmove((ptr_d), (ptr), (sz))
+# endif /* PSTMNT_MOVE */
+# ifndef PSTMNT_ZEROIZE
+# define PSTMNT_ZEROIZE(ptr, sz) memset((ptr), 0, (sz))
+# endif /* PSTMNT_ZEROIZE */
+
+/* Basic mathematics operations - inlined or macro. */
+# define PSTMNT_WORD_NEGATE(x) ((~((pstmnt_word) (x))) + 1)
+# define PSTMNT_WORD_BITS_M1 31
+# define PSTMNT_WORD_HIGH_BIT (1U << (PSTMNT_WORD_BITS_M1))
+# define PSTMNT_WORDS_TO_BITS(in) ((in) * 32)
+# define pstmnt_is_zero(w, n) (pstmnt_get_num_bits((w), (n)) == 0)
+# define pstmnt_is_one(w, n) (pstmnt_get_num_bits((w), (n)) == 1)
+# define pstmnt_is_even(w, n) (n == 0 || (w[0] & 1) == 0)
+# define pstmnt_is_odd(w, n) (n > 0 && (w[0] & 1) == 1)
+# define pstmnt_clear(r_, n_) (void) PSTMNT_ZEROIZE((r_), (n_) * sizeof(pstmnt_word))
+# define pstmnt_extend(r, n1, n2) pstmnt_clear((r) + (n1), (n2) - (n1))
+# define pstmnt_copy(a, r, n) (void) PSTMNT_COPY((r), (a), (n) * sizeof(pstmnt_word))
+# define pstmnt_reduce(a, p, r, t, n) pstmnt_reduce2(a, p, r, NULL, t, n)
+# define PSTMNT_UINT32 uint32_t
+# define PSTMNT_UINT64 uint64_t
+
+/* Determine platform and configure accordingly. */
+
+# define PSTMNT_NO_KARATSUBA
+# if defined(__LP64__) || defined(_LP64)
+/* X86 or ARM64: Use 128-bit integers where available. */
+# define PSTMNT_USE_INT128
+# define PSTMNT_USE_INT128
+# define PSTMNT_USE_INT128_SQUARE
+# define PSTMNT_USE_INT128_MULT
+# define PSTMNT_USE_INT128_MONTGOMERY
+# endif /* __LP64__ */
+
+# ifdef __i386__
+/* Note: on X86 we must enable inline assembly: to make sure the C compiler
+ does not use __udivdi3, __umoddi3 functions. */
+# define PSTMNT_USE_X86_ASSEMBLY
+# endif /* __i386__ */
+
+# ifdef __thumb2__
+/* Optional assembly optimizations for ARMv7 with Thumb-2. */
+# ifndef PSTMNT_OMIT_ASSEMBLY_OPTIMIZATIONS
+# define PSTMNT_USE_THUMB2_ASSEMBLY
+# endif /* PSTMNT_OMIT_ASSEMBLY_OPTIMIZATIONS */
+# endif /* __thumb2__ */
+
+# if __arm__
+/* Optional assembly optimizations for ARM
+ (note: also Thumb-2, above, may be in effect). */
+# ifndef PSTMNT_OMIT_ASSEMBLY_OPTIMIZATIONS
+# define PSTMNT_USE_ARM_ASSEMBLY
+# endif /* PSTMNT_OMIT_ASSEMBLY_OPTIMIZATIONS */
+# endif /* __arm__ */
+
+/* --- low-level mathematics operations --- */
+
+# ifdef PSTMNT_USE_X86_ASSEMBLY
+/* Optimized versions for macros for Intel x86 architecture based
+ platforms. (Only for GCC compiler.) */
+
+/* Replace contents of count with number of leading zeros in x.
+ Both count and x are 32-bit unsigned values. */
+# define PSTMNT_COUNT_LEADING_ZEROS(count, x) \
+ __asm__("bsrl %1,%0; xorl $31, %0" : \
+ "=r" (count) : "rm" ((pstmnt_word) (x)))
+
+/* Replace contents of count with number of trailing zeros in x.
+ Both count and x are 32-bit unsigned values. */
+# define PSTMNT_COUNT_TRAILING_ZEROS(count, x) \
+ __asm__("bsfl %1,%0" : \
+ "=r" (count) : "rm" ((pstmnt_word) (x)))
+
+# ifndef PSTMNT_LONG_MUL_GENERIC
+/* Multiply a and b, produce result u:v. Where u is 32 high order bits of
+ the result and v are the 32 low order bits of the result.
+ All parameters are 32-bit unsigned integers. */
+# define PSTMNT_LONG_MUL(u, v, a, b) \
+ __asm__("mull %3" \
+ : "=a" ((pstmnt_word) v), \
+ "=d" ((pstmnt_word) u) \
+ : "0" ((pstmnt_word) a), \
+ "rm" ((pstmnt_word) b))
+# endif /* PSTMNT_LONG_MUL_GENERIC */
+
+/* {u:v} = {u:v} + c1 + c2
+ Add 32-bit values c1 and c2 to 64-bit value represented by {u:v},
+ where u has 32 highest bits of the value and v has 32 lowest bits of
+ the values.
+ All parameters (u, v, c1, c2) are 32-bit integers. */
+# define PSTMNT_LONG_ADD32_32(u, v, c1, c2) \
+ __asm__("addl %4,%0\nadcl $0,%1\n\taddl %5,%0\n\tadcl $0,%1" \
+ : "=&r" ((pstmnt_word) v), \
+ "=&r" ((pstmnt_word) u) \
+ : "0" ((pstmnt_word) v), \
+ "1" ((pstmnt_word) u), \
+ "rm" ((pstmnt_word) c1), \
+ "rm" ((pstmnt_word) c2))
+
+/* {u:v} = {u:v} + c1 + c2
+ Add 32-bit values c1 and c2 to 64-bit value represented by {u:v},
+ where u has 32 highest bits of the value and v has 32 lowest bits of
+ the values.
+ All parameters (u, v, c1, c2) are 32-bit integers.
+ For this function, value c2 is constrained to be either 0 or 1, for
+ any other values of c2, result of the function is undefined. */
+# define PSTMNT_LONG_ADD32_1(u, v, c1, c2) \
+ do { uint32_t c2_shift; \
+ __asm__("rcrl $1,%6\n\tadcl %5,%0\n\tadcl $0,%1" \
+ : "=&r" ((pstmnt_word) v), \
+ "=r" ((pstmnt_word) u), \
+ "=&r" ((pstmnt_word) c2_shift) \
+ : "0" ((pstmnt_word) v), \
+ "1" ((pstmnt_word) u), \
+ "rm" ((pstmnt_word) c1), \
+ "2" ((pstmnt_word) c2)); \
+ } while (0)
+
+/* {u:v} = {u:v} + c
+ Add 32-bit c to 64-bit value represented by {u:v},
+ All parameters (u, v, c) are 32-bit integers.
+ */
+# define PSTMNT_LONG_ADD32(u, v, c) \
+ __asm__("addl %4,%0\n\tadcl $0,%1" \
+ : "=&r" ((pstmnt_word) v), \
+ "=r" ((pstmnt_word) u) \
+ : "0" ((pstmnt_word) v), \
+ "1" ((pstmnt_word) u), \
+ "rm" ((pstmnt_word) c))
+
+/* Same as PSTMNT_LONG_MUL, but additional parameter with 32-bit value c
+ is added to result of the multiplication. */
+# define PSTMNT_LONG_MUL_ADD32(u, v, a, b, c) \
+ do { PSTMNT_LONG_MUL(u, v, a, b); PSTMNT_LONG_ADD32(u, v, c); } while (0)
+
+/* Divide 64-bit value represented by {d1:d0} with 32-bit value d.
+ 32-bit result is returned as q, and remainder is returned as r.
+ The behavior is undefined if d is not defined or if the result of
+ operation does not fit in q. */
+# define PSTMNT_LONG_DIV(q, r, d1, d0, d) \
+ __asm__("divl %4" \
+ : "=a" ((pstmnt_word) q), \
+ "=d" ((pstmnt_word) r) \
+ : "0" ((pstmnt_word) d0), \
+ "1" ((pstmnt_word) d1), \
+ "rm" ((pstmnt_word) d))
+
+# elif defined PSTMNT_USE_ARM_ASSEMBLY
+/* Assembly optimizations for ARMv7 with and without Thumb-2. */
+
+/* {u:v} = {u:v} + b*a
+ Set 64-bit result of multiplication of 32-bit integers to
+ 64-bit value represented by {u:v},
+ All parameters (u, v, b, a) are 32-bit integers.
+ */
+# ifndef PSTMNT_LONG_MUL_GENERIC
+# define PSTMNT_LONG_MUL(u, v, a, b) \
+ __asm__("umull %0, %1, %2, %3" : "=r" (v), "=r" (u) : "r" (a), "r" (b))
+# endif /* PSTMNT_LONG_MUL_GENERIC */
+
+/* {u:v} = {u:v} + b*a
+ Add 64-bit result of multiplication of 32-bit integers to
+ 64-bit value represented by {u:v},
+ All parameters (u, v, b, a) are 32-bit integers.
+ */
+# define PSTMNT_LONG_MULADD(u, v, b, a) \
+ __asm__("umlal %0,%1,%2,%3" : \
+ "=r" (v), "=r" (u) : \
+ "r" (a), "r" (b), "0" (v), "1" (u))
+
+/* {u:v} = u + v + b*a
+ Add 64-bit result of multiplication of 32-bit integers to
+ 32-bit values represented by u and v, return 64-bit result
+ in {u:v}.
+ All parameters (u, v, b, a) are 32-bit integers.
+ */
+# ifdef __ARM_ARCH_7A__
+# define PSTMNT_LONG_MULADD2(u, v, b, a) \
+ __asm__("umaal %0,%1,%2,%3" : \
+ "=r" (v), "=r" (u) : \
+ "r" (a), "r" (b), "0" (v), "1" (u) : "cc")
+# else
+/* avoid umaal instruction. */
+# define PSTMNT_LONG_MULADD2(u, v, b, a) \
+ do { PSTMNT_LONG_ADD32_32_TO_33(u, v, u, v); \
+ PSTMNT_LONG_MULADD(u, v, b, a); } while (0)
+# endif
+
+# ifdef __ARM_ARCH_7A__
+/* PSTMNT_LONG_MULADD2 is fast enough to substitute much of usual integer
+ addition arithmetics (it can be used as add 3x32 => 64bit result.) */
+# define PSTMNT_LONG_MULADD2_FAST PSTMNT_LONG_MULADD2
+# endif /* __ARM_ARCH_7A__ */
+
+/* {uu} += u_new < u_old
+ Handle carries: increment uu if increment of u_old
+ to u_new caused overflow.
+ All parameters (uu, u_new, u_old) are 32-bit integers.
+ */
+# define PSTMNT_LONG_CARRY(uu, u_new, u_old) \
+ __asm__("cmp %1, %2\n\t" \
+ "it lo\n\t" \
+ "addlo %0, %3, #1" \
+ : "=&r" (uu) : "r" (u_new), "r" (u_old), "0" (uu) : "cc")
+
+/* {uu:u:v} = {uu:u:v} + b*a
+ Add 64-bit result of multiplication of 32-bit integers to
+ 96-bit value represented by {uu:u:v},
+ All parameters (uu, u, v, b, a) are 32-bit integers.
+ */
+# define PSTMNT_LONG_MULADD_CARRY(uu, u, v, b, a) \
+ do { unsigned int u_old = (u); \
+ PSTMNT_LONG_MULADD(u, v, b, a); \
+ PSTMNT_LONG_CARRY(uu, (u), u_old); \
+ } while (0)
+
+/* {u:v} = {u:v} + c1 */
+# define PSTMNT_LONG_ADD32(u, v, c) \
+ __asm__("adds %0, %0, %3\n\tadc %1, %2, #0" : \
+ "+&r" (v), "=r" (u) : \
+ "r" (u), "rI" (c) : "cc")
+
+/* {hi:u:v} = {u:v} + {u2:v2} */
+# define PSTMNT_LONG_ADD64_CARRY(hi, u, v, u2, v2) \
+ __asm__("adds %0, %0, %3\n\tadcs %1, %1, %4\n\tadc %2, %2, #0" : \
+ "+&r" (v), "+&r" (u), "+r" (hi) : \
+ "r" (v2), "r" (u2) : "cc")
+
+
+# ifdef PSTMNT_ARMV7
+/* {u:v} = a + b */
+# define PSTMNT_LONG_ADD32_32_TO_33(u, v, a, b) \
+ __asm__("adds %0, %2, %3\n\tsbc.w %1, %1, %1\n\tadd %1, %1, #1" : \
+ "=&r" (v), "=r" (u) : \
+ "r" (a), "r" (b) : "cc")
+# endif /* PSTMNT_ARMV7 */
+# ifndef PSTMNT_LONG_ADD32_32_TO_33
+# define PSTMNT_LONG_ADD32_32_TO_33(u, v, a, b) \
+ do { \
+ unsigned int b_in = (b); \
+ v = (a) + b_in; \
+ u = (v < b_in); /* Check carry. */ \
+ } while (0)
+# endif /* PSTMNT_LONG_ADD32_32_TO_33 */
+
+/* {u:v} = {u:v} + c1 + c2.
+ All parameters except c2 are 32-bit integers. c2 is either 0 or 1. */
+# define PSTMNT_LONG_ADD32_1(u, v, c1, c2) \
+ __asm__("cmn %5, #0xffffffff\n\t" \
+ "adcs %0, %2, %4\n\tadc %1, %3, #0" : \
+ "=&r" (v), "=r" (u) : \
+ "r" (v), "r" (u), "rI" (c1), "r" (c2) : "cc")
+
+# endif /* Switch: platform specific assembly optimizations. */
+
+# ifdef PSTMNT_LONG_MULADD_GENERIC
+/* Provide PSTMNT_LONG_MULADD and others as generic variants.
+ This'll make some compilers use paths optimized for fused-multiply-add
+ instruction, which often is faster, at least on platforms with many
+ registers. */
+
+# ifndef PSTMNT_LONG_ADD32_32_TO_33
+# define PSTMNT_LONG_ADD32_32_TO_33(u, v, a, b) \
+ do { \
+ unsigned int b_in = (b); \
+ v = (a) + b_in; \
+ u = (v < b_in); /* Check carry. */ \
+ } while (0)
+# endif /* PSTMNT_LONG_ADD32_32_TO_33 */
+
+# ifndef PSTMNT_LONG_LEFT_SHIFT96_1
+/* {c,b,a} = {c,b,a} + {c,b,a} */
+# define PSTMNT_LONG_LEFT_SHIFT96_1(c, b, a) \
+ do { \
+ c = ((c) << 1) | ((b) >> 31); \
+ b = ((b) << 1) | ((a) >> 31); \
+ a = (a) << 1; \
+ } while (0)
+# endif /* PSTMNT_LONG_SHIFT96_1 */
+
+# ifndef PSTMNT_LONG_ADD64
+# define PSTMNT_LONG_ADD64(u, v, b, a) \
+ do { \
+ PSTMNT_UINT64 uv; \
+ PSTMNT_UINT64 ba; \
+ uv = (((PSTMNT_UINT64) u) << 32) | v; \
+ ba = (((PSTMNT_UINT64) b) << 32) | a; \
+ uv += ba; \
+ u = (PSTMNT_UINT32) (uv >> 32); \
+ v = (PSTMNT_UINT32) (uv); \
+ } while (0)
+# endif /* PSTMNT_LONG_ADD64 */
+
+# ifndef PSTMNT_LONG_ADD32
+# define PSTMNT_LONG_ADD32(u, v, a) PSTMNT_LONG_ADD64(u, v, 0, a)
+# endif /* PSTMNT_LONG_ADD32 */
+
+# ifndef PSTMNT_LONG_ADD64_CARRY
+# define PSTMNT_LONG_ADD64_CARRY(uu, u, v, b, a) \
+ do { \
+ PSTMNT_UINT64 uv; \
+ PSTMNT_UINT64 ba; \
+ uv = (((PSTMNT_UINT64) u) << 32) | v; \
+ ba = (((PSTMNT_UINT64) b) << 32) | a; \
+ uv += ba; \
+ if (uv < ba) { uu++; /* Carry handling. */ \
+ } \
+ u = (PSTMNT_UINT32) (uv >> 32); \
+ v = (PSTMNT_UINT32) (uv); \
+ } while (0)
+# endif /* PSTMNT_LONG_ADD64_CARRY */
+
+# ifndef PSTMNT_LONG_MULADD
+# define PSTMNT_LONG_MULADD(u, v, b, a) \
+ do { unsigned int ut, vt; \
+ PSTMNT_LONG_MUL(ut, vt, b, a); \
+ PSTMNT_LONG_ADD64(u, v, ut, vt); \
+ } while (0)
+# endif /* PSTMNT_LONG_MULADD */
+
+/* {u:v} = u + v + b*a
+ Add 64-bit result of multiplication of 32-bit integers to
+ 32-bit values represented by u and v, return 64-bit result
+ in {u:v}.
+ All parameters (u, v, b, a) are 32-bit integers.
+ */
+# ifndef PSTMNT_LONG_MULADD2
+# define PSTMNT_LONG_MULADD2(u, v, b, a) \
+ do { \
+ pstmnt_dword uv; \
+ pstmnt_dword ba; \
+ uv = ((pstmnt_dword) u) + v; \
+ ba = ((pstmnt_dword) b) * a; \
+ uv += ba; \
+ u = (pstmnt_word) (uv >> 32); \
+ v = (pstmnt_word) (uv); \
+ } while (0)
+# endif /* PSTMNT_LONG_MULADD2 */
+
+# ifndef PSTMNT_LONG_MULADD_CARRY
+# define PSTMNT_LONG_MULADD_CARRY(uu, u, v, b, a) \
+ do { pstmnt_word uo = u; \
+ pstmnt_dword uv; \
+ pstmnt_dword ba; \
+ uv = (((pstmnt_dword) u) << 32) | v; \
+ ba = ((pstmnt_dword) b) * a; \
+ uv += ba; \
+ u = (pstmnt_word) (uv >> 32); \
+ v = (pstmnt_word) (uv); \
+ uu += (u < uo); /* Carry handling. */ \
+ } while (0)
+# endif /* PSTMNT_LONG_MULADD_CARRY */
+
+# endif /* Switch: platform specific assembly optimizations. */
+
+# ifndef PSTMNT_LONG_ADD64_CARRY
+# define PSTMNT_LONG_ADD64_CARRY(uu, u, v, b, a) \
+ do { \
+ PSTMNT_UINT64 uv; \
+ PSTMNT_UINT64 ba; \
+ uv = (((PSTMNT_UINT64) u) << 32) | v; \
+ ba = (((PSTMNT_UINT64) b) << 32) | a; \
+ uv += ba; \
+ uu += (uv < ba); /* Carry handling. */ \
+ u = (PSTMNT_UINT32) (uv >> 32); \
+ v = (PSTMNT_UINT32) (uv); \
+ } while (0)
+# endif /* PSTMNT_LONG_ADD64_CARRY */
+
+# ifndef PSTMNT_LONG_LEFT_SHIFT96_1
+/* {c,b,a} = {c,b,a} + {c,b,a} */
+# define PSTMNT_LONG_LEFT_SHIFT96_1(c, b, a) \
+ do { \
+ c = ((c) << 1) | ((b) >> 31); \
+ b = ((b) << 1) | ((a) >> 31); \
+ a = (a) << 1; \
+ } while (0)
+# endif /* PSTMNT_LONG_LEFT_SHIFT96_1 */
+
+static
+inline
+uint32_t
+pstmnt_pop_count(uint32_t Value)
+{
+ /* Reduce bits into counts. */
+ Value -= ((Value >> 1) & 0x55555555);
+ Value = ((Value >> 2) & 0x33333333) + (Value & 0x33333333);
+ Value = ((Value >> 4) + Value); /* Upper nibbles of each byte are
+ garbage. */
+# if defined(__ARM_ARCH_7A__) && defined(PSTMNT_USE_ARM_ASSEMBLY)
+ /* Combine results with usad8, use subtraction to ignore
+ garbage bits. */
+ __asm__("usad8 %0, %1, %2" : "=r" (Value) : "r" (Value),
+ "r" (Value & 0xf0f0f0f0));
+ return Value;
+# else /* Not ARM ARCH 7-A. */
+ /* Reduce bits into counts. */
+ Value &= 0x0f0f0f0f;
+ Value += (Value >> 8);
+ Value += (Value >> 16);
+ return Value & 0x0000003f;
+# endif /* defined(__ARM_ARCH_7A__) && defined(PSTMNT_USE_ARM_ASSEMBLY) */
+}
+
+static
+inline
+uint32_t
+pstmnt_ffsV(const uint32_t Value)
+{
+ /* Get least significant 1 bit (or 0 if Value is zero.) */
+ return Value & - Value;
+}
+
+# ifdef PSTMNT_USE_GCC_BUILTIN_CTZ
+# ifndef PSTMNT_COUNT_TRAILING_ZEROS
+# define PSTMNT_COUNT_TRAILING_ZEROS(count, x) \
+ count = (uint32_t) __builtin_ctz((uint32_t) x)
+# endif /* PSTMNT_COUNT_TRAILING_ZEROS */
+# endif /* PSTMNT_USE_GCC_BUILTIN_CTZ */
+
+# ifndef PSTMNT_COUNT_TRAILING_ZEROS
+static
+inline
+uint32_t
+pstmnt_ffs__minus1(uint32_t Value)
+{
+ /* OPTN: This algorithm has three SWAR operations, likely it is
+ possible to just use two, like PSTMNT_COUNT_LEADING_ZEROS. */
+ Value = pstmnt_ffsV(Value);
+ /* Decrement 1 from highest bit set to get mask with all bits prior
+ the highest valued bit set.
+ Note: possible wraparound makes the value 0xFFFFFFFFU. */
+ Value--;
+
+ /* Construct mask, starting from the lowest bit. */
+ Value |= (Value >> 1);
+ Value |= (Value >> 2);
+ Value |= (Value >> 4);
+ Value |= (Value >> 8);
+ Value |= (Value >> 16);
+
+ /* Calculate bits within the mask, return 0 when mask is full of ones. */
+ return pstmnt_pop_count(Value) & 31;
+}
+
+# define PSTMNT_COUNT_TRAILING_ZEROS(count, x) count = pstmnt_ffs__minus1(x)
+# endif /* !PSTMNT_COUNT_TRAILING_ZEROS */
+
+# ifdef PSTMNT_USE_GCC_BUILTIN_CLZ
+# ifndef PSTMNT_COUNT_LEADING_ZEROS
+# define PSTMNT_COUNT_LEADING_ZEROS(count, x) \
+ count = (uint32_t) __builtin_clz((uint32_t) x)
+# endif /* PSTMNT_COUNT_LEADING_ZEROS */
+# endif /* PSTMNT_USE_GCC_BUILTIN_CLZ */
+
+# ifndef PSTMNT_COUNT_LEADING_ZEROS
+static
+inline
+uint32_t
+pstmnt_lzc(uint32_t Value)
+{
+ /* Create mask with all bits starting from first set bit set. */
+ Value |= (Value >> 1);
+ Value |= (Value >> 2);
+ Value |= (Value >> 4);
+ Value |= (Value >> 8);
+ Value |= (Value >> 16);
+
+ /* Calculate population count, return 0 when mask is full of ones. */
+ return (32 - pstmnt_pop_count(Value)) & 31;
+}
+
+# define PSTMNT_COUNT_LEADING_ZEROS(count, x) count = pstmnt_lzc(x)
+# endif /* PSTMNT_COUNT_LEADING_ZEROS */
+
+# ifndef PSTMNT_LONG_MUL
+/* Define generic version of PSTMNT_LONG_MUL if no specific
+ instruction/instruction sequence is available. */
+static
+inline
+void
+pstmnt_parse__uint64(uint64_t InputBits,
+ uint32_t * const HighBits_p,
+ uint32_t * const LowBits_p)
+{
+ *HighBits_p = (uint32_t) (InputBits >> 32);
+ *LowBits_p = (uint32_t) (InputBits & 0xFFFFFFFFUL);
+}
+
+# define PSTMNT_LONG_MUL(u, v, a, b) \
+ pstmnt_parse__uint64(((uint64_t) (a)) * (b), (&(u)), (&(v)))
+# endif /* !PSTMNT_LONG_MUL */
+
+# ifndef PSTMNT_LONG_DIV
+# ifndef __arm__
+/* Use simple inline function for long division. */
+static inline
+void
+pstmnt_long_div(uint32_t *q_p, uint32_t *r_p,
+ uint32_t d1, uint32_t d0, uint32_t Divisor)
+{
+ uint32_t q = (uint32_t) (((((uint64_t) d1) << 32) | d0) / Divisor);
+ uint32_t r = (uint32_t) (((((uint64_t) d1) << 32) | d0) % Divisor);
+
+ *q_p = q;
+ *r_p = r;
+}
+# else
+/* On ARM, pstmnt_long_div implemented in fl-deps.c.
+ This is because in ARM the CPU instruction does not have neccessary
+ division instruction, but long division is processed by the platform ABI. */
+void
+pstmnt_long_div(uint32_t *q_p, uint32_t *r_p,
+ uint32_t d1, uint32_t d0, uint32_t Divisor);
+# endif
+
+# define PSTMNT_LONG_DIV(q, r, d1, d0, d) \
+ pstmnt_long_div(&(q), &(r), d1, d0, d)
+# endif /* !PSTMNT_LONG_DIV */
+
+# ifndef PSTMNT_USE_GCC_BUILTIN_BSWAP32
+static
+inline
+uint32_t
+pstmnt_reverse_bytes32(uint32_t Value)
+{
+ Value = (((Value & 0xff00ff00U) >> 8) | ((Value & 0x00ff00ffU) << 8));
+ return (Value >> 16) | (Value << 16);
+}
+# else
+static
+inline
+uint32_t
+pstmnt_reverse_bytes32(uint32_t Value)
+{
+ return __builtin_bswap32(Value);
+}
+# endif /* PSTMNT_USE_GCC_BUILTIN_BSWAP32 */
+
+# ifndef PSTMNT_USE_GCC_BUILTIN_BSWAP64
+static
+inline
+uint64_t
+pstmnt_reverse_bytes64(uint64_t Value)
+{
+ Value = (((Value & 0xff00ff00ff00ff00ULL) >> 8) |
+ ((Value & 0x00ff00ff00ff00ffULL) << 8));
+ Value = (((Value & 0xffff0000ffff0000ULL) >> 16) |
+ ((Value & 0x0000ffff0000ffffULL) << 16));
+ return (Value >> 32) | (Value << 32);
+}
+# else
+static
+inline
+uint64_t
+pstmnt_reverse_bytes64(uint64_t Value)
+{
+ return __builtin_bswap64(Value);
+}
+# endif /* PSTMNT_USE_GCC_BUILTIN_BSWAP64 */
+
+# ifdef PSTMNT_USE_INT128
+typedef struct
+{
+ uint64_t value;
+} __attribute__((__packed__, __aligned__(4))) pstmnt_uint64_aligned4_t;
+
+__extension__ typedef unsigned __int128 pstmntDD_word;
+
+# ifndef PSTMNT_VERYLONG_MULADD_CARRY
+# define PSTMNT_VERYLONG_MULADD_CARRY(uu, u, v, b, a) \
+ do { pstmnt_dword uo = u; \
+ pstmntDD_word uv; \
+ pstmntDD_word ba; \
+ uv = (((pstmntDD_word) u) << 64) | v; \
+ ba = ((pstmntDD_word) b) * a; \
+ uv += ba; \
+ u = (pstmnt_dword) (uv >> 64); \
+ v = (pstmnt_dword) (uv); \
+ uu += (u < uo); /* Carry handling. */ \
+ } while (0)
+# endif /* PSTMNT_VERYLONG_MULADD_CARRY */
+
+# ifndef PSTMNT_VERYLONG_MULADD2
+# define PSTMNT_VERYLONG_MULADD2(u, v, b, a) \
+ do { \
+ pstmntDD_word uv; \
+ pstmntDD_word ba; \
+ uv = ((pstmntDD_word) u) + v; \
+ ba = ((pstmntDD_word) b) * a; \
+ uv += ba; \
+ u = (pstmnt_dword) (uv >> 64); \
+ v = (pstmnt_dword) (uv); \
+ } while (0)
+# endif /* PSTMNT_VERYLONG_MULADD2 */
+
+# ifndef PSTMNT_VERYLONG_ADD128_CARRY
+# define PSTMNT_VERYLONG_ADD128_CARRY(uu, u, v, b, a) \
+ do { \
+ pstmntDD_word uv; \
+ pstmntDD_word ba; \
+ uv = (((pstmntDD_word) u) << 64) | v; \
+ ba = (((pstmntDD_word) b) << 64) | a; \
+ uv += ba; \
+ uu += (uv < ba); /* Carry handling. */ \
+ u = (pstmntDD_word) (uv >> 64); \
+ v = (pstmntDD_word) (uv); \
+ } while (0)
+# endif /* PSTMNT_VERYLONG_ADD128_CARRY */
+# endif /* PSTMNT_USE_INT128 */
+
+# ifndef PSTMNT_VERYLONG_LEFT_SHIFT192_1
+/* {c,b,a} = {c,b,a} + {c,b,a} */
+# define PSTMNT_VERYLONG_LEFT_SHIFT192_1(c, b, a) \
+ do { \
+ c = ((c) << 1) | ((b) >> 63); \
+ b = ((b) << 1) | ((a) >> 63); \
+ a = (a) << 1; \
+ } while (0)
+# endif /* PSTMNT_VERYLONG_SHIFT192_1 */
+
+# ifndef __PLATFORM_HAS_SPECIAL_DIV_MOD_U32__
+/* Macros for division/modulo. (For the most platforms.) */
+# define PSTMNT_DIV_U32(a, b) ((a) / (b))
+# define PSTMNT_MOD_U32(a, b) ((a) % (b))
+# endif /* __PLATFORM_HAS_SPECIAL_DIV_MOD_U32__ */
+
+/* Logic to map square and multiplication functions to implementations.
+ Occasionally it is better to invoke pstm_*_comba.
+ Occasionally square is not individually defined and it needs to map to
+ multiplication.
+ */
+
+/* Create "wrapper" pstm_int's for memory arrays.
+ These can be used by pstm_*_comba functions but these are not safe for
+ all pstm functions. These wrappers shall not be freed or resized. */
+# define PSTM_INT_UNSIGNED_MEM(ptr_uint32, sz_digits) \
+ { \
+ (pstm_digit *) (const pstm_digit *) (ptr_uint32), \
+ (psPool_t *) (void *) 1UL, \
+ (sz_digits), \
+ (sz_digits), \
+ PSTM_ZPOS \
+ }
+
+/* Use pstm_sqr_comba if compiled in and suitable size variant is available. */
+__inline static int
+pstmnt_square_comba(
+ const uint32_t a[],
+ uint32_t * restrict r,
+ int sz)
+{
+# ifndef PSTMNT_NO_COMBA
+# if PSTMNT_WORD_BITS == 32
+# if DIGIT_BIT == 64 && defined(USE_1024_KEY_SPEED_OPTIMIZATIONS)
+ if (sz == 32)
+ {
+ pstm_int a_wrap = PSTM_INT_UNSIGNED_MEM(a, 16);
+ pstm_int r_wrap = PSTM_INT_UNSIGNED_MEM(r, 32);
+ int32_t res = pstm_sqr_comba(NULL, &a_wrap, &r_wrap, NULL, 0);
+ return res == PSTM_OKAY;
+ }
+# endif
+# if DIGIT_BIT == 64 && defined(USE_2048_KEY_SPEED_OPTIMIZATIONS)
+ if (sz == 64)
+ {
+ pstm_int a_wrap = PSTM_INT_UNSIGNED_MEM(a, 32);
+ pstm_int r_wrap = PSTM_INT_UNSIGNED_MEM(r, 64);
+ int32_t res = pstm_sqr_comba(NULL, &a_wrap, &r_wrap, NULL, 0);
+ return res == PSTM_OKAY;
+ }
+# endif
+# if DIGIT_BIT == 32 && defined(USE_1024_KEY_SPEED_OPTIMIZATIONS)
+ if (sz == 16)
+ {
+ pstm_int a_wrap = PSTM_INT_UNSIGNED_MEM(a, 16);
+ pstm_int r_wrap = PSTM_INT_UNSIGNED_MEM(r, 32);
+ int32_t res = pstm_sqr_comba(NULL, &a_wrap, &r_wrap, NULL, 0);
+ return res == PSTM_OKAY;
+ }
+# endif
+# if DIGIT_BIT == 32 && defined(USE_2048_KEY_SPEED_OPTIMIZATIONS)
+ if (sz == 32)
+ {
+ pstm_int a_wrap = PSTM_INT_UNSIGNED_MEM(a, 32);
+ pstm_int r_wrap = PSTM_INT_UNSIGNED_MEM(r, 64);
+ int32_t res = pstm_sqr_comba(NULL, &a_wrap, &r_wrap, NULL, 0);
+ return res == PSTM_OKAY;
+ }
+# endif
+# endif /* PSTMNT_WORD_BITS == 32 */
+# endif /* !PSTMNT_NO_COMBA */
+ return 0;
+}
+
+__inline static int
+pstmnt_mult_comba(
+ const uint32_t a[],
+ const uint32_t b[],
+ uint32_t * restrict r,
+ int sz)
+{
+# ifndef PSTMNT_NO_COMBA
+# if PSTMNT_WORD_BITS == 32
+# if DIGIT_BIT == 64 && defined(USE_1024_KEY_SPEED_OPTIMIZATIONS)
+ if (sz == 32)
+ {
+ pstm_int a_wrap = PSTM_INT_UNSIGNED_MEM(a, 16);
+ pstm_int b_wrap = PSTM_INT_UNSIGNED_MEM(b, 16);
+ pstm_int r_wrap = PSTM_INT_UNSIGNED_MEM(r, 32);
+ int32_t res = pstm_mul_comba(NULL, &a_wrap, &b_wrap, &r_wrap, NULL, 0);
+ return res == PSTM_OKAY;
+ }
+# endif
+# if DIGIT_BIT == 64 && defined(USE_2048_KEY_SPEED_OPTIMIZATIONS)
+ if (sz == 64)
+ {
+ pstm_int a_wrap = PSTM_INT_UNSIGNED_MEM(a, 32);
+ pstm_int b_wrap = PSTM_INT_UNSIGNED_MEM(b, 32);
+ pstm_int r_wrap = PSTM_INT_UNSIGNED_MEM(r, 64);
+ int32_t res = pstm_mul_comba(NULL, &a_wrap, &b_wrap, &r_wrap, NULL, 0);
+ return res == PSTM_OKAY;
+ }
+# endif
+# if DIGIT_BIT == 32 && defined(USE_1024_KEY_SPEED_OPTIMIZATIONS)
+ if (sz == 16)
+ {
+ pstm_int a_wrap = PSTM_INT_UNSIGNED_MEM(a, 16);
+ pstm_int b_wrap = PSTM_INT_UNSIGNED_MEM(b, 16);
+ pstm_int r_wrap = PSTM_INT_UNSIGNED_MEM(r, 32);
+ int32_t res = pstm_mul_comba(NULL, &a_wrap, &b_wrap, &r_wrap, NULL, 0);
+ return res == PSTM_OKAY;
+ }
+# endif
+# if DIGIT_BIT == 32 && defined(USE_2048_KEY_SPEED_OPTIMIZATIONS)
+ if (sz == 32)
+ {
+ pstm_int a_wrap = PSTM_INT_UNSIGNED_MEM(a, 32);
+ pstm_int b_wrap = PSTM_INT_UNSIGNED_MEM(b, 32);
+ pstm_int r_wrap = PSTM_INT_UNSIGNED_MEM(r, 64);
+ int32_t res = pstm_mul_comba(NULL, &a_wrap, &b_wrap, &r_wrap, NULL, 0);
+ return res == PSTM_OKAY;
+ }
+# endif
+# endif /* PSTMNT_WORD_BITS == 32 */
+# endif /* !PSTMNT_NO_COMBA */
+ return 0;
+}
+
+void
+pstmnt_mult(
+ const uint32_t a[],
+ const uint32_t b[],
+ uint32_t * restrict r,
+ int sz);
+
+# if defined(PSTMNT_LONG_MULADD_CARRY) || defined PSTMNT_USE_INT128_SQUARE
+/* Use optimized square function */
+void
+pstmnt_square(
+ const uint32_t a[],
+ uint32_t * restrict r,
+ int sz);
+# else
+/* Apply the generic pstmnt_mult() function for square. */
+
+void
+pstmnt_square(
+ const uint32_t a[],
+ uint32_t * restrict r,
+ int sz)
+{
+ if (pstmnt_square_comba(a, r, sz))
+ {
+ return;
+ }
+
+ /* No square function, just use multiplier. */
+ pstmnt_mult(a, a, r, n);
+}
+# endif
+
+/* --- actual high level functions --- */
+
+/* pstmnt_neg_small_inv is dependent on bits per word. */
+PSTMNT_COMPILE_ASSERT(PSTMNT_WORD_BITS == 32);
+
+/* Return -1 / a (mod 2^PSTMNT_WORD_BITS).
+ Note: The function is based on Newton iteration method.
+ The inverse only exists if x is odd.
+ The function shall not be passed even values as input.
+ The function has 4 rounds, test if flu.c ensures 4 rounds
+ is enough for all 32-bit values. */
+pstmnt_word pstmnt_neg_small_inv(const pstmnt_word *a_p)
+{
+ pstmnt_word a = *a_p;
+ pstmnt_word t, k;
+ int countdown = 4; /* Because of quadratic convergence, the
+ operation is always finished with up-to 4
+ steps [assuming pstmnt_word is 32-bit unsigned int].
+ */
+
+ PSTMNT_ASSERT((a & 1) == 1); /* Ensure value passed in is odd. */
+
+ /* This function uses the Newton's iteration to find
+ modular multiplicative inverse of given value in field mod 2^32.
+ Such value is needed e.g. in Montgomery Reduction.
+
+ Note on sequence used:
+ * Sequence (x_n+1 = x_n*(2 - a*x_n) (mod 2^k))
+ converges quadratically, iff a == a^-1 (mod 2).
+
+ It can be shown for this sequence that error converges.
+
+ Using a test in flu.c, it is ensured that the function operates
+ correctly for all odd values to converge between 1 and 2^32 - 1.
+ ATTN: Ensure the filename is updated if test is moved.
+
+ The reason to use static value 4 is that it makes the function
+ performance deterministic: function will execute the same operations
+ no matter what odd integer was passed in.
+ */
+ t = a;
+ while (countdown > 0)
+ {
+ k = 2 - (t * a);
+ t *= k;
+ countdown--;
+ }
+
+ PSTMNT_ASSERT(a * t == 1); /* Ensure t has been calculated correctly */
+ return PSTMNT_WORD_NEGATE(t); /* Return calculated t. */
+}
+
+static inline
+uint32_t add_carry_nt(uint32_t a, uint32_t b, psBool_t *carry)
+{
+ /* OPTN: If available, prefer PSTMNT_LONG_ADD32_32, PSTMNT_LONG_ADD32_1 etc. */
+ /* over this function. */
+ uint32_t res;
+ int c = *carry;
+
+ if (c)
+ {
+ res = a + b + 1;
+ *carry = res <= a;
+ }
+ else
+ {
+ res = a + b;
+ *carry = res < a;
+ }
+ return res;
+}
+
+/*
+ Addition of two big numbers. The numbers added shall be the same length.
+ If numbers are different length, the smaller number shall be extended
+ (pstmnt_extend) prior addition or the result of the addition shall be used as
+ carry, for pstmnt_add_1.
+
+ Operation: carry || r == a + b
+ The carry is returned from function,
+ The result is stored in r and operands for addition are read from
+ a and b.
+
+ Note: b shall not alias r.
+ */
+int pstmnt_add(const uint32_t *a, const uint32_t *b, uint32_t *r, int szl)
+{
+ /* Simple but slow addition function. */
+ psBool_t carry = PS_FALSE;
+
+ /* a may be same as r, but b may only be same as r if all
+ a, b and r are the same. */
+ PSTMNT_PRECONDITION((b != r) || (a == b));
+ PSTMNT_PRECONDITION(szl >= 1);
+ PSTMNT_PRECONDITION(szl <= 4096 / PSTMNT_WORD_BITS);
+
+# ifdef PSTMNT_LONG_MULADD2_FAST
+ /* Use MULADD2 to add two values and carry. */
+ {
+ uint32_t hi;
+ int i;
+
+ if (a != r)
+ {
+ pstmnt_copy(a, r, szl);
+ }
+
+ /* OPTN: Optimize this function even further. */
+ /* Duff's device (unrolling, calculate 4 words per loop iteration. */
+ {
+ register int n = (szl + 3) / 4;
+ int szl_mod4 = szl % 4;
+ hi = 0;
+ i = 0;
+ switch (PSTMNT_EXPECT(szl_mod4, 0))
+ {
+ case 0:
+ do
+ {
+ PSTMNT_LONG_MULADD2(hi, r[i], b[i], 1); i++;
+ case 3: PSTMNT_LONG_MULADD2(hi, r[i], b[i], 1); i++;
+ case 2: PSTMNT_LONG_MULADD2(hi, r[i], b[i], 1); i++;
+ case 1: PSTMNT_LONG_MULADD2(hi, r[i], b[i], 1); i++;
+ }
+ while (--n > 0);
+ }
+ }
+ carry = hi;
+ }
+# elif defined(PSTMNT_LONG_ADD32_1)
+ /* PSTMNT_LONG_ADD32_1 available. Use it. */
+ {
+ int i;
+ uint32_t hi1;
+ uint32_t hi2;
+
+ if (a != r)
+ {
+ pstmnt_copy(a, r, szl);
+ }
+
+ /* OPTN: Optimize this function even further. */
+ /* Duff's device (unrolling, calculate 4 words per loop iteration. */
+ {
+ register int n = (szl + 3) / 4;
+ hi1 = hi2 = 0;
+ i = 0;
+ switch (szl % 4)
+ {
+ case 0:
+ do
+ {
+ hi1 = 0; PSTMNT_LONG_ADD32_1(hi1, r[i], b[i], hi2); i++;
+ case 3: hi2 = 0; PSTMNT_LONG_ADD32_1(hi2, r[i], b[i], hi1); i++;
+ case 2: hi1 = 0; PSTMNT_LONG_ADD32_1(hi1, r[i], b[i], hi2); i++;
+ case 1: hi2 = 0; PSTMNT_LONG_ADD32_1(hi2, r[i], b[i], hi1); i++;
+ }
+ while (--n > 0);
+ }
+ }
+ carry = hi2;
+ }
+# else
+ while (szl > 0)
+ {
+ *r = add_carry_nt(*a, *b, &carry);
+ a++;
+ b++;
+ r++;
+ szl--;
+ }
+# endif
+ return carry;
+}
+
+# ifdef PSTMNT_USE_INT128_MONTGOMERY
+pstmnt_dword pstmnt_montgomery_reduce_d(PSTMNT_UINT64 * restrict temp_r,
+ pstmnt_word r[] /* n * 2 */,
+ const PSTMNT_UINT64 p[] /* n */,
+ pstmnt_word mp_,
+ pstmnt_words n)
+{
+ unsigned int i;
+ int j;
+ pstmnt_dword high_carry;
+ pstmnt_dword u, a1, c;
+ pstmnt_dword mp;
+
+ /* Construct 64-bit equivalent of 32-bit mp (on extra calculation step). */
+ mp = PSTMNT_WORD_NEGATE(mp_);
+ mp = mp * (2 - (mp * p[0]));
+ mp = ((~((pstmnt_dword) (mp))) + 1);
+
+ if (temp_r + n != (PSTMNT_UINT64 *) r)
+ {
+ PSTMNT_ZEROIZE(r, n * 8); /* Clear r. */
+ }
+
+ for (high_carry = 0, i = 0; i < n; i++)
+ {
+ pstmnt_dword d;
+ pstmnt_dword *array = &temp_r[i];
+ d = *array;
+ /* Calculate u and process the first 32 bits. */
+ u = d * mp;
+
+ /* Perform {c:d} = d + u * p[0] */
+ c = 0;
+ PSTMNT_VERYLONG_MULADD2(c, d, u, p[0]);
+ /* Note: the calculated value for d (which is always 0)
+ could be stored to temp_r[i] = d like this.
+ However, this is skipped as the cleared portion of temp_r
+ is not used after pstmnt_montgomery_reduce. */
+ for (j = 1; j < (int) n; j++)
+ {
+ a1 = array[j];
+ PSTMNT_VERYLONG_MULADD2(c, a1, u, p[j]);
+ array[j] = a1;
+ }
+
+ PSTMNT_VERYLONG_MULADD2(high_carry, c, array[j], 1);
+ array[j] = c;
+ }
+
+ /* Copy high portion, if required. */
+ if (temp_r + n != (PSTMNT_UINT64 *) r)
+ {
+ /* OPTN: It is may be possible to get rid of this copy operation
+ by reorganizing how this function works or is used. */
+ PSTMNT_COPY(r, temp_r + n, n * 8);
+ }
+
+ return high_carry;
+}
+# endif /* PSTMNT_USE_INT128_MONTGOMERY */
+
+# ifndef PSTMNT_LONG_MULADD_CARRY
+static inline
+void
+add64_to_96_nt(
+ const uint64_t a,
+ uint32_t r[3]) PSTMNT_HOT_FUNCTION;
+
+/* If Multiply-add with high carry handling is not available,
+ define this helper function. */
+static inline
+void
+add64_to_96_nt(
+ const uint64_t a,
+ uint32_t r[3])
+{
+ /* Use PSTMNT_LONG_ADD32 and PSTMNT_LONG_ADD32_1 if available. */
+# if defined(PSTMNT_LONG_ADD32_1) && defined(PSTMNT_LONG_ADD32)
+ uint32_t carry;
+ PSTMNT_ASSERT(r[2] != 0xffffffff); /* detect possible carry loss */
+ PSTMNT_ASSERT(a <= (((uint64_t) (0xFFFFFFFFU)) << 32)); /* Check range of
+ input values. */
+
+ carry = 0;
+ PSTMNT_LONG_ADD32(carry, r[0], (uint32_t) (a & 0xFFFFFFFFU));
+ PSTMNT_LONG_ADD32_1(r[2], r[1], (uint32_t) (a >> 32), carry);
+# else
+ uint32_t p[2];
+
+ PSTMNT_ASSERT(r[2] != 0xffffffff); /* detect possible carry loss */
+ PSTMNT_ASSERT(a <= (((uint64_t) (0xFFFFFFFFU)) << 32)); /* Check range of
+ input values. */
+
+ p[0] = (uint32_t) a;
+ p[1] = (uint32_t) (a >> 32);
+ r[2] += pstmnt_add(r, p, r, 2);
+# endif
+}
+# endif /* PSTMNT_LONG_MULADD_CARRY */
+
+/*
+ Optionally add given big number.
+ The number is masked with given mask. The mask will be repeated as
+ neccessary.
+ If add, and, and shift execution times are data-independent, this
+ function will provide data independent execution time.
+
+ Operation: carry || r == r + (b & bmask)
+ The carry is returned from function,
+ The result is stored in r and operands for addition are read from
+ r and b.
+
+ Note: b shall not alias r.
+ */
+int pstmnt_add_mask(const uint32_t * restrict b, uint32_t * restrict r, int szl,
+ uint32_t bmask)
+{
+ uint32_t carry = 0;
+ int i;
+
+ for (i = 0; i < szl; i++)
+ {
+ uint64_t sum;
+ uint32_t bv = b[i];
+ uint32_t rv = r[i];
+ sum = rv;
+ bv &= bmask;
+ sum += bv;
+ sum += carry;
+ r[i] = sum & (-1U);
+ carry = (uint32_t) (sum >> 32);
+ }
+ return carry;
+}
+
+/*
+ Optionally subtract given big number.
+ The number is masked with given mask. The mask will be repeated as
+ neccessary.
+ If negate, sub, and, and shift execution times are data-independent, this
+ function will provide data independent execution time.
+
+ Operation: carry || r == r - (b & bmask)
+ The carry is returned from function,
+ The result is stored in r and operands for addition are read from
+ r and b