summaryrefslogtreecommitdiffstats
path: root/crypto/drbg.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/drbg.c')
-rw-r--r--crypto/drbg.c81
1 files changed, 54 insertions, 27 deletions
diff --git a/crypto/drbg.c b/crypto/drbg.c
index 23d444ed3176..36dfece45e88 100644
--- a/crypto/drbg.c
+++ b/crypto/drbg.c
@@ -1041,6 +1041,21 @@ static struct drbg_state_ops drbg_hash_ops = {
1041 * Functions common for DRBG implementations 1041 * Functions common for DRBG implementations
1042 ******************************************************************/ 1042 ******************************************************************/
1043 1043
1044static inline int __drbg_seed(struct drbg_state *drbg, struct list_head *seed,
1045 int reseed)
1046{
1047 int ret = drbg->d_ops->update(drbg, seed, reseed);
1048
1049 if (ret)
1050 return ret;
1051
1052 drbg->seeded = true;
1053 /* 10.1.1.2 / 10.1.1.3 step 5 */
1054 drbg->reseed_ctr = 1;
1055
1056 return ret;
1057}
1058
1044/* 1059/*
1045 * Seeding or reseeding of the DRBG 1060 * Seeding or reseeding of the DRBG
1046 * 1061 *
@@ -1056,8 +1071,6 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
1056 bool reseed) 1071 bool reseed)
1057{ 1072{
1058 int ret = 0; 1073 int ret = 0;
1059 unsigned char *entropy = NULL;
1060 size_t entropylen = 0;
1061 struct drbg_string data1; 1074 struct drbg_string data1;
1062 LIST_HEAD(seedlist); 1075 LIST_HEAD(seedlist);
1063 1076
@@ -1073,26 +1086,10 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
1073 drbg->test_data.len); 1086 drbg->test_data.len);
1074 pr_devel("DRBG: using test entropy\n"); 1087 pr_devel("DRBG: using test entropy\n");
1075 } else { 1088 } else {
1076 /*
1077 * Gather entropy equal to the security strength of the DRBG.
1078 * With a derivation function, a nonce is required in addition
1079 * to the entropy. A nonce must be at least 1/2 of the security
1080 * strength of the DRBG in size. Thus, entropy * nonce is 3/2
1081 * of the strength. The consideration of a nonce is only
1082 * applicable during initial seeding.
1083 */
1084 entropylen = drbg_sec_strength(drbg->core->flags);
1085 if (!entropylen)
1086 return -EFAULT;
1087 if (!reseed)
1088 entropylen = ((entropylen + 1) / 2) * 3;
1089 pr_devel("DRBG: (re)seeding with %zu bytes of entropy\n", 1089 pr_devel("DRBG: (re)seeding with %zu bytes of entropy\n",
1090 entropylen); 1090 drbg->seed_buf_len);
1091 entropy = kzalloc(entropylen, GFP_KERNEL); 1091 get_random_bytes(drbg->seed_buf, drbg->seed_buf_len);
1092 if (!entropy) 1092 drbg_string_fill(&data1, drbg->seed_buf, drbg->seed_buf_len);
1093 return -ENOMEM;
1094 get_random_bytes(entropy, entropylen);
1095 drbg_string_fill(&data1, entropy, entropylen);
1096 } 1093 }
1097 list_add_tail(&data1.list, &seedlist); 1094 list_add_tail(&data1.list, &seedlist);
1098 1095
@@ -1111,16 +1108,24 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
1111 memset(drbg->C, 0, drbg_statelen(drbg)); 1108 memset(drbg->C, 0, drbg_statelen(drbg));
1112 } 1109 }
1113 1110
1114 ret = drbg->d_ops->update(drbg, &seedlist, reseed); 1111 ret = __drbg_seed(drbg, &seedlist, reseed);
1112
1113 /*
1114 * Clear the initial entropy buffer as the async call may not overwrite
1115 * that buffer for quite some time.
1116 */
1117 memzero_explicit(drbg->seed_buf, drbg->seed_buf_len);
1115 if (ret) 1118 if (ret)
1116 goto out; 1119 goto out;
1117 1120 /*
1118 drbg->seeded = true; 1121 * For all subsequent seeding calls, we only need the seed buffer
1119 /* 10.1.1.2 / 10.1.1.3 step 5 */ 1122 * equal to the security strength of the DRBG. We undo the calculation
1120 drbg->reseed_ctr = 1; 1123 * in drbg_alloc_state.
1124 */
1125 if (!reseed)
1126 drbg->seed_buf_len = drbg->seed_buf_len / 3 * 2;
1121 1127
1122out: 1128out:
1123 kzfree(entropy);
1124 return ret; 1129 return ret;
1125} 1130}
1126 1131
@@ -1143,6 +1148,8 @@ static inline void drbg_dealloc_state(struct drbg_state *drbg)
1143 drbg->prev = NULL; 1148 drbg->prev = NULL;
1144 drbg->fips_primed = false; 1149 drbg->fips_primed = false;
1145#endif 1150#endif
1151 kzfree(drbg->seed_buf);
1152 drbg->seed_buf = NULL;
1146} 1153}
1147 1154
1148/* 1155/*
@@ -1204,6 +1211,26 @@ static inline int drbg_alloc_state(struct drbg_state *drbg)
1204 if (!drbg->scratchpad) 1211 if (!drbg->scratchpad)
1205 goto err; 1212 goto err;
1206 } 1213 }
1214
1215 /*
1216 * Gather entropy equal to the security strength of the DRBG.
1217 * With a derivation function, a nonce is required in addition
1218 * to the entropy. A nonce must be at least 1/2 of the security
1219 * strength of the DRBG in size. Thus, entropy * nonce is 3/2
1220 * of the strength. The consideration of a nonce is only
1221 * applicable during initial seeding.
1222 */
1223 drbg->seed_buf_len = drbg_sec_strength(drbg->core->flags);
1224 if (!drbg->seed_buf_len) {
1225 ret = -EFAULT;
1226 goto err;
1227 }
1228 /* ensure we have sufficient buffer space for initial seed */
1229 drbg->seed_buf_len = ((drbg->seed_buf_len + 1) / 2) * 3;
1230 drbg->seed_buf = kzalloc(drbg->seed_buf_len, GFP_KERNEL);
1231 if (!drbg->seed_buf)
1232 goto err;
1233
1207 return 0; 1234 return 0;
1208 1235
1209err: 1236err: