27 RCSID(
"$Id: 3f2145ae9ddcdc921489fa204c8300ebf3cc0624 $")
31 #include <freeradius-devel/tls/base.h>
32 #include <freeradius-devel/eap/tls.h>
34 #include <freeradius-devel/tls/openssl_user_macros.h>
35 #include <openssl/evp.h>
36 #include <openssl/aes.h>
37 #include <openssl/err.h>
42 void T_PRF(
unsigned char const *
secret,
unsigned int secret_len,
43 char const *prf_label,
44 unsigned char const *seed,
unsigned int seed_len,
45 unsigned char *
out,
unsigned int out_len)
47 size_t prf_size = strlen(prf_label);
51 if (prf_size > 128) prf_size = 128;
64 #define MIN(a,b) (((a)>(b)) ? (b) : (a))
68 while (pos < out_len) {
87 unsigned long errCode;
89 fprintf(stderr,
"An error occurred\n");
90 while((errCode = ERR_get_error()))
92 char *
err = ERR_error_string(errCode, NULL);
93 fprintf(stderr,
"%s\n",
err);
100 uint8_t const *aad,
size_t aad_len,
115 if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
119 if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL))
123 if (1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
handleErrors();
128 if (1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len))
134 if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
136 ciphertext_len = len;
141 if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
handleErrors();
142 ciphertext_len += len;
145 if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag))
149 EVP_CIPHER_CTX_free(ctx);
151 return ciphertext_len;
155 uint8_t const *aad,
size_t aad_len,
167 if (!EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL))
171 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL))
175 if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv))
handleErrors();
180 if (!EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len))
186 if (!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len))
193 memcpy(&tmp, &tag,
sizeof(tmp));
196 if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tmp))
handleErrors();
202 ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
205 EVP_CIPHER_CTX_free(ctx);
210 plaintext_len += len;
211 return plaintext_len;
222 EVP_MD
const *evp_md,
224 uint8_t const *seed,
size_t seed_len)
226 EVP_MD_CTX *ctx_a, *ctx_out;
232 ctx_a = EVP_MD_CTX_new();
233 ctx_out = EVP_MD_CTX_new();
235 MEM(pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
secret, secret_len));
237 EVP_DigestSignInit(ctx_a, NULL, evp_md, NULL, pkey);
238 EVP_DigestSignInit(ctx_out, NULL, evp_md, NULL, pkey);
240 size = EVP_MD_size(evp_md);
243 EVP_DigestSignUpdate(ctx_a, seed, seed_len);
248 EVP_DigestSignFinal(ctx_a, a, &(
size_t){
sizeof(a) });
252 EVP_DigestSignUpdate(ctx_out, a, size);
253 EVP_DigestSignUpdate(ctx_out, seed, seed_len);
256 if (out_len < size) {
257 EVP_DigestSignFinal(ctx_out, a, &(
size_t){
sizeof(a) });
258 memcpy(
out, a, out_len);
263 EVP_DigestSignFinal(ctx_out,
out, &(
size_t){ EVP_MAX_MD_SIZE });
264 EVP_MD_CTX_reset(ctx_out);
266 EVP_DigestSignInit(ctx_out, NULL, evp_md, NULL, pkey);
271 EVP_MD_CTX_reset(ctx_a);
272 EVP_DigestSignInit(ctx_a, NULL, evp_md, NULL, pkey);
273 EVP_DigestSignUpdate(ctx_a, a, size);
274 EVP_DigestSignFinal(ctx_a, a, &(
size_t){ EVP_MAX_MD_SIZE });
279 EVP_MD_CTX_free(ctx_a);
280 EVP_MD_CTX_free(ctx_out);
281 #ifdef __STDC_LIB_EXT1__
282 memset_s(a, 0,
sizeof(a),
sizeof(a));
284 memset(a, 0,
sizeof(a));
291 uint8_t const *seed,
size_t seed_len)
294 unsigned int len = (secret_len + 1) / 2;
301 for (i = 0; i < out_len; i++)
out[i] ^= scratch[i];
311 size_t len, master_key_len;
312 uint8_t seed[128 + (2 * SSL3_RANDOM_SIZE)];
313 uint8_t master_key[SSL_MAX_MASTER_KEY_LENGTH];
315 len = strlen(prf_label);
316 if (len > 128) len = 128;
319 memcpy(p, prf_label, len);
321 (void) SSL_get_server_random(s, p, SSL3_RANDOM_SIZE);
322 p += SSL3_RANDOM_SIZE;
323 (void) SSL_get_client_random(s, p, SSL3_RANDOM_SIZE);
324 p += SSL3_RANDOM_SIZE;
326 master_key_len = SSL_SESSION_get_master_key(SSL_get_session(s), master_key,
sizeof(master_key));
static int const char char buffer[256]
#define USES_APPLE_DEPRECATED_API
#define NEVER_RETURNS
Should be placed before the function return type.
int eap_fast_decrypt(uint8_t const *ciphertext, size_t ciphertext_len, uint8_t const *aad, size_t aad_len, uint8_t const *tag, uint8_t const *key, uint8_t const *iv, uint8_t *plaintext)
static NEVER_RETURNS void handleErrors(void)
void eap_fast_tls_gen_challenge(SSL *s, uint8_t *buffer, uint8_t *scratch, size_t size, char const *prf_label)
int eap_fast_encrypt(uint8_t const *plaintext, size_t plaintext_len, uint8_t const *aad, size_t aad_len, uint8_t const *key, uint8_t *iv, unsigned char *ciphertext, uint8_t *tag)
static void crypto_rfc4346_p_hash(uint8_t *out, size_t out_len, EVP_MD const *evp_md, uint8_t const *secret, size_t secret_len, uint8_t const *seed, size_t seed_len)
USES_APPLE_DEPRECATED_API void T_PRF(unsigned char const *secret, unsigned int secret_len, char const *prf_label, unsigned char const *seed, unsigned int seed_len, unsigned char *out, unsigned int out_len)
static void eap_crypto_rfc4346_prf(uint8_t *out, size_t out_len, uint8_t *scratch, uint8_t const *secret, size_t secret_len, uint8_t const *seed, size_t seed_len)
Crypto function declarations.
int fr_hmac_sha1(uint8_t digest[static SHA1_DIGEST_LENGTH], uint8_t const *in, size_t inlen, uint8_t const *key, size_t key_len)
Calculate HMAC using internal SHA1 implementation.
#define SHA1_DIGEST_LENGTH
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
static size_t char ** out