diff options
Diffstat (limited to 'crypto/drbg.c')
-rw-r--r-- | crypto/drbg.c | 81 |
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 | ||
1044 | static 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 | ||
1122 | out: | 1128 | out: |
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 | ||
1209 | err: | 1236 | err: |