]>
Commit | Line | Data |
---|---|---|
f1b59d26 | 1 | #include <splat-ctl.h> |
f1ca4da6 | 2 | |
3 | #define KZT_SUBSYSTEM_KRNG 0x0300 | |
4 | #define KZT_KRNG_NAME "krng" | |
5 | #define KZT_KRNG_DESC "Kernel Random Number Generator Tests" | |
6 | ||
7 | #define KZT_KRNG_TEST1_ID 0x0301 | |
8 | #define KZT_KRNG_TEST1_NAME "freq" | |
9 | #define KZT_KRNG_TEST1_DESC "Frequency Test" | |
10 | ||
11 | #define KRNG_NUM_BITS 1048576 | |
12 | #define KRNG_NUM_BYTES (KRNG_NUM_BITS >> 3) | |
13 | #define KRNG_NUM_BITS_DIV2 (KRNG_NUM_BITS >> 1) | |
14 | #define KRNG_ERROR_RANGE 2097 | |
15 | ||
16 | /* Random Number Generator Tests | |
17 | There can be meny more tests on quality of the | |
18 | random number generator. For now we are only | |
19 | testing the frequency of particular bits. | |
20 | We could also test consecutive sequences, | |
21 | randomness within a particular block, etc. | |
22 | but is probably not necessary for our purposes */ | |
23 | ||
24 | static int | |
25 | kzt_krng_test1(struct file *file, void *arg) | |
26 | { | |
27 | uint8_t *buf; | |
28 | int i, j, diff, num = 0, rc = 0; | |
29 | ||
30 | buf = kmalloc(sizeof(*buf) * KRNG_NUM_BYTES, GFP_KERNEL); | |
31 | if (buf == NULL) { | |
32 | rc = -ENOMEM; | |
33 | goto out; | |
34 | } | |
35 | ||
36 | memset(buf, 0, sizeof(*buf) * KRNG_NUM_BYTES); | |
37 | ||
38 | /* Always succeeds */ | |
39 | random_get_pseudo_bytes(buf, sizeof(uint8_t) * KRNG_NUM_BYTES); | |
40 | ||
41 | for (i = 0; i < KRNG_NUM_BYTES; i++) { | |
42 | uint8_t tmp = buf[i]; | |
43 | for (j = 0; j < 8; j++) { | |
44 | uint8_t tmp2 = ((tmp >> j) & 0x01); | |
45 | if (tmp2 == 1) { | |
46 | num++; | |
47 | } | |
48 | } | |
49 | } | |
50 | ||
51 | kfree(buf); | |
52 | ||
53 | diff = KRNG_NUM_BITS_DIV2 - num; | |
54 | if (diff < 0) | |
55 | diff *= -1; | |
56 | ||
57 | kzt_print(file, "Test 1 Number of ones: %d\n", num); | |
58 | kzt_print(file, "Test 1 Difference from expected: %d Allowed: %d\n", | |
59 | diff, KRNG_ERROR_RANGE); | |
60 | ||
61 | if (diff > KRNG_ERROR_RANGE) | |
62 | rc = -ERANGE; | |
63 | out: | |
64 | return rc; | |
65 | } | |
66 | ||
67 | kzt_subsystem_t * | |
68 | kzt_krng_init(void) | |
69 | { | |
70 | kzt_subsystem_t *sub; | |
71 | ||
72 | sub = kmalloc(sizeof(*sub), GFP_KERNEL); | |
73 | if (sub == NULL) | |
74 | return NULL; | |
75 | ||
76 | memset(sub, 0, sizeof(*sub)); | |
77 | strncpy(sub->desc.name, KZT_KRNG_NAME, KZT_NAME_SIZE); | |
78 | strncpy(sub->desc.desc, KZT_KRNG_DESC, KZT_DESC_SIZE); | |
79 | INIT_LIST_HEAD(&sub->subsystem_list); | |
80 | INIT_LIST_HEAD(&sub->test_list); | |
81 | spin_lock_init(&sub->test_lock); | |
82 | sub->desc.id = KZT_SUBSYSTEM_KRNG; | |
83 | ||
84 | KZT_TEST_INIT(sub, KZT_KRNG_TEST1_NAME, KZT_KRNG_TEST1_DESC, | |
85 | KZT_KRNG_TEST1_ID, kzt_krng_test1); | |
86 | ||
87 | return sub; | |
88 | } | |
89 | ||
90 | void | |
91 | kzt_krng_fini(kzt_subsystem_t *sub) | |
92 | { | |
93 | ASSERT(sub); | |
94 | ||
95 | KZT_TEST_FINI(sub, KZT_KRNG_TEST1_ID); | |
96 | ||
97 | kfree(sub); | |
98 | } | |
99 | ||
100 | int | |
101 | kzt_krng_id(void) { | |
102 | return KZT_SUBSYSTEM_KRNG; | |
103 | } |