Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
s390
crypto
prng.c
Go to the documentation of this file.
1
/*
2
* Copyright IBM Corp. 2006, 2007
3
* Author(s): Jan Glauber <
[email protected]
>
4
* Driver for the s390 pseudo random number generator
5
*/
6
#include <linux/fs.h>
7
#include <
linux/init.h
>
8
#include <linux/kernel.h>
9
#include <
linux/miscdevice.h
>
10
#include <linux/module.h>
11
#include <
linux/moduleparam.h
>
12
#include <linux/random.h>
13
#include <linux/slab.h>
14
#include <asm/debug.h>
15
#include <asm/uaccess.h>
16
17
#include "
crypt_s390.h
"
18
19
MODULE_LICENSE
(
"GPL"
);
20
MODULE_AUTHOR
(
"Jan Glauber <
[email protected]
>"
);
21
MODULE_DESCRIPTION
(
"s390 PRNG interface"
);
22
23
static
int
prng_chunk_size = 256;
24
module_param
(prng_chunk_size,
int
,
S_IRUSR
|
S_IRGRP
|
S_IROTH
);
25
MODULE_PARM_DESC
(prng_chunk_size,
"PRNG read chunk size in bytes"
);
26
27
static
int
prng_entropy_limit = 4096;
28
module_param
(prng_entropy_limit,
int
,
S_IRUSR
|
S_IRGRP
|
S_IROTH
|
S_IWUSR
);
29
MODULE_PARM_DESC
(prng_entropy_limit,
30
"PRNG add entropy after that much bytes were produced"
);
31
32
/*
33
* Any one who considers arithmetical methods of producing random digits is,
34
* of course, in a state of sin. -- John von Neumann
35
*/
36
37
struct
s390_prng_data
{
38
unsigned
long
count
;
/* how many bytes were produced */
39
char
*
buf
;
40
};
41
42
static
struct
s390_prng_data
*
p
;
43
44
/* copied from libica, use a non-zero initial parameter block */
45
static
unsigned
char
parm_block[32] = {
46
0x0F,0x2B,0x8E,0x63,0x8C,0x8E,0xD2,0x52,0x64,0xB7,0xA0,0x7B,0x75,0x28,0xB8,0xF4,
47
0x75,0x5F,0xD2,0xA6,0x8D,0x97,0x11,0xFF,0x49,0xD8,0x23,0xF3,0x7E,0x21,0xEC,0xA0,
48
};
49
50
static
int
prng_open(
struct
inode
*
inode
,
struct
file
*
file
)
51
{
52
return
nonseekable_open
(inode, file);
53
}
54
55
static
void
prng_add_entropy(
void
)
56
{
57
__u64
entropy[4];
58
unsigned
int
i
;
59
int
ret
;
60
61
for
(i = 0; i < 16; i++) {
62
ret = crypt_s390_kmc(
KMC_PRNG
, parm_block, (
char
*)entropy,
63
(
char
*)entropy,
sizeof
(entropy));
64
BUG_ON
(ret < 0 || ret !=
sizeof
(entropy));
65
memcpy
(parm_block, entropy,
sizeof
(entropy));
66
}
67
}
68
69
static
void
prng_seed(
int
nbytes
)
70
{
71
char
buf
[16];
72
int
i = 0;
73
74
BUG_ON
(nbytes > 16);
75
get_random_bytes
(buf, nbytes);
76
77
/* Add the entropy */
78
while
(nbytes >= 8) {
79
*((
__u64
*)parm_block) ^= *((
__u64
*)(buf+i));
80
prng_add_entropy();
81
i += 8;
82
nbytes -= 8;
83
}
84
prng_add_entropy();
85
}
86
87
static
ssize_t
prng_read(
struct
file
*
file
,
char
__user *ubuf,
size_t
nbytes,
88
loff_t *ppos)
89
{
90
int
chunk
,
n
;
91
int
ret = 0;
92
int
tmp
;
93
94
/* nbytes can be arbitrary length, we split it into chunks */
95
while
(nbytes) {
96
/* same as in extract_entropy_user in random.c */
97
if
(need_resched()) {
98
if
(signal_pending(
current
)) {
99
if
(ret == 0)
100
ret = -
ERESTARTSYS
;
101
break
;
102
}
103
schedule
();
104
}
105
106
/*
107
* we lose some random bytes if an attacker issues
108
* reads < 8 bytes, but we don't care
109
*/
110
chunk =
min_t
(
int
, nbytes, prng_chunk_size);
111
112
/* PRNG only likes multiples of 8 bytes */
113
n = (chunk + 7) & -8;
114
115
if
(p->
count
> prng_entropy_limit)
116
prng_seed(8);
117
118
/* if the CPU supports PRNG stckf is present too */
119
asm
volatile
(
".insn s,0xb27c0000,%0"
120
:
"=m"
(*((
unsigned
long
long
*)p->
buf
)) : :
"cc"
);
121
122
/*
123
* Beside the STCKF the input for the TDES-EDE is the output
124
* of the last operation. We differ here from X9.17 since we
125
* only store one timestamp into the buffer. Padding the whole
126
* buffer with timestamps does not improve security, since
127
* successive stckf have nearly constant offsets.
128
* If an attacker knows the first timestamp it would be
129
* trivial to guess the additional values. One timestamp
130
* is therefore enough and still guarantees unique input values.
131
*
132
* Note: you can still get strict X9.17 conformity by setting
133
* prng_chunk_size to 8 bytes.
134
*/
135
tmp = crypt_s390_kmc(
KMC_PRNG
, parm_block, p->
buf
, p->
buf
, n);
136
BUG_ON
((tmp < 0) || (tmp != n));
137
138
p->
count
+=
n
;
139
140
if
(
copy_to_user
(ubuf, p->
buf
, chunk))
141
return
-
EFAULT
;
142
143
nbytes -=
chunk
;
144
ret +=
chunk
;
145
ubuf +=
chunk
;
146
}
147
return
ret
;
148
}
149
150
static
const
struct
file_operations
prng_fops = {
151
.owner =
THIS_MODULE
,
152
.open = &prng_open,
153
.release =
NULL
,
154
.read = &prng_read,
155
.llseek =
noop_llseek
,
156
};
157
158
static
struct
miscdevice
prng_dev = {
159
.name =
"prandom"
,
160
.minor =
MISC_DYNAMIC_MINOR
,
161
.fops = &prng_fops,
162
};
163
164
static
int
__init
prng_init(
void
)
165
{
166
int
ret
;
167
168
/* check if the CPU has a PRNG */
169
if
(!crypt_s390_func_available(
KMC_PRNG
,
CRYPT_S390_MSA
))
170
return
-
EOPNOTSUPP
;
171
172
if
(prng_chunk_size < 8)
173
return
-
EINVAL
;
174
175
p =
kmalloc
(
sizeof
(
struct
s390_prng_data
),
GFP_KERNEL
);
176
if
(!p)
177
return
-
ENOMEM
;
178
p->
count
= 0;
179
180
p->
buf
=
kmalloc
(prng_chunk_size,
GFP_KERNEL
);
181
if
(!p->
buf
) {
182
ret = -
ENOMEM
;
183
goto
out_free;
184
}
185
186
/* initialize the PRNG, add 128 bits of entropy */
187
prng_seed(16);
188
189
ret =
misc_register
(&prng_dev);
190
if
(ret)
191
goto
out_buf;
192
return
0;
193
194
out_buf:
195
kfree
(p->
buf
);
196
out_free:
197
kfree
(p);
198
return
ret
;
199
}
200
201
static
void
__exit
prng_exit(
void
)
202
{
203
/* wipe me */
204
kzfree
(p->
buf
);
205
kfree
(p);
206
207
misc_deregister
(&prng_dev);
208
}
209
210
module_init
(prng_init);
211
module_exit
(prng_exit);
Generated on Thu Jan 10 2013 13:16:35 for Linux Kernel by
1.8.2