diff options
-rw-r--r-- | crypto/drbg.c | 52 | ||||
-rw-r--r-- | include/crypto/drbg.h | 1 |
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 | ||
1259 | err: | 1297 | err: |
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; |