mirror of
				https://git.kernel.org/pub/scm/network/wireless/iwd.git
				synced 2025-10-31 13:17:25 +01:00 
			
		
		
		
	crypto: allow hkdf_expand/extract to use different SHA's
Rather than hard coding to SHA256, we can pass in l_checksum_type and use that SHA. This will allow for OWE/SAE/PWD to support more curves that use different SHA algorithms for hashing.
This commit is contained in:
		
							parent
							
								
									90c39afd61
								
							
						
					
					
						commit
						7bfaf182e6
					
				
							
								
								
									
										36
									
								
								src/crypto.c
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								src/crypto.c
									
									
									
									
									
								
							| @ -418,19 +418,24 @@ bool kdf_sha256(const void *key, size_t key_len, | ||||
|  * | ||||
|  * Null key equates to a zero key (makes calls in EAP-PWD more convenient) | ||||
|  */ | ||||
| bool hkdf_extract_sha256(const uint8_t *key, size_t key_len, uint8_t num_args, | ||||
| 			uint8_t *out, ...) | ||||
| bool hkdf_extract(enum l_checksum_type type, const uint8_t *key, | ||||
| 				size_t key_len, uint8_t num_args, | ||||
| 				uint8_t *out, ...) | ||||
| { | ||||
| 	struct l_checksum *hmac; | ||||
| 	struct iovec iov[num_args]; | ||||
| 	const uint8_t zero_key[32] = { 0 }; | ||||
| 	const uint8_t zero_key[64] = { 0 }; | ||||
| 	size_t dlen = l_checksum_digest_length(type); | ||||
| 	const uint8_t *k = key ? key : zero_key; | ||||
| 	size_t k_len = key ? key_len : 32; | ||||
| 	size_t k_len = key ? key_len : dlen; | ||||
| 	va_list va; | ||||
| 	int i; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	hmac = l_checksum_new_hmac(L_CHECKSUM_SHA256, k, k_len); | ||||
| 	if (dlen <= 0) | ||||
| 		return false; | ||||
| 
 | ||||
| 	hmac = l_checksum_new_hmac(type, k, k_len); | ||||
| 	if (!hmac) | ||||
| 		return false; | ||||
| 
 | ||||
| @ -446,27 +451,32 @@ bool hkdf_extract_sha256(const uint8_t *key, size_t key_len, uint8_t num_args, | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = l_checksum_get_digest(hmac, out, 32); | ||||
| 	ret = l_checksum_get_digest(hmac, out, dlen); | ||||
| 	l_checksum_free(hmac); | ||||
| 
 | ||||
| 	va_end(va); | ||||
| 	return (ret == 32); | ||||
| 	return (ret == (int) dlen); | ||||
| } | ||||
| 
 | ||||
| bool hkdf_expand_sha256(const uint8_t *key, size_t key_len, const char *info, | ||||
| 			size_t info_len, void *out, size_t out_len) | ||||
| bool hkdf_expand(enum l_checksum_type type, const uint8_t *key, size_t key_len, | ||||
| 			const char *info, size_t info_len, void *out, | ||||
| 			size_t out_len) | ||||
| { | ||||
| 	uint8_t t[32]; | ||||
| 	uint8_t t[64]; | ||||
| 	size_t t_len = 0; | ||||
| 	struct iovec iov[3]; | ||||
| 	struct l_checksum *hmac; | ||||
| 	uint8_t count = 1; | ||||
| 	uint8_t *out_ptr = out; | ||||
| 	size_t dlen = l_checksum_digest_length(type); | ||||
| 
 | ||||
| 	if (dlen <= 0) | ||||
| 		return false; | ||||
| 
 | ||||
| 	while (out_len > 0) { | ||||
| 		ssize_t ret; | ||||
| 
 | ||||
| 		hmac = l_checksum_new_hmac(L_CHECKSUM_SHA256, key, key_len); | ||||
| 		hmac = l_checksum_new_hmac(type, key, key_len); | ||||
| 
 | ||||
| 		iov[0].iov_base = t; | ||||
| 		iov[0].iov_len = t_len; | ||||
| @ -481,7 +491,7 @@ bool hkdf_expand_sha256(const uint8_t *key, size_t key_len, const char *info, | ||||
| 		} | ||||
| 
 | ||||
| 		ret = l_checksum_get_digest(hmac, t, | ||||
| 						(out_len > 32) ? 32 : out_len); | ||||
| 					(out_len > dlen) ? dlen : out_len); | ||||
| 		if (ret < 0) { | ||||
| 			l_checksum_free(hmac); | ||||
| 			return false; | ||||
| @ -495,7 +505,7 @@ bool hkdf_expand_sha256(const uint8_t *key, size_t key_len, const char *info, | ||||
| 		 * RFC specifies that T(0) = empty string, so after the first | ||||
| 		 * iteration we update the length for T(1)...T(N) | ||||
| 		 */ | ||||
| 		t_len = 32; | ||||
| 		t_len = dlen; | ||||
| 		count++; | ||||
| 
 | ||||
| 		l_checksum_free(hmac); | ||||
|  | ||||
| @ -89,11 +89,12 @@ bool kdf_sha256(const void *key, size_t key_len, | ||||
| bool prf_sha1(const void *key, size_t key_len, | ||||
| 		const void *prefix, size_t prefix_len, | ||||
| 		const void *data, size_t data_len, void *output, size_t size); | ||||
| bool hkdf_extract_sha256(const uint8_t *key, size_t key_len, uint8_t num_args, | ||||
| 			uint8_t *out, ...); | ||||
| bool hkdf_extract(enum l_checksum_type type, const uint8_t *key, size_t key_len, | ||||
| 				uint8_t num_args, uint8_t *out, ...); | ||||
| 
 | ||||
| bool hkdf_expand_sha256(const uint8_t *key, size_t key_len, const char *info, | ||||
| 			size_t info_len, void *out, size_t out_len); | ||||
| bool hkdf_expand(enum l_checksum_type type, const uint8_t *key, size_t key_len, | ||||
| 				const char *info, size_t info_len, void *out, | ||||
| 				size_t out_len); | ||||
| 
 | ||||
| bool crypto_derive_pairwise_ptk(const uint8_t *pmk, size_t pmk_len, | ||||
| 				const uint8_t *addr1, const uint8_t *addr2, | ||||
|  | ||||
| @ -293,7 +293,7 @@ static void eap_pwd_handle_id(struct eap_state *eap, | ||||
| 
 | ||||
| 	while (counter < 20) { | ||||
| 		/* pwd-seed = H(token|peer-ID|server-ID|password|counter) */ | ||||
| 		hkdf_extract_sha256(NULL, 0, 5, pwd_seed, &token, 4, | ||||
| 		hkdf_extract(L_CHECKSUM_SHA256, NULL, 0, 5, pwd_seed, &token, 4, | ||||
| 				pwd->identity, strlen(pwd->identity), pkt + 9, | ||||
| 				len - 9, pwd->password, strlen(pwd->password), | ||||
| 				&counter, 1); | ||||
| @ -488,13 +488,14 @@ static void eap_pwd_handle_confirm(struct eap_state *eap, | ||||
| 	 * compute Confirm_P = H(kp | Element_P | Scalar_P | | ||||
| 	 *                       Element_S | Scalar_S | Ciphersuite) | ||||
| 	 */ | ||||
| 	hkdf_extract_sha256(NULL, 0, 6, confirm_p, kpx, clen, element_p, plen, | ||||
| 				scalar_p, clen, element_s, plen, scalar_s, | ||||
| 				clen, &pwd->ciphersuite, 4); | ||||
| 	hkdf_extract(L_CHECKSUM_SHA256, NULL, 0, 6, confirm_p, kpx, clen, | ||||
| 				element_p, plen, scalar_p, clen, element_s, | ||||
| 				plen, scalar_s, clen, &pwd->ciphersuite, 4); | ||||
| 
 | ||||
| 	hkdf_extract_sha256(NULL, 0, 6, expected_confirm_s, kpx, clen, | ||||
| 				element_s, plen, scalar_s, clen, element_p, | ||||
| 				plen, scalar_p, clen, &pwd->ciphersuite, 4); | ||||
| 	hkdf_extract(L_CHECKSUM_SHA256, NULL, 0, 6, expected_confirm_s, kpx, | ||||
| 				clen, element_s, plen, scalar_s, clen, | ||||
| 				element_p, plen, scalar_p, clen, | ||||
| 				&pwd->ciphersuite, 4); | ||||
| 
 | ||||
| 	if (memcmp(confirm_s, expected_confirm_s, 32)) { | ||||
| 		l_error("Confirm_S did not verify"); | ||||
| @ -507,7 +508,7 @@ static void eap_pwd_handle_confirm(struct eap_state *eap, | ||||
| 	pos += 32; | ||||
| 
 | ||||
| 	/* derive MK = H(kp | Confirm_P | Confirm_S ) */ | ||||
| 	hkdf_extract_sha256(NULL, 0, 3, mk, kpx, clen, confirm_p, | ||||
| 	hkdf_extract(L_CHECKSUM_SHA256, NULL, 0, 3, mk, kpx, clen, confirm_p, | ||||
| 			32, confirm_s, 32); | ||||
| 
 | ||||
| 	eap_pwd_send_response(eap, resp, pos - resp); | ||||
| @ -515,8 +516,8 @@ static void eap_pwd_handle_confirm(struct eap_state *eap, | ||||
| 	eap_method_success(eap); | ||||
| 
 | ||||
| 	session_id[0] = 52; | ||||
| 	hkdf_extract_sha256(NULL, 0, 3, session_id + 1, &pwd->ciphersuite, 4, | ||||
| 			scalar_p, clen, scalar_s, clen); | ||||
| 	hkdf_extract(L_CHECKSUM_SHA256, NULL, 0, 3, session_id + 1, | ||||
| 			&pwd->ciphersuite, 4, scalar_p, clen, scalar_s, clen); | ||||
| 
 | ||||
| 	kdf(mk, 32, (const char *) session_id, 33, msk_emsk, 128); | ||||
| 	eap_set_key_material(eap, msk_emsk, 64, msk_emsk + 64, 64, NULL, 0); | ||||
|  | ||||
| @ -157,11 +157,11 @@ static bool owe_compute_keys(struct owe_sm *owe, const void *public_key, | ||||
| 	l_put_le16(OWE_DEFAULT_GROUP, key + 64); | ||||
| 
 | ||||
| 	/* prk = HKDF-extract(C | A | group, z) */ | ||||
| 	if (!hkdf_extract_sha256(key, 66, 1, prk, ss_buf, 32)) | ||||
| 	if (!hkdf_extract(L_CHECKSUM_SHA256, key, 66, 1, prk, ss_buf, 32)) | ||||
| 		goto failed; | ||||
| 
 | ||||
| 	/* PMK = HKDF-expand(prk, "OWE Key Generation", n) */ | ||||
| 	if (!hkdf_expand_sha256(prk, 32, "OWE Key Generation", | ||||
| 	if (!hkdf_expand(L_CHECKSUM_SHA256, prk, 32, "OWE Key Generation", | ||||
| 				strlen("OWE Key Generation"), pmk, 32)) | ||||
| 		goto failed; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 James Prestwood
						James Prestwood