Add 'pkg/ent/' from commit '31ac2913f14c6f7631f5792ad942605fb2d9fb87'

git-subtree-dir: pkg/ent
git-subtree-mainline: 1207c204cb
git-subtree-split: 31ac2913f1
This commit is contained in:
Benjamin Summers 2019-03-04 16:49:14 -08:00
commit 9618f37965
8 changed files with 211 additions and 0 deletions

4
pkg/ent/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/*.a
/*.o
/out
/test

20
pkg/ent/LICENSE Normal file
View File

@ -0,0 +1,20 @@
Copyright 2019 Steven Dee
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

29
pkg/ent/Makefile Normal file
View File

@ -0,0 +1,29 @@
CC ?= cc
AR ?= ar
PREFIX ?= ./out
ifndef IMPL
$(error IMPL must be set)
endif
################################################################################
.PHONY: all test install clean
all: ent.c ent.h
$(CC) -D$(IMPL) -O3 -Wall -Werror -pedantic -std=gnu99 -c ent.c
$(AR) rcs libent.a ent.o
test: all
$(CC) -D$(IMPL) -O3 -Wall -Werror -pedantic -std=gnu99 ent.c test.c -o test
./test
install: all
@mkdir -p $(PREFIX)/lib/
@mkdir -p $(PREFIX)/include/
cp libent.a $(PREFIX)/lib/
cp ent.h $(PREFIX)/include/
clean:
rm -f *.o *.a test
rm -rf ./out

38
pkg/ent/README.md Normal file
View File

@ -0,0 +1,38 @@
## `libent`
`libent` is a cross-platform wrapper around `getentropy(2)`. It exports
one symbol, `ent_getentropy`. If getentropy is available, then it's just
a shim around that. Otherwise, it uses `getrandom(2)` (available since
kernel 3.17) on Linux, or `/dev/urandom` on other \*nix.
### Building and Testing
```bash
./configure
make
make test
PREFIX=/usr/local make install
```
### Why?
`getentropy` is the wave of the future. It's the correct API for
generating small amounts of entropy to create cryptographic keys or seed
PRNGs. It's good and reasonable and true, it's on Linux, \*BSD, and OS
X, and it only took us fifty years of UNIX to get here.
Sadly, it only just arrived, so nobody has it yet. It didn't land in
Linux until glibc 2.25, which seems to only have made it into Debian 10.
Once `getentropy` is everywhere you care about, you can just do a
s/ent\_//g on all the call sites and discard this shim.
This project began because [Urbit](https://github.com/urbit/urbit)'s
entropy-generation function was bothering me. Then it got out of hand.
### References
* [OpenBSD getentropy](https://man.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man2/getentropy.2)
* [djb on entropy gathering](https://blog.cr.yp.to/20140205-entropy.html)

25
pkg/ent/configure vendored Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/env bash
log () {
echo "$@" >&2;
}
for impl in ENT_GETENTROPY_UNISTD \
ENT_GETENTROPY_SYSRANDOM \
ENT_GETRANDOM_SYSCALL \
ENT_DEV_URANDOM
do
export IMPL=$impl
log "Trying IMPL=$IMPL"
if IMPL=$impl make >/dev/null 2>/dev/null
then sed -i 's|$(error IMPL must be set)|IMPL='"$impl"'|' Makefile
log "IMPL=$IMPL works"
exit 0
else log "IMPL=$IMPL failed"
fi
done
log "This shouldn't happen, something is broken."
exit 1

62
pkg/ent/ent.c Normal file
View File

@ -0,0 +1,62 @@
// Use `getentropy` from unistd.h //////////////////////////////////////////////
#if defined(ENT_GETENTROPY_UNISTD)
#include <stddef.h>
#include <unistd.h>
int ent_getentropy(void* buf, size_t len) {
return getentropy(buf, len);
}
// Use `getentropy` from sys/random.h //////////////////////////////////////////
#elif defined(ENT_GETENTROPY_SYSRANDOM)
#include <stddef.h>
#include <sys/random.h>
int ent_getentropy(void* buf, size_t len) {
return getentropy(buf, len);
}
// Use the `getrandom` syscall /////////////////////////////////////////////////
#elif defined(ENT_GETRANDOM_SYSCALL)
#include <stddef.h>
#include <errno.h>
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#define ENTFAIL { errno=EIO; return -1; }
int ent_getentropy(void* buf, size_t len) {
if (len > 256) ENTFAIL
int r = syscall(SYS_getrandom, buf, len, 0);
if (r < 0) return r;
if (r != len) ENTFAIL
return 0;
}
// Use `/dev/urandom` //////////////////////////////////////////////////////////
#elif defined(ENT_DEV_URANDOM)
#include <stddef.h>
#include <errno.h>
#include <stdio.h>
#define ENTFAIL { errno=EIO; return -1; }
int ent_getentropy(void* buf, size_t len) {
if (len > 256) ENTFAIL;
FILE *f = fopen("/dev/urandom", "re");
if (!f) return -1;
int r = fread(buf, 1, len, f);
(void) fclose(f);
if (r != len) ENTFAIL
return 0;
}
#else
#error "One of these must be set: ENT_DEV_URANDOM, ENT_GETENTROPY_UNISTD, ENT_GETENTROPY_SYSRANDOM, ENT_GETRANDOM_SYSCALL"
#endif

13
pkg/ent/ent.h Normal file
View File

@ -0,0 +1,13 @@
#pragma once
#include <stddef.h>
/*
Fills buf with high-quality entropy.
buflen is the number of bytes, no greater than 256.
Returns 0 on success. On failure, returns -1 and sets errno to
indicate the error.
*/
int ent_getentropy(void* buf, size_t buflen);

20
pkg/ent/test.c Normal file
View File

@ -0,0 +1,20 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ent.h"
int main(void) {
char buf[256] = {0};
if (0 != ent_getentropy(buf, sizeof(buf))) {
perror("getentropy");
exit(1);
}
for (int i = 0; i < sizeof buf; i++) {
printf("%02hhx", buf[i]);
}
puts("");
}