NaCl: Networking and Cryptography library |
![]() Computer Aided Cryptography Engineering |
|
InternalsAre you contributing code to NaCl? Here's some advice on how to write your code.Naming conventions: an exampleThe reference SHA-512 implementation in NaCl is crypto_hash/sha512/ref/hash.c, which defines a crypto_hash function as follows:
#include "crypto_hash.h"
int crypto_hash(unsigned char *out,const unsigned char *in,unsigned long long inlen)
{
...
}
An accompanying file
crypto_hash/sha512/ref/api.h
says
#define CRYPTO_BYTES 64
to indicate that this function produces a 64-byte hash.
The NaCl compilation scripts automatically create crypto_hash.h with various macros, including the following:
#define crypto_hash crypto_hash_sha512
#define crypto_hash_sha512 crypto_hash_sha512_ref
#define crypto_hash_BYTES crypto_hash_sha512_BYTES
#define crypto_hash_sha512_BYTES crypto_hash_sha512_ref_BYTES
#define crypto_hash_sha512_ref_BYTES 64
#define crypto_hash_PRIMITIVE "sha512"
#define crypto_hash_IMPLEMENTATION crypto_hash_sha512_IMPLEMENTATION
#define crypto_hash_sha512_IMPLEMENTATION "crypto_hash/sha512/ref"
This means that hash.c actually defines a crypto_hash_sha512_ref function.
Normally, as an implementor, you don't have to think about this;
but if you avoid including crypto_hash.h
(for example, because you're actually writing hash.s instead of hash.c)
then you should make sure to define crypto_hash_sha512_ref.
Multiple implementations of the same primitiveTo add another SHA-512 implementation, create another subdirectory of crypto_hash/sha512. For example, you might choose crypto_hash/sha512/core2 for an implementation optimized for the Core 2. Inside that subdirectory, create an api.h file that defines CRYPTO_BYTES, and a .c file that defines crypto_hash.You can use names other than hash.c. You can split your code across several files *.c defining various auxiliary functions; the files will be automatically compiled together. BranchesDo not use secret data to control a branch. In particular, do not use the memcmp function to compare secrets. Instead use crypto_verify_16, crypto_verify_32, etc., which perform constant-time string comparisons.Array lookupsExcept inside primitives specifically labelled vulnerable, do not use secret data as an array index.Dynamic memory allocationDo not use malloc, calloc, sbrk, etc. in C NaCl.AlignmentDo not assume that the input arrays or output arrays have any particular alignment. If you want to use, e.g., an aligned 16-byte load instruction for speed, check at the top of your function that the input array is properly aligned, and have a (slower) fallback in case the input array is not properly aligned.Specific integer sizesIf you want a 32-bit integer, use crypto_int32 after #include <crypto_int32.h>. This is more portable than int32_t from inttypes.h, and more portable than int32_t from stdint.h. Similar comments apply to crypto_int8, crypto_int16, crypto_int32, crypto_int64, crypto_uint8, crypto_uint16, crypto_uint32, crypto_uint64.VersionThis is version 2008.12.21 of the internals.html web page. |