나는 MIPSEL을 가지고 있습니다CI20 개발 보드그건엔트로피 고갈로 고통받는. 이 보드에는 하드웨어 rng(주소 0x100000DC에 매핑된 레지스터)가 있는 JZ4780 SoC가 있습니다. 이것Ingenic 드라이버에 문제가 있습니다, 그래서 레지스터를 읽고 풀을 보충하는 사용자 영역 프로그램을 작성했습니다.
프로그램을 실행한 후 나는 다음을 관찰했습니다.
$ sudo ./ci20-rng.exe && for((i=1;i<=20;i+=1)); do (cat /proc/sys/kernel/random/entropy_avail; sleep 5); done
3968
3712
3456
3200
2944
2688
2432
2176
1920
1664
1408
1152
896
640
384
128
128
...
비슷한 질문은엔트로피를 소비한다는 것은 무엇입니까?거터 설명은 기본적으로 의미가 있습니다. 이러한 설명을 고려하면 너무 빨리 일어난 일이라고 생각합니다. 하지만 변위가 160이나 128 주위에 고정되는 대신 계속 0으로 유지되어야 하는 것처럼 보입니다.
왜 entropy_avail
160이나 128 부근에서 안정적인가요?
다음 프로그램은 ioctl(fd, RNDADDENTROPY, &entropy)
is 설명 fd
자를 사용합니다 /dev/random
. entropy
예상되는 구조는 다음과 같습니다.
typedef struct {
int bit_count;
int byte_count;
unsigned char buf[4096];
} entropy_t;
제어 레지스터( *ctrl = 0x00
및 *ctrl = 0x01
)의 전환 및 읽기로 인한 후속 지연JZ4780 프로그래머 매뉴얼. 아이디어는 SC-ROM 컨트롤러에 쓰지만 1초 미만 동안 밀어 올리는 것입니다."...VDDQ의 최대 2.5V 전원 공급 시간은 1초 이내로 엄격하게 제어되어야 합니다.". 너무 심각하게 받아들이거나 오해하지 않았으면 좋겠습니다.
절차는 다음과 같습니다.
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <linux/random.h>
typedef struct {
int bit_count; /* number of bits of entropy in data */
int byte_count; /* number of bytes of data in array */
unsigned char buf[4096];
} entropy_t;
static int print_only;
/* gcc -g2 -O2 -std=c99 ci20-rng.c -o ci20-rng.exe */
int main(int argc, char* argv[])
{
int ret = 1, fd1 = -1, fd2 = -1, fd3 = -1;
void *map1 = MAP_FAILED, *map2 = MAP_FAILED;
const int PAGE_SIZE = sysconf(_SC_PAGESIZE);
const int PAGE_MASK = ~(PAGE_SIZE - 1);
#define CTRL_ADDR 0x100000D8
#define DATA_ADDR 0x100000DC
if(argc >= 2)
{
if(0 == strcmp(argv[1], "-p") || 0 == strcmp(argv[1], "/p") || 0 == strcmp(argv[1], "--print"))
print_only = 1;
}
fd1 = open("/dev/mem", O_RDWR | O_SYNC);
if(fd1 == -1)
{
fprintf(stderr, "Failed to open /dev/mem for reading and writing (error %d)\n", errno);
goto cleanup;
}
fd2 = open("/dev/mem", O_RDONLY | O_SYNC);
if(fd2 == -1)
{
fprintf(stderr, "Failed to open /dev/mem for reading (error %d)\n", errno);
goto cleanup;
}
fd3 = open("/dev/random", O_RDWR);
if(fd3 == -1)
{
fprintf(stderr, "Failed to open /dev/random for writing (error %d)\n", errno);
goto cleanup;
}
map1 = mmap (NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd1, CTRL_ADDR & PAGE_MASK);
if(map1 == MAP_FAILED)
{
fprintf(stderr, "Failed to map 0x100000D8 for control (error %d)\n", errno);
goto cleanup;
}
map2 = mmap (NULL, PAGE_SIZE, PROT_READ, MAP_SHARED, fd2, DATA_ADDR & PAGE_MASK);
if(map2 == MAP_FAILED)
{
fprintf(stderr, "Failed to map 0x100000DC for data (error %d)\n", errno);
goto cleanup;
}
const int off1 = CTRL_ADDR % PAGE_SIZE;
volatile uint32_t* volatile ctrl = (uint32_t*)((uint8_t*)map1+off1);
const int off2 = DATA_ADDR % PAGE_SIZE;
volatile uint32_t* volatile data = (uint32_t*)((uint8_t*)map2+off2);
entropy_t entropy = { .bit_count = 4096*8, .byte_count = 4096 };
int count = 4096/4, idx = 0;
while(count--)
{
/* If the delay from the loop drops too low, then we */
/* can watch the random values being shifted in. */
#define DELAY 5000
*ctrl = 0x01;
for(unsigned int i = 0; i < DELAY; i++) {
volatile uint32_t unused = *ctrl;
}
if(!print_only)
{
memcpy(entropy.buf+idx, (const void *)data, 4);
idx += 4;
}
else
{
if(isatty(fileno(stdout)))
fprintf(stdout, "0x%08x\n", *data);
else
write(fileno(stdout), (const void *)data, 4);
}
*ctrl = 0x00;
for(unsigned int i = 0; i < DELAY; i++) {
volatile uint32_t unused = *ctrl;
}
}
if(!print_only)
{
int rc = ioctl(fd3, RNDADDENTROPY, &entropy);
if(rc != 0)
{
fprintf(stderr, "Failed to add entropy (error %d)\n", errno);
goto cleanup;
}
}
ret = 0;
cleanup:
if(map2 != MAP_FAILED) { munmap(map2, PAGE_SIZE); }
if(map1 != MAP_FAILED) { munmap(map1, PAGE_SIZE); }
if(fd3 != -1) { close(fd3); }
if(fd2 != -1) { close(fd2); }
if(fd1 != -1) { close(fd1); }
return ret;
}
답변1
나는 장치가 "무작위" 데이터를 생성하는 알고리즘을 변경(약화?)하여 완전히 소진되지 않을 것이라고 추측합니다. 즉, "실제" 무작위 데이터를 무시하고 CSPNRG에 의존합니다.
방금 관련 질문을 했고 매뉴얼 페이지에서 답변을 찾았습니다 rngd
.
서비스 rnd-tools
는 프로그램을 호출합니다 /usr/sbin/rngd
. 찾다우분투 문서매개변수가 있는 것을 볼 수 있습니다.
-W n, --fill-watermark=nnn
이 작업을 시작하면 엔트로피를 제공하십시오.무작위 장비적어도워터마크 채우기 엔트로피 풀에는 사용 가능한 엔트로피 비트가 있습니다(기본값: 2048). 너무 높게 설정하면
rngd
엔트로피 풀의 내용을 제어합니다. 낮은 값은 엔트로피 결핍 기간 동안 시스템 성능을 저하시킬 수 있습니다. 설정되지 않음 워터마크 채우기엔트로피 풀의 크기(일반적으로 4096비트)보다 큽니다.
내 질문/답변여기 있어요.