summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/drbg.c52
-rw-r--r--include/crypto/drbg.h1
2 files changed, 46 insertions, 7 deletions
diff --git a/crypto/drbg.c b/crypto/drbg.c
index aca86847ea49..92843488af09 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1062,13 +1062,18 @@ static void drbg_async_seed(struct work_struct *work)
1062 LIST_HEAD(seedlist); 1062 LIST_HEAD(seedlist);
1063 struct drbg_state *drbg = container_of(work, struct drbg_state, 1063 struct drbg_state *drbg = container_of(work, struct drbg_state,
1064 seed_work); 1064 seed_work);
1065 int ret;
1065 1066
1066 get_blocking_random_bytes(drbg->seed_buf, drbg->seed_buf_len); 1067 get_blocking_random_bytes(drbg->seed_buf, drbg->seed_buf_len);
1067 1068
1068 drbg_string_fill(&data, drbg->seed_buf, drbg->seed_buf_len); 1069 drbg_string_fill(&data, drbg->seed_buf, drbg->seed_buf_len);
1069 list_add_tail(&data.list, &seedlist); 1070 list_add_tail(&data.list, &seedlist);
1070 mutex_lock(&drbg->drbg_mutex); 1071 mutex_lock(&drbg->drbg_mutex);
1071 __drbg_seed(drbg, &seedlist, true); 1072 ret = __drbg_seed(drbg, &seedlist, true);
1073 if (!ret && drbg->jent) {
1074 crypto_free_rng(drbg->jent);
1075 drbg->jent = NULL;
1076 }
1072 memzero_explicit(drbg->seed_buf, drbg->seed_buf_len); 1077 memzero_explicit(drbg->seed_buf, drbg->seed_buf_len);
1073 mutex_unlock(&drbg->drbg_mutex); 1078 mutex_unlock(&drbg->drbg_mutex);
1074} 1079}
@@ -1103,10 +1108,24 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
1103 drbg->test_data.len); 1108 drbg->test_data.len);
1104 pr_devel("DRBG: using test entropy\n"); 1109 pr_devel("DRBG: using test entropy\n");
1105 } else { 1110 } else {
1106 pr_devel("DRBG: (re)seeding with %zu bytes of entropy\n", 1111 /* Get seed from in-kernel /dev/urandom */
1107 drbg->seed_buf_len);
1108 get_random_bytes(drbg->seed_buf, drbg->seed_buf_len); 1112 get_random_bytes(drbg->seed_buf, drbg->seed_buf_len);
1109 drbg_string_fill(&data1, drbg->seed_buf, drbg->seed_buf_len); 1113
1114 /* Get seed from Jitter RNG */
1115 if (!drbg->jent ||
1116 crypto_rng_get_bytes(drbg->jent,
1117 drbg->seed_buf + drbg->seed_buf_len,
1118 drbg->seed_buf_len)) {
1119 drbg_string_fill(&data1, drbg->seed_buf,
1120 drbg->seed_buf_len);
1121 pr_devel("DRBG: (re)seeding with %zu bytes of entropy\n",
1122 drbg->seed_buf_len);
1123 } else {
1124 drbg_string_fill(&data1, drbg->seed_buf,
1125 drbg->seed_buf_len * 2);
1126 pr_devel("DRBG: (re)seeding with %zu bytes of entropy\n",
1127 drbg->seed_buf_len * 2);
1128 }
1110 } 1129 }
1111 list_add_tail(&data1.list, &seedlist); 1130 list_add_tail(&data1.list, &seedlist);
1112 1131
@@ -1131,7 +1150,7 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
1131 * Clear the initial entropy buffer as the async call may not overwrite 1150 * Clear the initial entropy buffer as the async call may not overwrite
1132 * that buffer for quite some time. 1151 * that buffer for quite some time.
1133 */ 1152 */
1134 memzero_explicit(drbg->seed_buf, drbg->seed_buf_len); 1153 memzero_explicit(drbg->seed_buf, drbg->seed_buf_len * 2);
1135 if (ret) 1154 if (ret)
1136 goto out; 1155 goto out;
1137 /* 1156 /*
@@ -1171,6 +1190,10 @@ static inline void drbg_dealloc_state(struct drbg_state *drbg)
1171#endif 1190#endif
1172 kzfree(drbg->seed_buf); 1191 kzfree(drbg->seed_buf);
1173 drbg->seed_buf = NULL; 1192 drbg->seed_buf = NULL;
1193 if (drbg->jent) {
1194 crypto_free_rng(drbg->jent);
1195 drbg->jent = NULL;
1196 }
1174} 1197}
1175 1198
1176/* 1199/*
@@ -1246,14 +1269,29 @@ static inline int drbg_alloc_state(struct drbg_state *drbg)
1246 ret = -EFAULT; 1269 ret = -EFAULT;
1247 goto err; 1270 goto err;
1248 } 1271 }
1249 /* ensure we have sufficient buffer space for initial seed */ 1272 /*
1273 * Ensure we have sufficient buffer space for initial seed which
1274 * consists of the seed from get_random_bytes and the Jitter RNG.
1275 */
1250 drbg->seed_buf_len = ((drbg->seed_buf_len + 1) / 2) * 3; 1276 drbg->seed_buf_len = ((drbg->seed_buf_len + 1) / 2) * 3;
1251 drbg->seed_buf = kzalloc(drbg->seed_buf_len, GFP_KERNEL); 1277 drbg->seed_buf = kzalloc(drbg->seed_buf_len * 2, GFP_KERNEL);
1252 if (!drbg->seed_buf) 1278 if (!drbg->seed_buf)
1253 goto err; 1279 goto err;
1254 1280
1255 INIT_WORK(&drbg->seed_work, drbg_async_seed); 1281 INIT_WORK(&drbg->seed_work, drbg_async_seed);
1256 1282
1283 drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0);
1284 if(IS_ERR(drbg->jent))
1285 {
1286 pr_info("DRBG: could not allocate Jitter RNG handle for seeding\n");
1287 /*
1288 * As the Jitter RNG is a module that may not be present, we
1289 * continue with the operation and do not fully tie the DRBG
1290 * to the Jitter RNG.
1291 */
1292 drbg->jent = NULL;
1293 }
1294
1257 return 0; 1295 return 0;
1258 1296
1259err: 1297err:
diff --git a/include/crypto/drbg.h b/include/crypto/drbg.h
index 46994b25dc85..c3f208dc83ee 100644
--- a/include/crypto/drbg.h
+++ b/include/crypto/drbg.h
@@ -123,6 +123,7 @@ struct drbg_state {
123 struct work_struct seed_work; /* asynchronous seeding support */ 123 struct work_struct seed_work; /* asynchronous seeding support */
124 u8 *seed_buf; /* buffer holding the seed */ 124 u8 *seed_buf; /* buffer holding the seed */
125 size_t seed_buf_len; 125 size_t seed_buf_len;
126 struct crypto_rng *jent;
126 const struct drbg_state_ops *d_ops; 127 const struct drbg_state_ops *d_ops;
127 const struct drbg_core *core; 128 const struct drbg_core *core;
128 struct drbg_string test_data; 129 struct drbg_string test_data;