10. DRBG Algorithm Specifications
讲述DRBG三种机制:
- 基于纯HASH的DRBG
- 基于HMAC的DRBG
- 基于分组密码+CTR的DRBG
10.1 DRBG Mechanisms Based on Hash Functions
10.1.1 Hash_DRBG
仅支持4种安全强度:112、128、192、256比特。
Supported security strengths和highest_supported_security_strength的值可以参见SP800-57的表3 Hash function that can be used to provide the targeted security strengths。
SHA224、SHA-384、SHA-512/224、SHA-512/256都不推荐使用。因为SHA224基于SHA256得到的,但输出比特又比SHA256少。后三个同理。
Hash_DRBG分四块讨论,内部状态、Instantiation函数、Reseeding函数、Generating函数。这三个函数分别对接第9章的三个相关函数。
10.1.1.1 Hash DRBG Internal State
内部状态构成:
- 工作状态
- V:长度为seedlen比特,每次调用都会更新。
- C:长度为seedlen比特,从seed计算出来的不变量。
- reseed_counter:长度为reseed_interval的长度(表2显示为48比特),记录Generate函数调用次数,每调用一次累加1。初始化和重置时为1。
- 管理信息
- security_strength:DRBG实例的安全强度
- prediction_resistance_flag:DRBG实例是否抵抗预测攻击的标识
10.3.1 Hash_df
注:本节从后面挪过来,以便相关内容放在一起。
有两种导出函数:(1)基于HASH算法的导出函数Hash_df;(2)基于分组密码算法的导出函数Block_Cipher_df。本节描述供Hash_DRBG使用的Hash_df。
函数:(status, requested_bits) = Hash_df (input_string, no_of_bits_to_return)
功能:基于HASH算法的导出函数
输入参数:
- input_string:输入的待HASH的数据。
- no_of_bits_to_return:期望的返回数据长度。
返回数据:
- status:执行结果。
- requested_bits:返回数据长度。
执行步骤:
步骤1:初始化临时数据串temp = NULL。
步骤2:
步骤3:初始化8比特整数counter = 0x01。
步骤4:For i = 1 to len 执行如下步骤.
-
- 4.1 temp = temp || Hash (counter || no_of_bits_to_return || input_string).
注:counter和no_of_bits_to_return分别表示为8和32比特字符串。
-
- 4.2 counter = counter + 1.
步骤5:requested_bits = leftmost (temp, no_of_bits_to_return).
步骤6:返回 (SUCCESS, requested_bits).
10.1.1.2 Hash DRBG Instantiate
函数:initial_working_state = Hash_DRBG_Instantiate_algorithm (entropy_input, nonce, personalization_string, security_strength)
功能:Hash DRBG实例化函数
输入参数:
- entropy_input:熵。
- nonce:临时数据。
- personalization_string:可选参数,提供个性化信息。允许的最大长度max_personalization_string_length = 235比特。
- security_strength:在Hash_DRBG中无用。
返回数据:
- initial_working_state:工作状态,记录了V、C、reseed_counter信息。
执行步骤:
步骤1:seed_material = entropy_input || nonce || personalization_string.
步骤2:seed = Hash_df (seed_material, seedlen).
步骤3:V = seed.
步骤4:C = Hash_df ((0x00 || V), seedlen)
步骤5:reseed_counter = 1.
步骤6:返回 (V, C, reseed_counter).
备注:
- Hash_DRBG 的Instantiate和Reseed函数的执行步骤几乎完全一样,仅第一步有差异:
- Instantiate:seed_material=entropy_input||nonce||personalization_string
- Reseed:seed_material = 0x01 || V || entropy_input || additional_input.
10.1.1.3 Hash DRBG Reseed
函数:new_working_state = Hash_DRBG_Reseed_algorithm (working_state, entropy_input, additional_input)
功能:Hash DRBG重新种子化函数
输入参数:
- working_state: 工作状态。
- entropy_input: 熵。
- additional_input: 可选参数,附加信息。
返回数据:
- new_working_state:新工作状态,记录了V、C、reseed_counter信息。
执行步骤:
步骤1:seed_material = 0x01 || V || entropy_input || additional_input.
步骤2:seed = Hash_df (seed_material, seedlen).
步骤3:V = seed.
步骤4:C = Hash_df ((0x00 || V), seedlen)
步骤5:reseed_counter = 1.
步骤6:返回 (V, C, reseed_counter).
备注:
- Hash_DRBG 的Instantiate和Reseed函数的执行步骤几乎完全一样,仅第一步有差异:
- Instantiate:seed_material=entropy_input||nonce||personalization_string
- Reseed:seed_material = 0x01 || V || entropy_input || additional_input.
10.1.1.4 Hash DRBG Generate
函数:(status, returned_bits, new_working_state) = Hash_DRBG_Generate_algorithm (working_state, requested_number_of_bits, additional_input)
功能:Hash DRBG生成随机比特
输入参数:
- working_state: 工作状态。
- requested_number_of_bits: 请求的比特数。
- additional_input: 可选参数,附加信息。
内部调用函数:
- Hashgen:派生出一段数据,类似Hash_df,参见本节末尾。
返回数据:
- status: 函数返回标识,成功SUCCESS 或者错误码。
- returned_bitss:生成的随机比特数量。
- new_working_stat:新工作状态,记录了V、C、reseed_counter信息。
执行步骤:
步骤1:若 reseed_counter > reseed_interval,返回错误标识,请求先执行reseed函数。
步骤2:若 additional_input 非空串,执行如下步骤:
-
- 2.1 w = Hash (0x02 || V || additional_input).
- 2.2 V = (V + w) mod 2seedlen
步骤3:returned_bits = Hashgen (requested_number_of_bits, V).
步骤4:H = Hash (0x03 || V).
步骤5:V = (V + H + C + reseed_counter) mod 2seedlen .
步骤6:reseed_counter = reseed_counter + 1.
步骤7:返回(SUCCESS, returned_bits V, C, reseed_counter).
10.1.1.4+ Hashgen
函数:returned_bits = Hashgen (requested_no_of_bits, V)
功能:Hash DRBG数据派生函数
输入参数:
- requested_no_of_bits:请求的比特数。
- V:Hash DRBG工作状态中的V信息。
返回数据:
- returned_bitss:生成的随机比特数量。
执行步骤:
步骤1: (注1:向上取整;注2:outlen是HASH函数的输出比特长度)
步骤2:data = V.
步骤3:初始化临时数据串W = NULL.
步骤4:For i = 1 to m
-
- 4.1 w = Hash (data).
- 4.2 W = W || w.
- 4.3 data = (data + 1) mod 2seedlen .
步骤5:returned_bits = leftmost (W, requested_no_of_bits).
步骤6:返回 returned_bits。
10.1.2 HMAC_DRBG
仅支持4种安全强度:112、128、192、256比特。
Supported security strengths和highest_supported_security_strength的值可以参见SP800-57的表3 Hash function that can be used to provide the targeted security strengths。
SHA224、SHA-384、SHA-512/224、SHA-512/256都不推荐使用。因为SHA224基于SHA256得到的,但输出比特又比SHA256少。后三个同理。
10.1.2.1 HMAC DRBGInternal State
内部状态构成:
- 工作状态
- V:长度为outlen比特,每次调用都会更新。
- Key:长度为outlen比特,每次调用都会更新。
- reseed_counter:长度为reseed_interval的长度(表2显示为48比特),记录Generate函数调用次数,每调用一次累加1。初始化和重置时置为1。
- 管理信息
- security_strength:DRBG实例的安全强度
- prediction_resistance_flag:DRBG实例是否抵抗预测攻击的标识
10.1.2.2 HMAC DRBG Update
这是后面三个函数都会调用的Key和V的状态更新函数。
函数:(K, V) = HMAC_DRBG_Update (provided_data, K, V)
功能:Hash DRBG的Key和V的状态更新函数
输入参数:
- provided_data:输入数据。
- K:当前Key值。
- V:当前V值。
返回数据:
- K:新的Key值。
- V:新的V值。
执行步骤:
步骤1:K = HMAC (K, V || 0x00 || provided_data)
步骤2:V = HMAC (K, V).
步骤3:若 provided_data 为空串,返回 (K, V).
步骤4:K = HMAC (K, V || 0x01 || provided_data).
步骤5:V = HMAC (K, V).
步骤6:返回 (K, V).
10.1.2.3 HMAC DRBG Instantiate
函数:initial_working_state = HMAC_DRBG_Instantiate_algorithm (entropy_input, nonce, personalization_string, security_strength)
功能:HMAC DRBG实例化函数
输入参数:
- entropy_input:熵。
- nonce:临时数据。
- personalization_string:可选参数,提供个性化信息。允许的最大长度max_personalization_string_length = 235比特。
- security_strength:在Hash_DRBG中无用。
返回数据:
- initial_working_state:工作状态,记录了V、C、reseed_counter信息。
执行步骤:
步骤1:seed_material = entropy_input || nonce || personalization_string.
步骤2:初始化Key = 0x00 00...00 (outlen比特)
步骤3:初始化V = 0x01 01...01. (outlen比特)
步骤4:更新(Key, V) = HMAC_DRBG_Update (seed_material, Key, V)
步骤5:reseed_counter = 1.
步骤6:返回 (V, Key, reseed_counter).
HMAC Instantiate 和Ressed执行流程比较。
步骤 |
HMAC Instantiate |
HMAC Ressed |
1 生成seed_material |
异 seed_material = entropy_input || nonce || personalization_string. |
异 seed_material = entropy_input || additional_input. |
2初始化Key和V |
异 初始化为特定值 |
异 无需初始化 |
3更新Key和V |
同 |
同 |
4重置reseed_counter |
同 |
同 |
5返回 |
同 |
同 |
10.1.2.4 HMAC DRBG Reseed
函数:new_working_state = HMAC_DRBG_Reseed_algorithm (working_state, entropy_input, additional_input)
功能:HMAC DRBG重新种子化函数
输入参数:
- working_state: 工作状态。
- entropy_input: 熵。
- additional_input: 可选参数,附加信息。
返回数据:
- new_working_state:新工作状态,记录了V、C、reseed_counter信息。
执行步骤:
步骤1:seed_material = entropy_input || additional_input.
步骤2:更新(Key, V) = HMAC_DRBG_Update (seed_material, Key, V).
步骤3:reseed_counter = 1.
步骤4:返回 (V, Key, reseed_counter).
HMAC Instantiate 和Ressed执行流程比较。
步骤 |
HMAC Instantiate |
HMAC Ressed |
1 生成seed_material |
异 seed_material = entropy_input || nonce || personalization_string. |
异 seed_material = entropy_input || additional_input. |
2初始化Key和V |
异 初始化为特定值 |
异 无需初始化 |
3更新Key和V |
同 |
同 |
4重置reseed_counter |
同 |
同 |
5返回 |
同 |
同 |
10.1.2.5 HMAC DRBG Generate
函数:(status, returned_bits, new_working_state) = HMAC_DRBG_Generate_algorithm (working_state, requested_number_of_bits, additional_input)
功能:HMAC DRBG生成随机比特
输入参数:
- working_state: 工作状态。
- requested_number_of_bits: 请求的比特数。
- additional_input: 可选参数,附加信息。
返回数据:
- status: 函数返回标识,成功SUCCESS 或者错误码。
- returned_bitss:生成的随机比特数量。
- new_working_stat:新工作状态,记录了V、Key、reseed_counter信息。
执行步骤:
步骤1:若 reseed_counter > reseed_interval,返回错误标识,请求先执行reseed函数。
步骤2:若 additional_input 非空串,(Key, V) = HMAC_DRBG_Update (additional_input, Key, V)
步骤3:初始化临时字符串temp = NULL.
步骤4:While ( len (temp) < requested_number_of_bits ) 执行如下步骤
-
- 4.1 V = HMAC (Key, V).
- 4.2 temp = temp || V.
步骤5:returned_bits = leftmost (temp, requested_number_of_bits).
步骤6:(Key, V) = HMAC_DRBG_Update (additional_input, Key, V).
步骤7:reseed_counter = reseed_counter + 1.
步骤8:返回 (SUCCESS, returned_bits, Key, V, reseed_counter).
10.2 DRBG Mechanism Based on Block Ciphers
10.2.1 CTR_DRBG
表 CTR_DRBG定义
CTR_DRBG分四块讨论,内部状态、Instantiation函数、Reseeding函数、Generating函数。这三个函数分别对接第9章的三个相关函数。
10.2.1.1 CTR DRBG Internal State
内部状态构成:
- 工作状态
- V:长度为blocklen(分组大小)比特,每次调用都会更新。
- Key:长度为seedlen比特,每次调用都会更新。
- counter:长度为reseed_interval的长度(CTR_DRBGd的表显示,TDES对应32比特,AES任一版本均对应48比特),记录Generate函数调用次数,每调用一次累加1。初始化和重置时置为1。
- 管理信息
- security_strength:DRBG实例的安全强度
- prediction_resistance_flag:DRBG实例是否抵抗预测攻击的标识
10.3.2 Block_Cipher_df
注:本节从后面挪过来,以便相关内容放在一起。
有两种导出函数:(1)基于HASH算法的导出函数Hash_df;(2)基于分组密码算法的导出函数Block_Cipher_df。本节描述供CTR_DRBG使用的导出函数Block_Cipher_df。
函数:(status, requested_bits) = Block_Cipher_df (input_string, no_of_bits_to_return)
功能:基于分组密码算法的导出函数
输入参数:
- input_string:输入的待HASH数据。
- no_of_bits_to_return:期望的返回数据长度。最大不能超过max_number_of_bits(对当前密码算法而言,为512比特)。
内部调用函数:
- BCC:即CBC-MAC:CBC加密 + IV为0 + 返回最后一个密文。
返回数据:
- status:执行结果。
- requested_bits:返回数据长度。
执行步骤:
步骤1:若 number_of_bits_to_return > max_number_of_bits(此为512比特),返回(ERROR_FLAG, NULL)。
步骤2:32比特整数L = len (input_string)/8。
步骤3:32比特整数N = number_of_bits_to_return/8。
步骤4:S = L || N || input_string || 0x80,其中L和N表示为32比特整数。
步骤5:在S后添零补足。While ( len (S) mod outlen ) ≠ 0, do S = S || 0x00.
步骤6:初始化字符串 temp = NULL。.
步骤7:32比特整数i = 0。
步骤8:K = leftmost (0x00010203...1D1E1F, keylen).
步骤9:While ( len (temp) < keylen + outlen ), 执行如下步骤
-
- 9.1 IV = i || 0outlen -len (i),其中len(i)=32
- 9.2 temp = temp || BCC (K, (IV || S)).
- 9.3 i = i + 1.
步骤10:K = leftmost (temp, keylen).
步骤11:X = select (temp, keylen+1, keylen+outlen).
注:即K|| X= temp
步骤12:重置字符串temp = NULL.
步骤13:While ( len (temp) < number_of_bits_to_return ), 执行如下步骤
-
- 13.1 X = Block_Encrypt (K, X).
- 13.2 temp = temp || X.
步骤14:requested_bits = leftmost (temp, number_of_bits_to_return).
步骤15:返回 (SUCCESS, requested_bits).
10.2.1.2 CTR DRBG Update
函数:(Key, V) = CTR_DRBG_Update (provided_data, Key, V)
功能:CTR DRBG更新Key和V的函数
输入参数:
- provided_data:任意数据,长度必需是seedlen比特(上层调用函数提供此保障)。
- Key:当前的Key值。
- V:当前的V值。
内部调用函数:
- Block_Encrypt (Key, V).:分组算法ECB加密V,密钥为Key,参见10.3.3。
返回数据:
- Key:新的Key值。
- V:新的V值。
执行步骤:
步骤1:临时数据串temp = NULL.
步骤2:While ( len (temp) < seedlen ) 执行如下步骤
-
- 2.1 V = (V+1) mod 2ctr_len
- 2.2 output_block = Block_Encrypt (Key, V).
- 2.3 temp = temp || output_block.
步骤3:temp = leftmost (temp, seedlen).
步骤4:temp = temp ? provided_data.
步骤5:Key = leftmost (temp, keylen).
步骤6:V = rightmost (temp, blocklen).
注:因为keylen + outlen = seedlen,所以Key || V = temp
步骤7:返回 (Key, V).
10.2.1.3 CTR DRBG Instantiate
本节将使用导出函数和不适用导出函数的情况糅合在一起。
函数:initial_working_state = CTR_DRBG_Instantiate_algorithm (entropy_input, nonce, personalization_string, security_strength)
功能:CTR DRBG实例化函数
输入参数:
- entropy_input:熵。
- nonce:临时数据。使用导出函数nonce无效;不使用导出函数nonce有效。
- personalization_string:可选参数,提供个性化信息。允许的最大长度max_personalization_string_length = 235比特。
- security_strength:安全强度,可选参数(在后续流程中未见使用)。
内部调用函数:
- df:导出函数,参见10.3.2。
返回数据:
- initial_working_state:工作状态,记录了V、C、reseed_counter信息。
执行步骤:
步骤1:按如下步骤计算长度刚好为seedlen比特的seed_material。
1a 若不使用导出函数df,执行如下步骤
-
-
-
- 1a.1 temp = len (personalization_string)
- 1a.2 personalization_string = personalization_string || 0seedlen-temp
- 1a.3 seed_material = entropy_input ? personalization_string.
-
-
1b 否则(使用导出函数),执行如下步骤
-
-
-
- 1b.1 seed_material = entropy_input || nonce||personalization_string
- 1b.2 seed_material = df (seed_material, seedlen)(保证长度刚好为seedlen比特)
-
-
步骤2:初始化Key = 0keylen (keylen比特的全零串)
步骤3:初始化V = 0blocklen (blocklen比特的全零串)
步骤4:更新(Key, V) = CTR_DRBG_Update (seed_material, Key, V).
步骤5:初始化reseed_counter = 1.
步骤6:返回 (V, Key, reseed_counter)
10.2.1.4 CTR DRBG Reseed
本节将使用导出函数和不适用导出函数的情况糅合在一起。
函数:new_working_state = CTR_DRBG_Reseed_algorithm (working_state, entropy_input, additional_input)
功能:CTR DRBG重新种子化函数
输入参数:
- working_state: 工作状态。
- entropy_input: 熵。
- additional_input: 可选参数,附加信息。
内部调用函数:
- Hash_df:基于HASH的派生函数,参见10.3.1。
返回数据:
- new_working_state:新工作状态,记录了V、C、reseed_counter信息。
执行步骤:
步骤1:按如下步骤计算长度刚好为seedlen比特的seed_material。
1a 若不使用导出函数df,执行如下步骤
-
-
-
- 1a.1 temp = len (additional_input)
- 1a.2 additional_input = additional_input || 0seedlen -temp.
- 1a.3 seed_material = entropy_input ? additional_input
-
-
1b 否则(使用导出函数),执行如下步骤
-
-
-
- 1b.1 seed_material = entropy_input || additional_input
- 1b.2 seed_material = df (seed_material, seedlen)(保证长度刚好为seedlen比特)
-
-
步骤2:更新(Key, V) = CTR_DRBG_Update (seed_material, Key, V).
步骤3:重置reseed_counter = 1.
步骤4:返回 (V, Key, reseed_counter).
Instantiate和Reseed函数的执行过程很相似。
步骤 |
CTR Instantiate |
CTR Reseed |
|
1生成seed_material |
不使用df |
相似 personalization_string换成additional_input |
相似 personalization_string换成additional_input |
使用df |
相似nonce||personalization_string换成additional_input |
相似nonce||personalization_string换成additional_input |
|
2-3初始化Key和V |
异 需要初始化 |
异 不需要初始化 |
|
4更新(Key, V) |
同 |
同 |
|
5重置reseed_counter |
同 |
同 |
|
6返回 |
同 |
同 |
10.2.1.5 CTR DRBG Generate
本节将使用导出函数和不使用导出函数的情况糅合在一起。
函数:(status, returned_bits, new_working_state) = CTR_DRBG_Generate_algorithm (working_state, requested_number_of_bits, additional_input)
功能:CTR DRBG生成随机比特
输入参数:
- working_state: 工作状态。
- requested_number_of_bits: 请求的比特数。
- additional_input: 可选参数,附加信息。
内部调用函数:
- Block_Cipher_df:基于分组密码算法的派生函数,参见10.3.2。
- Block_Encrypt:基于分组密码算法ECB加密。
返回数据:
- status: 函数返回标识,成功SUCCESS 或者错误码。
- returned_bits:生成的随机比特数量。
- new_working_state:新工作状态,记录了V、C、reseed_counter信息。
执行步骤:
步骤1:若 reseed_counter > reseed_interval,返回错误标识,请求先执行reseed函数。
步骤2:计算additional_input。
2a 若additional_input 为空串,additional_input = 0seedlen。
2b 否则(additional_input 非空串),执行如下步骤:
-
- 2b.1 初始化additional_input。
- 不使用Block_Cipher_df时,additional_input = additional_input || 0seedlen –temp,其中temp = len (additional_input).
- 使用Block_Cipher_df时,additional_input = Block_Cipher_df (additional_input, seedlen).
- 2b.2 更新(Key, V) = CTR_DRBG_Update (additional_input, Key, V).
- 2b.1 初始化additional_input。
步骤3:初始化临时字符串temp = NULL
步骤4:While ( len (temp) < requested_number_of_bits ) 执行如下步骤:
-
- 4.1 V = (V+1) mod 2 ctr_len
- 4.2 output_block = Block_Encrypt (Key, V).
- 4.3 temp = temp || output_block.
步骤5:returned_bits = leftmost (temp, requested_number_of_bits).
步骤6:(Key, V) = CTR_DRBG_Update (additional_input, Key, V).
步骤7:reseed_counter = reseed_counter + 1.
步骤8:返回 (SUCCESS, returned_bits, Key, V, reseed_counter).
10.3 Auxiliary Functions
两种导出函数:
- 基于HASH算法的导出函数Hash_df,放置于10.1.1节中描述。
- 基于分组密码算法的导出函数Block_Cipher_df,放置于10.2.1节中描述。