mirror of
				https://git.kernel.org/pub/scm/network/wireless/iwd.git
				synced 2025-10-31 04:57:25 +01:00 
			
		
		
		
	eapol: encrypt key data for AKM-defined ciphers
Support encrypting key data when the cipher is AKM-defined. This is needed to support SAE in AP mode.
This commit is contained in:
		
							parent
							
								
									3132e9f595
								
							
						
					
					
						commit
						78bdb26296
					
				
							
								
								
									
										53
									
								
								src/eapol.c
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								src/eapol.c
									
									
									
									
									
								
							| @ -387,6 +387,23 @@ error: | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| static int padded_aes_wrap(const uint8_t *kek, uint8_t *key_data, | ||||
| 				size_t *key_data_len, | ||||
| 				struct eapol_key *out_frame, size_t mic_len) | ||||
| { | ||||
| 	if (*key_data_len < 16 || *key_data_len % 8) | ||||
| 		key_data[(*key_data_len)++] = 0xdd; | ||||
| 	while (*key_data_len < 16 || *key_data_len % 8) | ||||
| 		key_data[(*key_data_len)++] = 0x00; | ||||
| 
 | ||||
| 	if (!aes_wrap(kek, key_data, *key_data_len, | ||||
| 				EAPOL_KEY_DATA(out_frame, mic_len))) | ||||
| 		return -ENOPROTOOPT; | ||||
| 
 | ||||
| 	*key_data_len += 8; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Pad and encrypt the plaintext Key Data contents in @key_data using | ||||
|  * the encryption scheme required by @out_frame->key_descriptor_version, | ||||
| @ -395,12 +412,12 @@ error: | ||||
|  * Note that for efficiency @key_data is being modified, including in | ||||
|  * case of failure, so it must be sufficiently larger than @key_data_len. | ||||
|  */ | ||||
| static int eapol_encrypt_key_data(const uint8_t *kek, uint8_t *key_data, | ||||
| 				size_t key_data_len, | ||||
| static int eapol_encrypt_key_data(enum ie_rsn_akm_suite akm, const uint8_t *kek, | ||||
| 				uint8_t *key_data, size_t key_data_len, | ||||
| 				struct eapol_key *out_frame, size_t mic_len) | ||||
| { | ||||
| 	uint8_t key[32]; | ||||
| 	bool ret; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	switch (out_frame->key_descriptor_version) { | ||||
| 	case EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_MD5_ARC4: | ||||
| @ -426,18 +443,23 @@ static int eapol_encrypt_key_data(const uint8_t *kek, uint8_t *key_data, | ||||
| 		break; | ||||
| 	case EAPOL_KEY_DESCRIPTOR_VERSION_HMAC_SHA1_AES: | ||||
| 	case EAPOL_KEY_DESCRIPTOR_VERSION_AES_128_CMAC_AES: | ||||
| 		if (key_data_len < 16 || key_data_len % 8) | ||||
| 			key_data[key_data_len++] = 0xdd; | ||||
| 		while (key_data_len < 16 || key_data_len % 8) | ||||
| 			key_data[key_data_len++] = 0x00; | ||||
| 
 | ||||
| 		if (!aes_wrap(kek, key_data, key_data_len, | ||||
| 					EAPOL_KEY_DATA(out_frame, mic_len))) | ||||
| 			return -ENOPROTOOPT; | ||||
| 
 | ||||
| 		key_data_len += 8; | ||||
| 		ret = padded_aes_wrap(kek, key_data, &key_data_len, | ||||
| 					out_frame, mic_len); | ||||
| 		if (ret < 0) | ||||
| 			return ret; | ||||
| 
 | ||||
| 		break; | ||||
| 	case EAPOL_KEY_DESCRIPTOR_VERSION_AKM_DEFINED: | ||||
| 		switch (akm) { | ||||
| 		case IE_RSN_AKM_SUITE_SAE_SHA256: | ||||
| 			ret = padded_aes_wrap(kek, key_data, &key_data_len, | ||||
| 						out_frame, mic_len); | ||||
| 			if (ret < 0) | ||||
| 				return ret; | ||||
| 			break; | ||||
| 		default: | ||||
| 			return -ENOTSUP; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	l_put_be16(key_data_len, EAPOL_KEY_DATA(out_frame, mic_len) - 2); | ||||
| @ -1467,8 +1489,9 @@ static void eapol_send_ptk_3_of_4(struct eapol_sm *sm) | ||||
| 	} | ||||
| 
 | ||||
| 	kek = handshake_state_get_kek(sm->handshake); | ||||
| 	key_data_len = eapol_encrypt_key_data(kek, key_data_buf, | ||||
| 						key_data_len, ek, sm->mic_len); | ||||
| 	key_data_len = eapol_encrypt_key_data(sm->handshake->akm_suite, kek, | ||||
| 						key_data_buf, key_data_len, ek, | ||||
| 						sm->mic_len); | ||||
| 	explicit_bzero(key_data_buf, sizeof(key_data_buf)); | ||||
| 
 | ||||
| 	if (key_data_len < 0) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 John Brandt
						John Brandt