wpa_supplicant: Write Crypto API based on mbedtls

This commit add following crypto changes

1. Update current crypto code with upstream supplicant code
2. Add a proper porting layer to use mbedtls APIs for all the crypto
   operations used by supplicant.

Internal crypto will be used when USE_MBEDLTS flag is disabled
in supplicant's menuconfig.

This commit also removes the clutter in crypto files due to partial
porting of some APIs to mbedtls, all the code from those files have
been removed and rewritten in a generic way, this is inspired from
current upstream code.

This also reduces the lib size significantly, supplicant's lib
size reduces around ~567kb after this change(NB: lib size doesn't
indicate reduction in final bin size).
This commit is contained in:
kapil.gupta
2020-09-14 13:51:25 +05:30
committed by bot
parent 639e7ad494
commit ad7cb5f5c1
68 changed files with 2009 additions and 1746 deletions

View File

@@ -6,10 +6,9 @@
* See README for more details.
*/
#include "includes.h"
#include "utils/includes.h"
#include "utils/common.h"
#include "common.h"
#include "sha1.h"
#include "ms_funcs.h"
#include "crypto.h"
@@ -24,8 +23,8 @@
* Returns: 0 on success, -1 on failure
*/
static int utf8_to_ucs2(const u8 *utf8_string, size_t utf8_string_len,
u8 *ucs2_buffer, size_t ucs2_buffer_size,
size_t *ucs2_string_size)
u8 *ucs2_buffer, size_t ucs2_buffer_size,
size_t *ucs2_string_size)
{
size_t i, j;
@@ -49,7 +48,7 @@ static int utf8_to_ucs2(const u8 *utf8_string, size_t utf8_string_len,
WPA_PUT_LE16(ucs2_buffer + j,
((c & 0x1F) << 6) | (c2 & 0x3F));
j += 2;
} else if (i == utf8_string_len ||
} else if (i == utf8_string_len - 1 ||
j >= ucs2_buffer_size - 1) {
/* incomplete surrogate */
return -1;
@@ -59,6 +58,7 @@ static int utf8_to_ucs2(const u8 *utf8_string, size_t utf8_string_len,
WPA_PUT_LE16(ucs2_buffer + j,
((c & 0xF) << 12) |
((c2 & 0x3F) << 6) | (c3 & 0x3F));
j += 2;
}
}
}
@@ -78,9 +78,8 @@ static int utf8_to_ucs2(const u8 *utf8_string, size_t utf8_string_len,
* @challenge: 8-octet Challenge (OUT)
* Returns: 0 on success, -1 on failure
*/
static int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge,
const u8 *username, size_t username_len,
u8 *challenge)
int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge,
const u8 *username, size_t username_len, u8 *challenge)
{
u8 hash[SHA1_MAC_LEN];
const unsigned char *addr[3];
@@ -108,7 +107,7 @@ static int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge,
* Returns: 0 on success, -1 on failure
*/
int nt_password_hash(const u8 *password, size_t password_len,
u8 *password_hash)
u8 *password_hash)
{
u8 buf[512], *pos;
size_t len, max_len;
@@ -141,17 +140,20 @@ int hash_nt_password_hash(const u8 *password_hash, u8 *password_hash_hash)
* @challenge: 8-octet Challenge (IN)
* @password_hash: 16-octet PasswordHash (IN)
* @response: 24-octet Response (OUT)
* Returns: 0 on success, -1 on failure
*/
void challenge_response(const u8 *challenge, const u8 *password_hash,
u8 *response)
int challenge_response(const u8 *challenge, const u8 *password_hash,
u8 *response)
{
u8 zpwd[7];
des_encrypt(challenge, password_hash, response);
des_encrypt(challenge, password_hash + 7, response + 8);
if (des_encrypt(challenge, password_hash, response) < 0 ||
des_encrypt(challenge, password_hash + 7, response + 8) < 0)
return -1;
zpwd[0] = password_hash[14];
zpwd[1] = password_hash[15];
os_memset(zpwd + 2, 0, 5);
des_encrypt(challenge, zpwd, response + 16);
return des_encrypt(challenge, zpwd, response + 16);
}
@@ -167,19 +169,18 @@ void challenge_response(const u8 *challenge, const u8 *password_hash,
* Returns: 0 on success, -1 on failure
*/
int generate_nt_response(const u8 *auth_challenge, const u8 *peer_challenge,
const u8 *username, size_t username_len,
const u8 *password, size_t password_len,
u8 *response)
const u8 *username, size_t username_len,
const u8 *password, size_t password_len,
u8 *response)
{
u8 challenge[8];
u8 password_hash[16];
if (challenge_hash(peer_challenge, auth_challenge, username,
username_len, challenge))
username_len, challenge) ||
nt_password_hash(password, password_len, password_hash) ||
challenge_response(challenge, password_hash, response))
return -1;
if (nt_password_hash(password, password_len, password_hash))
return -1;
challenge_response(challenge, password_hash, response);
return 0;
}
@@ -195,18 +196,18 @@ int generate_nt_response(const u8 *auth_challenge, const u8 *peer_challenge,
* Returns: 0 on success, -1 on failure
*/
int generate_nt_response_pwhash(const u8 *auth_challenge,
const u8 *peer_challenge,
const u8 *username, size_t username_len,
const u8 *password_hash,
u8 *response)
const u8 *peer_challenge,
const u8 *username, size_t username_len,
const u8 *password_hash,
u8 *response)
{
u8 challenge[8];
if (challenge_hash(peer_challenge, auth_challenge,
username, username_len,
challenge))
challenge) ||
challenge_response(challenge, password_hash, response))
return -1;
challenge_response(challenge, password_hash, response);
return 0;
}
@@ -257,12 +258,9 @@ int generate_authenticator_response_pwhash(
addr2[1] = challenge;
addr2[2] = magic2;
if (hash_nt_password_hash(password_hash, password_hash_hash))
return -1;
if (sha1_vector(3, addr1, len1, response))
return -1;
if (challenge_hash(peer_challenge, auth_challenge, username,
if (hash_nt_password_hash(password_hash, password_hash_hash) ||
sha1_vector(3, addr1, len1, response) ||
challenge_hash(peer_challenge, auth_challenge, username,
username_len, challenge))
return -1;
return sha1_vector(3, addr2, len2, response);
@@ -283,10 +281,10 @@ int generate_authenticator_response_pwhash(
* Returns: 0 on success, -1 on failure
*/
int generate_authenticator_response(const u8 *password, size_t password_len,
const u8 *peer_challenge,
const u8 *auth_challenge,
const u8 *username, size_t username_len,
const u8 *nt_response, u8 *response)
const u8 *peer_challenge,
const u8 *auth_challenge,
const u8 *username, size_t username_len,
const u8 *nt_response, u8 *response)
{
u8 password_hash[16];
if (nt_password_hash(password, password_len, password_hash))
@@ -306,12 +304,13 @@ int generate_authenticator_response(const u8 *password, size_t password_len,
* Returns: 0 on success, -1 on failure
*/
int nt_challenge_response(const u8 *challenge, const u8 *password,
size_t password_len, u8 *response)
size_t password_len, u8 *response)
{
u8 password_hash[16];
if (nt_password_hash(password, password_len, password_hash))
if (nt_password_hash(password, password_len, password_hash) ||
challenge_response(challenge, password_hash, response))
return -1;
challenge_response(challenge, password_hash, response);
return 0;
}
@@ -324,7 +323,7 @@ int nt_challenge_response(const u8 *challenge, const u8 *password,
* Returns: 0 on success, -1 on failure
*/
int get_master_key(const u8 *password_hash_hash, const u8 *nt_response,
u8 *master_key)
u8 *master_key)
{
static const u8 magic1[27] = {
0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
@@ -356,8 +355,8 @@ int get_master_key(const u8 *password_hash_hash, const u8 *nt_response,
* Returns: 0 on success, -1 on failure
*/
int get_asymetric_start_key(const u8 *master_key, u8 *session_key,
size_t session_key_len, int is_send,
int is_server)
size_t session_key_len, int is_send,
int is_server)
{
static const u8 magic2[84] = {
0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
@@ -417,6 +416,8 @@ int get_asymetric_start_key(const u8 *master_key, u8 *session_key,
}
#ifndef CONFIG_NO_RC4
#define PWBLOCK_LEN 516
/**
@@ -436,10 +437,8 @@ int encrypt_pw_block_with_password_hash(
os_memset(pw_block, 0, PWBLOCK_LEN);
if (utf8_to_ucs2(password, password_len, pw_block, 512, &ucs2_len) < 0)
return -1;
if (ucs2_len > 256)
if (utf8_to_ucs2(password, password_len, pw_block, 512, &ucs2_len) < 0
|| ucs2_len > 256)
return -1;
offset = (256 - ucs2_len) * 2;
@@ -484,18 +483,23 @@ int new_password_encrypted_with_old_nt_password_hash(
return 0;
}
#endif /* CONFIG_NO_RC4 */
/**
* nt_password_hash_encrypted_with_block - NtPasswordHashEncryptedWithBlock() - RFC 2759, Sect 8.13
* @password_hash: 16-octer PasswordHash (IN)
* @block: 16-octet Block (IN)
* @cypher: 16-octer Cypher (OUT)
* Returns: 0 on success, -1 on failure
*/
void nt_password_hash_encrypted_with_block(const u8 *password_hash,
const u8 *block, u8 *cypher)
int nt_password_hash_encrypted_with_block(const u8 *password_hash,
const u8 *block, u8 *cypher)
{
des_encrypt(password_hash, block, cypher);
des_encrypt(password_hash + 8, block + 7, cypher + 8);
if (des_encrypt(password_hash, block, cypher) < 0 ||
des_encrypt(password_hash + 8, block + 7, cypher + 8) < 0)
return -1;
return 0;
}
@@ -518,10 +522,10 @@ int old_nt_password_hash_encrypted_with_new_nt_password_hash(
if (nt_password_hash(old_password, old_password_len,
old_password_hash) ||
nt_password_hash(new_password, new_password_len,
new_password_hash))
new_password_hash) ||
nt_password_hash_encrypted_with_block(old_password_hash,
new_password_hash,
encrypted_password_hash))
return -1;
nt_password_hash_encrypted_with_block(old_password_hash,
new_password_hash,
encrypted_password_hash);
return 0;
}