mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-22 10:31: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
|
FROM linuxkit/alpine:c23813875499d85163dc358fc6370c9de650df57 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:9bcf61f605ef0ce36cc94d59b8eac307862de6e1 AS build
|
RUN apk add --no-cache go gcc musl-dev linux-headers
|
||||||
RUN apk add \
|
ENV GOPATH=/go PATH=$PATH:/go/bin
|
||||||
argp-standalone \
|
|
||||||
automake \
|
|
||||||
curl \
|
|
||||||
gcc \
|
|
||||||
linux-headers \
|
|
||||||
make \
|
|
||||||
musl-dev \
|
|
||||||
patch
|
|
||||||
|
|
||||||
COPY . /
|
COPY cmd/rngd/*.go /go/src/rngd/
|
||||||
|
RUN REQUIRE_CGO=1 go-compile.sh /go/src/rngd
|
||||||
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
|
|
||||||
|
|
||||||
FROM scratch
|
FROM scratch
|
||||||
ENTRYPOINT []
|
ENTRYPOINT []
|
||||||
|
CMD []
|
||||||
WORKDIR /
|
WORKDIR /
|
||||||
COPY --from=mirror /out/ /
|
COPY --from=mirror /go/bin/rngd /sbin/rngd
|
||||||
COPY --from=build usr/sbin/rngd usr/sbin/rngd
|
CMD ["/sbin/rngd"]
|
||||||
CMD ["/sbin/tini", "/usr/sbin/rngd", "-f"]
|
|
||||||
LABEL org.mobyproject.config='{"capabilities": ["CAP_SYS_ADMIN"], "oomScoreAdj": -800, "readonly": true, "net": "new", "ipc": "new"}'
|
LABEL org.mobyproject.config='{"capabilities": ["CAP_SYS_ADMIN"], "oomScoreAdj": -800, "readonly": true, "net": "new", "ipc": "new"}'
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
IMAGE=rngd
|
IMAGE=rngd
|
||||||
NETWORK=1
|
DEPS=$(wildcard cmd/rngd/*.go)
|
||||||
|
|
||||||
include ../package.mk
|
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