mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-21 18:11:35 +00:00
Replace rngd with a Go version
Only supports the use cases we currently need, currently support for using Intel hardware rng to initialise and add entropy. Supports oneshot and service mode. Call as `rngd -1` for one shot mode. Signed-off-by: Justin Cormack <justin.cormack@docker.com>
This commit is contained in:
parent
f436e66a77
commit
e0bc13451f
@ -1,46 +1,15 @@
|
||||
FROM linuxkit/alpine:9bcf61f605ef0ce36cc94d59b8eac307862de6e1 AS mirror
|
||||
RUN mkdir -p /out/etc/apk && cp -r /etc/apk/* /out/etc/apk/
|
||||
RUN apk add --no-cache --initdb -p /out \
|
||||
tini
|
||||
RUN rm -rf /out/etc/apk /out/lib/apk /out/var/cache
|
||||
RUN mkdir -p /out/dev /out/proc /out/sys
|
||||
FROM linuxkit/alpine:c23813875499d85163dc358fc6370c9de650df57 AS mirror
|
||||
|
||||
FROM linuxkit/alpine:9bcf61f605ef0ce36cc94d59b8eac307862de6e1 AS build
|
||||
RUN apk add \
|
||||
argp-standalone \
|
||||
automake \
|
||||
curl \
|
||||
gcc \
|
||||
linux-headers \
|
||||
make \
|
||||
musl-dev \
|
||||
patch
|
||||
RUN apk add --no-cache go gcc musl-dev linux-headers
|
||||
ENV GOPATH=/go PATH=$PATH:/go/bin
|
||||
|
||||
COPY . /
|
||||
|
||||
ENV pkgname=rng-tools pkgver=5
|
||||
|
||||
RUN curl -fSL "http://downloads.sourceforge.net/project/gkernel/$pkgname/$pkgver/$pkgname-$pkgver.tar.gz" -o "$pkgname-$pkgver.tar.gz"
|
||||
RUN sha256sum -c sha256sums
|
||||
RUN zcat $pkgname-$pkgver.tar.gz | tar xf -
|
||||
|
||||
RUN cd $pkgname-$pkgver && for p in ../*.patch; do cat $p | patch -p1; done
|
||||
|
||||
RUN cd $pkgname-$pkgver && \
|
||||
export LIBS="-largp" && \
|
||||
LDFLAGS=-static ./configure \
|
||||
--prefix=/usr \
|
||||
--libexecdir=/usr/lib/rng-tools \
|
||||
--sysconfdir=/etc \
|
||||
--disable-silent-rules && \
|
||||
make && \
|
||||
make DESTDIR=/ install && \
|
||||
strip /usr/sbin/rngd
|
||||
COPY cmd/rngd/*.go /go/src/rngd/
|
||||
RUN REQUIRE_CGO=1 go-compile.sh /go/src/rngd
|
||||
|
||||
FROM scratch
|
||||
ENTRYPOINT []
|
||||
CMD []
|
||||
WORKDIR /
|
||||
COPY --from=mirror /out/ /
|
||||
COPY --from=build usr/sbin/rngd usr/sbin/rngd
|
||||
CMD ["/sbin/tini", "/usr/sbin/rngd", "-f"]
|
||||
COPY --from=mirror /go/bin/rngd /sbin/rngd
|
||||
CMD ["/sbin/rngd"]
|
||||
LABEL org.mobyproject.config='{"capabilities": ["CAP_SYS_ADMIN"], "oomScoreAdj": -800, "readonly": true, "net": "new", "ipc": "new"}'
|
||||
|
@ -1,4 +1,4 @@
|
||||
IMAGE=rngd
|
||||
NETWORK=1
|
||||
DEPS=$(wildcard cmd/rngd/*.go)
|
||||
|
||||
include ../package.mk
|
||||
|
66
pkg/rngd/cmd/rngd/main.go
Normal file
66
pkg/rngd/cmd/rngd/main.go
Normal file
@ -0,0 +1,66 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func main() {
|
||||
oneshot := len(os.Args) > 1 && os.Args[1] == "-1"
|
||||
|
||||
timeout := -1
|
||||
if oneshot {
|
||||
timeout = 0
|
||||
}
|
||||
|
||||
supported := initRand()
|
||||
if !supported {
|
||||
log.Fatalf("No random source available")
|
||||
}
|
||||
|
||||
random, err := os.Open("/dev/random")
|
||||
if err != nil {
|
||||
log.Fatalf("Cannot open /dev/random: %v", err)
|
||||
}
|
||||
defer random.Close()
|
||||
fd := int(random.Fd())
|
||||
|
||||
epfd, err := syscall.EpollCreate1(0)
|
||||
if err != nil {
|
||||
log.Fatalf("epoll create error: %v", err)
|
||||
}
|
||||
defer syscall.Close(epfd)
|
||||
|
||||
var event syscall.EpollEvent
|
||||
var events [1]syscall.EpollEvent
|
||||
|
||||
event.Events = syscall.EPOLLOUT
|
||||
event.Fd = int32(fd)
|
||||
if err := syscall.EpollCtl(epfd, syscall.EPOLL_CTL_ADD, fd, &event); err != nil {
|
||||
log.Fatalf("epoll add error: %v", err)
|
||||
}
|
||||
|
||||
count := 0
|
||||
|
||||
for {
|
||||
// write some entropy
|
||||
n, err := writeEntropy(random)
|
||||
if err != nil {
|
||||
log.Fatalf("write entropy: %v", err)
|
||||
}
|
||||
count += n
|
||||
// sleep until we can write more
|
||||
nevents, err := syscall.EpollWait(epfd, events[:], timeout)
|
||||
if err != nil {
|
||||
log.Fatalf("epoll wait error: %v", err)
|
||||
}
|
||||
if nevents == 1 && events[0].Events&syscall.EPOLLOUT == syscall.EPOLLOUT {
|
||||
continue
|
||||
}
|
||||
if oneshot {
|
||||
log.Printf("Wrote %d bytes of entropy, exiting as oneshot\n", count)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
84
pkg/rngd/cmd/rngd/rng_amd64.go
Normal file
84
pkg/rngd/cmd/rngd/rng_amd64.go
Normal file
@ -0,0 +1,84 @@
|
||||
package main
|
||||
|
||||
// #cgo CFLAGS: -mrdrnd -mrdseed
|
||||
// #include <immintrin.h>
|
||||
// #include <x86intrin.h>
|
||||
// #include <stdint.h>
|
||||
// #include <cpuid.h>
|
||||
// #include <linux/random.h>
|
||||
// #include <sys/ioctl.h>
|
||||
//
|
||||
// int hasrdrand() {
|
||||
// unsigned int eax, ebx, ecx, edx;
|
||||
// __get_cpuid(1, &eax, &ebx, &ecx, &edx);
|
||||
//
|
||||
// return ((ecx & bit_RDRND) == bit_RDRND);
|
||||
// }
|
||||
//
|
||||
// int hasrdseed() {
|
||||
// unsigned int eax, ebx, ecx, edx;
|
||||
// __get_cpuid(7, &eax, &ebx, &ecx, &edx);
|
||||
//
|
||||
// return ((ebx & bit_RDSEED) == bit_RDSEED);
|
||||
// }
|
||||
//
|
||||
// int rdrand(uint64_t *val) {
|
||||
// return _rdrand64_step((unsigned long long *)val);
|
||||
// }
|
||||
//
|
||||
// int rdseed(uint64_t *val) {
|
||||
// return _rdseed64_step((unsigned long long *)val);
|
||||
// }
|
||||
//
|
||||
// int rndaddentropy = RNDADDENTROPY;
|
||||
//
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var hasRdrand, hasRdseed bool
|
||||
|
||||
type randInfo struct {
|
||||
entropyCount int
|
||||
size int
|
||||
buf uint64
|
||||
}
|
||||
|
||||
func initRand() bool {
|
||||
hasRdrand = C.hasrdrand() == 1
|
||||
hasRdseed = C.hasrdseed() == 1
|
||||
return hasRdrand || hasRdseed
|
||||
}
|
||||
|
||||
func rand() (uint64, error) {
|
||||
var x C.uint64_t
|
||||
// prefer rdseed as that is correct seed
|
||||
if hasRdseed && C.rdseed(&x) == 1 {
|
||||
return uint64(x), nil
|
||||
}
|
||||
// failed rdseed, rdrand better than nothing
|
||||
if hasRdrand && C.rdrand(&x) == 1 {
|
||||
return uint64(x), nil
|
||||
}
|
||||
return 0, errors.New("No randomness available")
|
||||
}
|
||||
|
||||
func writeEntropy(random *os.File) (int, error) {
|
||||
r, err := rand()
|
||||
if err != nil {
|
||||
// assume can fail occasionally
|
||||
return 0, nil
|
||||
}
|
||||
const entropy = 64 // they are good random numbers, Brent
|
||||
info := randInfo{entropy, 8, r}
|
||||
ret, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(random.Fd()), uintptr(C.rndaddentropy), uintptr(unsafe.Pointer(&info)))
|
||||
if ret == 0 {
|
||||
return 8, nil
|
||||
}
|
||||
return 0, err
|
||||
}
|
13
pkg/rngd/cmd/rngd/rng_unsupported.go
Normal file
13
pkg/rngd/cmd/rngd/rng_unsupported.go
Normal file
@ -0,0 +1,13 @@
|
||||
// +build !amd64
|
||||
|
||||
package main
|
||||
|
||||
import "errors"
|
||||
|
||||
func initRand() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func rand() (uint64, error) {
|
||||
return 0, errors.New("No rng available")
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
--- rng-tools/rdrand_asm.S
|
||||
+++ rng-tools/rdrand_asm.S
|
||||
@@ -49,6 +49,7 @@
|
||||
ret
|
||||
ENDPROC(x86_rdrand_nlong)
|
||||
|
||||
+#define INIT_PIC()
|
||||
#define SETPTR(var,ptr) leaq var(%rip),ptr
|
||||
#define PTR0 %rdi
|
||||
#define PTR1 %rsi
|
||||
@@ -84,7 +85,16 @@
|
||||
ret
|
||||
ENDPROC(x86_rdrand_nlong)
|
||||
|
||||
+#if defined(__PIC__)
|
||||
+#undef __i686 /* gcc builtin define gets in our way */
|
||||
+#define INIT_PIC() \
|
||||
+ call __i686.get_pc_thunk.bx ; \
|
||||
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
|
||||
+#define SETPTR(var,ptr) leal (var)@GOTOFF(%ebx),ptr
|
||||
+#else
|
||||
+#define INIT_PIC()
|
||||
#define SETPTR(var,ptr) movl $(var),ptr
|
||||
+#endif
|
||||
#define PTR0 %eax
|
||||
#define PTR1 %edx
|
||||
#define PTR2 %ecx
|
||||
@@ -101,6 +111,7 @@
|
||||
movl 8(%ebp), %eax
|
||||
movl 12(%ebp), %edx
|
||||
#endif
|
||||
+ INIT_PIC()
|
||||
|
||||
SETPTR(aes_round_keys, PTR2)
|
||||
|
||||
@@ -166,6 +177,17 @@
|
||||
#endif
|
||||
ret
|
||||
ENDPROC(x86_aes_mangle)
|
||||
+
|
||||
+#if defined(__i386__) && defined(__PIC__)
|
||||
+ .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
|
||||
+.globl __i686.get_pc_thunk.bx
|
||||
+ .hidden __i686.get_pc_thunk.bx
|
||||
+ .type __i686.get_pc_thunk.bx,@function
|
||||
+__i686.get_pc_thunk.bx:
|
||||
+ movl (%esp), %ebx
|
||||
+ ret
|
||||
+#endif
|
||||
+
|
@ -1 +0,0 @@
|
||||
60a102b6603bbcce2da341470cad42eeaa9564a16b4490e7867026ca11a3078e rng-tools-5.tar.gz
|
Loading…
Reference in New Issue
Block a user