Skip to content

Commit

Permalink
Merge pull request #27 from zanebeckwith/libsodium-randombytes
Browse files Browse the repository at this point in the history
Copy Libsodium's randombytes API and use for prng seeding
  • Loading branch information
Zane Beckwith authored Sep 22, 2017
2 parents 476903c + 144afb9 commit b953cd8
Show file tree
Hide file tree
Showing 28 changed files with 549 additions and 226 deletions.
22 changes: 18 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,20 @@ language: c

compiler: gcc

env:
global:
- LIBSODIUM_DIR=${TRAVIS_BUILD_DIR}/libsodium
- CFLAGS=-I${LIBSODIUM_DIR}/include/
- LDFLAGS=-L${LIBSODIUM_DIR}/lib/
- LD_LIBRARY_PATH=${LIBSODIUM_DIR}/lib/

jobs:
include:

# Release build, gcc
- env: TYPE=RELEASE
before_script:
- .travis/install-libsodium.sh ${LIBSODIUM_DIR}
- cmake . -DCMAKE_BUILD_TYPE=Release
script:
- cmake --build . -- -j2
Expand All @@ -30,17 +38,19 @@ jobs:
# Debug build, to get code coverage with gcov
- env: TYPE=DEBUG_WITH_COVERAGE
before_script:
- .travis/install-libsodium.sh ${LIBSODIUM_DIR}
- cmake . -DCMAKE_BUILD_TYPE=DebugWithCoverage -DCMAKE_C_OUTPUT_EXTENSION_REPLACE=ON
script:
- cmake --build . -- -j2
- ctest -VV
after_success:
- .travis/upload-gcov-results.sh `pwd`
- .travis/upload-gcov-results.sh ${TRAVIS_BUILD_DIR}

# Release build, clang
- env: TYPE=RELEASE-WITH-CLANG
compiler: clang
before_script:
- .travis/install-libsodium.sh ${LIBSODIUM_DIR}
- cmake . -DCMAKE_BUILD_TYPE=Release
script:
- cmake --build . -- -j2
Expand All @@ -62,22 +72,26 @@ jobs:
packages:
- valgrind
before_script:
- .travis/install-libsodium.sh ${LIBSODIUM_DIR}
- cmake . -DCMAKE_BUILD_TYPE=RelWithDebInfo
script:
- cmake --build . -- -j2
- ctest -VV -E benchmarks -T memcheck
after_failure:
- .travis/show-memcheck-results.sh `pwd`
- .travis/show-memcheck-results.sh ${TRAVIS_BUILD_DIR}

# Scan-build
- env: TYPE=SCAN_BUILD
before_script:
- .travis/install-libsodium.sh ${LIBSODIUM_DIR}
script:
- .travis/run-scanbuild.sh `pwd` `pwd`
- .travis/run-scanbuild.sh ${TRAVIS_BUILD_DIR} ${TRAVIS_BUILD_DIR}

# Sanitizers
- env: TYPE=SANITIZE
compiler: clang
before_script:
- .travis/install-libsodium.sh ${LIBSODIUM_DIR}
- cmake . -DCMAKE_BUILD_TYPE=RelWithSanitize
script:
- cmake --build . -- -j2
Expand All @@ -94,7 +108,7 @@ jobs:
name: "xaptum/ecdaa"
description: "A C implementation of elliptic-curve-based Direct Anonymous Attestation signatures"
notification_email: ecdaa-coverity-reports@xaptum.com
build_command_prepend: "cmake . -DCMAKE_BUILD_TYPE=Release"
build_command_prepend: ".travis/install-libsodium.sh ${LIBSODIUM_DIR} && cmake . -DCMAKE_BUILD_TYPE=Release"
build_command: "cmake --build ."
branch_pattern: coverity_scan

Expand Down
28 changes: 28 additions & 0 deletions .travis/install-libsodium.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash
# Copyright 2017 Xaptum, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License

if [[ $# -ne 1 ]]; then
echo "usage: $0 <absolute-path-to-libsodium-installation-directory>"
exit 1
fi

version=1.0.13
install_dir="$1"
wget https://download.libsodium.org/libsodium/releases/libsodium-${version}.tar.gz
tar xvfz libsodium-${version}.tar.gz
cd libsodium-${version}
./configure --prefix=$install_dir
make
make install
15 changes: 13 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
list(APPEND CMAKE_MODULE_PATH CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)
find_package(AMCL REQUIRED QUIET)

option(DISABLE_LIBSODIUM_RNG_SEED_FUNCTION
"Disable the default Libsodium-based seed function"
OFF)

project(ecdaa
LANGUAGES C
VERSION "0.1.1")
Expand All @@ -38,6 +42,12 @@ find_program(MEMORYCHECK_COMMAND NAMES valgrind)
set(MEMORYCHECK_COMMAND_OPTIONS
"--error-exitcode=5 --leak-check=full -v --track-origins=yes --partial-loads-ok=no")

if(NOT DISABLE_LIBSODIUM_RNG_SEED_FUNCTION)
SET(ECDAA_SEED_LINK_LIBRARY sodium)
else(NOT DISABLE_LIBSODIUM_RNG_SEED_FUNCTION)
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDISABLE_LIBSODIUM_RNG_SEED_FUNCTION")
endif(NOT DISABLE_LIBSODIUM_RNG_SEED_FUNCTION)

set(ECDAA_SRC_DIR src)
set(ECDAA_INTERNAL_SRC_DIR ${ECDAA_SRC_DIR}/internal/)
set(ECDAA_AMCL_EXTENSIONS_SRC_DIR ${ECDAA_SRC_DIR}/amcl-extensions/)
Expand All @@ -47,14 +57,14 @@ set(ECDAA_SRCS
${ECDAA_SRC_DIR}/group_public_key_BN254.c
${ECDAA_SRC_DIR}/issuer_keypair_BN254.c
${ECDAA_SRC_DIR}/member_keypair_BN254.c
${ECDAA_SRC_DIR}/prng.c
${ECDAA_SRC_DIR}/signature_BN254.c
${ECDAA_INTERNAL_SRC_DIR}/explicit_bzero.c
${ECDAA_INTERNAL_SRC_DIR}/schnorr.c
${ECDAA_AMCL_EXTENSIONS_SRC_DIR}/big_256_56.c
${ECDAA_AMCL_EXTENSIONS_SRC_DIR}/ecp_BN254.c
${ECDAA_AMCL_EXTENSIONS_SRC_DIR}/ecp2_BN254.c
${ECDAA_AMCL_EXTENSIONS_SRC_DIR}/pairing_BN254.c
${ECDAA_TEST_DIR}/ecdaa-test-utils.c
)

add_library(ecdaa ${ECDAA_SRCS})
Expand All @@ -66,7 +76,8 @@ target_include_directories(ecdaa
PUBLIC ${AMCL_INCLUDE_DIRS})

target_link_libraries(ecdaa
PUBLIC ${AMCL_LIBRARIES})
PRIVATE ${AMCL_LIBRARIES}
${ECDAA_SEED_LINK_LIBRARY})

enable_testing()
add_subdirectory(${ECDAA_TEST_DIR})
28 changes: 13 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ A C implementation of elliptic-curve-based Direct Anonymous Attestation signatur

- The CMake build system is used for building.
- gcc
- libsodium >= 1.0.11 (optionally, see below)
- For building the AMCL dependency:
- python3

Expand All @@ -37,25 +38,22 @@ ctest -V
## Random number generator

Many of the functions provided by this library (particularly, those used by an Issuer or a Member)
require a pointer to a pseudo-random number generator (type `csprng`).
require a pseudo random number generator (type `ecdaa_prng`).
The security of these algorithms depends critically on the proper seeding of this prng.
This means that the first use of any `ecdaa_prng` MUST be preceeded by a call to
`ecdaa_prng_init` (or `ecdaa_prng_init_custom`, see below) on the prng.

Before using these functions, create and seed the `csprng`:
In `ecdaa_prng_init`, the seed for the `ecdaa_prng` is generated from Libsodium's
`randombytes_buf` function.
A discussion on how this function works and any caveats can be found at Libsodium's webpage.

```c
#include <amcl/amcl.h>
#include <amcl/randapi.h>
csprng rng;
char seed[SEED_LEN];
/* Get cryptographically-secure random bytes of length SEED_LEN into seed */
octet seed_as_octet = {.len=SEED_LEN, .max=SEED_LEN, .val=seed};
CREATE_CSPRNG(rng, &seed_as_octet);
```
To use a different function for obtaining cryptographically-secure random data for a seed,
pass the option `-DDISABLE_LIBSODIUM_RNG_SEED_FUNCTION=ON` to CMake (this will remove the dependency on libsodium)
and use the function `ecdaa_prng_init_custom` rather than `ecdaa_prng_init`,
passing in a buffer of cryptographically-strong random bytes of length at least `AMCL_SEED_SIZE`.

The random seed `seed` MUST be generated in a cryptographically-secure manner,
and should be at least 128 bytes long.
Depending on the platform, this seed can be generated, for example, via calls to
`/dev/urandom` (or `getrandom()`), or a hardware random number generator.
When an `ecdaa_prng` is no longer needed, `ecdaa_prng_free` should be called on it
to securely erase its sensitive memory.

## Naming Convention in API

Expand Down
1 change: 1 addition & 0 deletions include/ecdaa.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "ecdaa/group_public_key_BN254.h"
#include "ecdaa/issuer_keypair_BN254.h"
#include "ecdaa/member_keypair_BN254.h"
#include "ecdaa/prng.h"
#include "ecdaa/revocation_list_BN254.h"
#include "ecdaa/signature_BN254.h"

Expand Down
4 changes: 2 additions & 2 deletions include/ecdaa/credential_BN254.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ extern "C" {
struct ecdaa_member_public_key_BN254;
struct ecdaa_issuer_secret_key_BN254;
struct ecdaa_group_public_key_BN254;
struct ecdaa_prng;

#include <amcl/ecp_BN254.h>
#include <amcl/big_256_56.h>
#include <amcl/randapi.h>

#include <stdint.h>

Expand Down Expand Up @@ -68,7 +68,7 @@ int ecdaa_credential_BN254_generate(struct ecdaa_credential_BN254 *cred_out,
struct ecdaa_credential_BN254_signature *cred_sig_out,
struct ecdaa_issuer_secret_key_BN254 *isk,
struct ecdaa_member_public_key_BN254 *member_pk,
csprng *rng);
struct ecdaa_prng *prng);

/*
* Validate a credential and its signature.
Expand Down
5 changes: 3 additions & 2 deletions include/ecdaa/issuer_keypair_BN254.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ extern "C" {
#include <ecdaa/group_public_key_BN254.h>

#include <amcl/big_256_56.h>
#include <amcl/randapi.h>

struct ecdaa_prng;

/*
* Issuer's public key.
Expand Down Expand Up @@ -62,7 +63,7 @@ size_t ecdaa_issuer_secret_key_BN254_length(void);
*/
int ecdaa_issuer_key_pair_BN254_generate(struct ecdaa_issuer_public_key_BN254 *pk_out,
struct ecdaa_issuer_secret_key_BN254 *sk_out,
csprng *rng);
struct ecdaa_prng *prng);

/*
* Check the signature on an `ecdaa_issuer_public_key_BN254`.
Expand Down
4 changes: 3 additions & 1 deletion include/ecdaa/member_keypair_BN254.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
extern "C" {
#endif

struct ecdaa_prng;

#include <amcl/big_256_56.h>
#include <amcl/ecp_BN254.h>

Expand Down Expand Up @@ -62,7 +64,7 @@ int ecdaa_member_key_pair_BN254_generate(struct ecdaa_member_public_key_BN254 *p
struct ecdaa_member_secret_key_BN254 *sk_out,
uint8_t *nonce,
uint32_t nonce_length,
csprng *rng);
struct ecdaa_prng *prng);

/*
* Check the signature on an `ecdaa_member_public_key_BN254`.
Expand Down
111 changes: 111 additions & 0 deletions include/ecdaa/prng.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/******************************************************************************
*
* Copyright 2017 Xaptum, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*
*****************************************************************************/

#ifndef ECDAA_PRNG_H
#define ECDAA_PRNG_H
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

#include <amcl/randapi.h>

#include <stddef.h>

#define AMCL_SEED_SIZE 128 // As recommended in AMCL's "rand.c"

enum ecdaa_prng_initialized {
ECDAA_PRNG_INITIALIZED_NO = 0,
ECDAA_PRNG_INITIALIZED_YES
};

/*
* Wrapper around AMCL's pseudo-random-number-generator.
*
* For the safe operation of this library,
* all `ecdaa_prng`s MUST first be properly seeded
* via a call to `ecdaa_prng_init`
* or `ecdaa_prng_init_custom` before first use.
*/
struct ecdaa_prng {
enum ecdaa_prng_initialized initialized;
csprng impl;
};

/*
* Accessor for the underlying AMCL csprng in a `ecdaa_prng`.
*
* Checks that `ecdaa_prng` was initialized before returning.
* If not, calls `abort()`.
*/
csprng *get_csprng(struct ecdaa_prng *prng);

/*
* Securely-clears memory used by a `ecdaa_prng`.
*
* To be used when finished with a `ecdaa_prng`.
*
* Does not do any heap deallocation.
*/
void ecdaa_prng_free(struct ecdaa_prng *prng);

#ifndef DISABLE_LIBSODIUM_RNG_SEED_FUNCTION

/*
* Properly seeds a `ecdaa_prng`.
*
* MUST be called on a `ecdaa_prng` before first use.
*
* No dynamic memory allocation is performed.
*
* Uses Libsodium's `randombytes_buf` as the source of
* a cryptographically-strong random seed.
* Requires the CMake option `DISABLE_LIBSODIUM_RNG_SEED_FUNCTION=OFF`.
*
* Returns:
* 0 on success
* -1 if unable to obtain seed
* -2 if entropy is insufficient
*/
int ecdaa_prng_init(struct ecdaa_prng *prng_in);

#endif // DISABLE_LIBSODIUM_RNG_SEED_FUNCTION

/*
* Properly seed a `ecdaa_prng`, with a custom cryptographically-strong random seed.
*
* MUST be called on a `ecdaa_prng` before first use,
* unless using `ecdaa_prng_init` instead.
*
* No dynamic memory allocation is performed.
*
* `seed_size` MUST be at least AMCL_SEED_SIZE.
*
* Returns:
* 0 on success
* -1 if seed_size < AMCL_SEED_SIZE
*/
int ecdaa_prng_init_custom(struct ecdaa_prng *prng_in, char *seed, size_t seed_size);

#ifdef __cplusplus
}
#endif

#endif

3 changes: 2 additions & 1 deletion include/ecdaa/signature_BN254.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct ecdaa_credential_BN254;
struct ecdaa_member_secret_key_BN254;
struct ecdaa_revocation_list_BN254;
struct ecdaa_group_public_key_BN254;
struct ecdaa_prng;

/*
* ECDAA signature.
Expand Down Expand Up @@ -58,7 +59,7 @@ int ecdaa_signature_BN254_sign(struct ecdaa_signature_BN254 *signature_out,
uint32_t message_len,
struct ecdaa_member_secret_key_BN254 *sk,
struct ecdaa_credential_BN254 *cred,
csprng *rng);
struct ecdaa_prng *prng);

/*
* Verify an ECDAA signature.
Expand Down
Loading

0 comments on commit b953cd8

Please sign in to comment.