Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
.privenv
nostril
/result
build.log
configurator.out*
configurator
.build-result
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "deps/secp256k1"]
path = deps/secp256k1
url = https://github.com/bitcoin-core/secp256k1
[submodule "deps/libsodium"]
path = deps/libsodium
url = https://github.com/jedisct1/libsodium.git
22 changes: 16 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@

CFLAGS = -Wall -O2 -Ideps/secp256k1/include
OBJS = sha256.o nostril.o aes.o base64.o
HEADERS = hex.h random.h config.h sha256.h deps/secp256k1/include/secp256k1.h
CFLAGS = -Wall -O2 -Ideps/secp256k1/include -Ideps/libsodium/src/libsodium/include/
LDFLAGS = -lm
OBJS = sha256.o nostril.o aes.o base64.o nip44.o hmac_sha256.o hkdf_sha256.o
HEADERS = hex.h nip44.h cursor.h random.h config.h sha256.h deps/secp256k1/include/secp256k1.h
PREFIX ?= /usr/local
ARS = libsecp256k1.a
LIBSODIUM_AR=deps/libsodium/src/libsodium/.libs/libsodium.a
ARS = libsecp256k1.a $(LIBSODIUM_AR)

SUBMODULES = deps/secp256k1
SUBMODULES = deps/secp256k1 deps/libsodium

all: nostril docs

Expand All @@ -27,6 +29,14 @@ dist: docs version
cp CHANGELOG dist/CHANGELOG.txt
rsync -avzP dist/ charon:/www/cdn.jb55.com/tarballs/nostril/

$(LIBSODIUM_AR): deps/libsodium/config.log
cd deps/libsodium/src/libsodium; \
make -j libsodium.la

deps/libsodium/config.log: deps/libsodium/configure
cd deps/libsodium; \
./configure --disable-shared --enable-minimal

deps/secp256k1/.git:
@devtools/refresh-submodules.sh $(SUBMODULES)

Expand All @@ -52,7 +62,7 @@ libsecp256k1.a: deps/secp256k1/.libs/libsecp256k1.a
@$(CC) $(CFLAGS) -c $< -o $@

nostril: $(HEADERS) $(OBJS) $(ARS)
$(CC) $(CFLAGS) $(OBJS) $(ARS) -o $@
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(ARS) -o $@

install: all
mkdir -p $(PREFIX)/share/man/man1
Expand Down
66 changes: 66 additions & 0 deletions cursor.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "hex.h"

#define unlikely(x) __builtin_expect((x),0)
#define likely(x) __builtin_expect((x),1)
Expand Down Expand Up @@ -254,11 +255,42 @@ static inline int cursor_pull_int(struct cursor *cursor, int *i)
return cursor_pull(cursor, (unsigned char*)i, sizeof(*i));
}

static inline int cursor_pull_u16(struct cursor *cursor, uint16_t *i)
{
return cursor_pull(cursor, (unsigned char*)i, sizeof(*i));
}

#define BSWAP_16(val) \
((((uint16_t)(val) & 0x00ff) << 8) \
| (((uint16_t)(val) & 0xff00) >> 8))

static inline uint16_t bswap_16(uint16_t val)
{
return BSWAP_16(val);
}

static inline int cursor_push_u16(struct cursor *cursor, unsigned short i)
{
return cursor_push(cursor, (unsigned char*)&i, sizeof(i));
}

static int cursor_pull_b16(struct cursor *c, uint16_t *s)
{
if (!cursor_pull_u16(c, s))
return 0;

// we assume little endian
*s = bswap_16(*s);
return 1;
}

static int cursor_push_b16(struct cursor *c, uint16_t s)
{
if (!cursor_push_u16(c, bswap_16(s)))
return 0;
return 1;
}

static inline void *index_cursor(struct cursor *cursor, unsigned int index, int elem_size)
{
unsigned char *p;
Expand Down Expand Up @@ -291,6 +323,16 @@ static inline int cursor_remaining_capacity(struct cursor *cursor)
return cursor->end - cursor->p;
}

static inline int cursor_push_hex(struct cursor *c, const void *buf, size_t bufsize)
{
int size;
size = hex_encode(buf, bufsize, (char *)c->p, c->end - c->p);
if (!size)
return 0;
c->p += bufsize * 2;
return 1;
}


#define max(a,b) ((a) > (b) ? (a) : (b))
static inline void cursor_print_around(struct cursor *cur, int range)
Expand All @@ -317,4 +359,28 @@ static inline void cursor_print_around(struct cursor *cur, int range)
}
#undef max

static inline int cursor_memset(struct cursor *cursor, unsigned char c, int n)
{
if (cursor->p + n >= cursor->end)
return 0;

memset(cursor->p, c, n);
cursor->p += n;

return 1;
}


static inline int cursor_align(struct cursor *cur, int bytes) {
size_t size = cur->p - cur->start;
int pad;

// pad to n-byte alignment
pad = ((size + (bytes-1)) & ~(bytes-1)) - size;
if (pad > 0 && !cursor_memset(cur, 0, pad))
return 0;

return 1;
}

#endif
1 change: 1 addition & 0 deletions deps/libsodium
Submodule libsodium added at 9511c9
4 changes: 4 additions & 0 deletions hex.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@

#ifndef NOSTRIL_HEX_H
#define NOSTRIL_HEX_H

static inline int char_to_hex(unsigned char *val, char c)
{
if (c >= '0' && c <= '9') {
Expand Down Expand Up @@ -67,3 +70,4 @@ static inline int hex_encode(const void *buf, size_t bufsize, char *dest, size_t
return 1;
}

#endif /* NOSTRIL_HEX_H */
104 changes: 104 additions & 0 deletions hkdf_sha256.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/* MIT (BSD) license - see LICENSE file for details */
#include "hkdf_sha256.h"
#include "hmac_sha256.h"
#include <assert.h>
#include <string.h>

void hkdf_expand(void *okm, size_t okm_size,
const void *prk, size_t prksize,
const void *info, size_t isize)
{
struct hmac_sha256_ctx ctx;
struct hmac_sha256 t;
unsigned char c;

assert(okm_size < 255 * sizeof(t));
/*
* 2.3. Step 2: Expand
*
* HKDF-Expand(PRK, info, L) -> OKM
*
* Options:
* Hash a hash function; HashLen denotes the length of the
* hash function output in octets
*
* Inputs:
* PRK a pseudorandom key of at least HashLen octets
* (usually, the output from the extract step)
* info optional context and application specific information
* (can be a zero-length string)
* L length of output keying material in octets
* (<= 255*HashLen)
*
* Output:
* OKM output keying material (of L octets)
*
* The output OKM is calculated as follows:
*
* N = ceil(L/HashLen)
* T = T(1) | T(2) | T(3) | ... | T(N)
* OKM = first L octets of T
*
* where:
* T(0) = empty string (zero length)
* T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
* T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
* T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
* ...
*
* (where the constant concatenated to the end of each T(n) is a
* single octet.)
*/
c = 1;
hmac_sha256_init(&ctx, prk, prksize);
hmac_sha256_update(&ctx, info, isize);
hmac_sha256_update(&ctx, &c, 1);
hmac_sha256_done(&ctx, &t);

while (okm_size > sizeof(t)) {
memcpy(okm, &t, sizeof(t));
okm = (char *)okm + sizeof(t);
okm_size -= sizeof(t);

c++;
hmac_sha256_init(&ctx, prk, prksize);
hmac_sha256_update(&ctx, &t, sizeof(t));
hmac_sha256_update(&ctx, info, isize);
hmac_sha256_update(&ctx, &c, 1);
hmac_sha256_done(&ctx, &t);
}
memcpy(okm, &t, okm_size);
}

void hkdf_sha256(void *okm, size_t okm_size,
const void *s, size_t ssize,
const void *k, size_t ksize,
const void *info, size_t isize)
{
struct hmac_sha256 prk;

/* RFC 5869:
*
* 2.2. Step 1: Extract
*
* HKDF-Extract(salt, IKM) -> PRK
*
* Options:
* Hash a hash function; HashLen denotes the length of the
* hash function output in octets
*
* Inputs:
* salt optional salt value (a non-secret random value);
* if not provided, it is set to a string of HashLen zeros.
* IKM input keying material
*
* Output:
* PRK a pseudorandom key (of HashLen octets)
*
* The output PRK is calculated as follows:
*
* PRK = HMAC-Hash(salt, IKM)
*/
hmac_sha256(&prk, s, ssize, k, ksize);
hkdf_expand(okm, okm_size, &prk, sizeof(prk), info, isize);
}
28 changes: 28 additions & 0 deletions hkdf_sha256.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef CCAN_CRYPTO_HKDF_SHA256_H
#define CCAN_CRYPTO_HKDF_SHA256_H
/* BSD-MIT - see LICENSE file for details */
#include "config.h"
#include "hmac_sha256.h"
#include <stdlib.h>

/**
* hkdf_sha256 - generate a derived key
* @okm: where to output the key
* @okm_size: the number of bytes pointed to by @okm (must be less than 255*32)
* @s: salt
* @ssize: the number of bytes pointed to by @s
* @k: pointer to input key
* @ksize: the number of bytes pointed to by @k
* @info: pointer to info
* @isize: the number of bytes pointed to by @info
*/
void hkdf_sha256(void *okm, size_t okm_size,
const void *s, size_t ssize,
const void *k, size_t ksize,
const void *info, size_t isize);

void hkdf_expand(void *okm, size_t okm_size,
const void *prk, size_t prksize,
const void *info, size_t isize);

#endif /* CCAN_CRYPTO_HKDF_SHA256_H */
Loading