static int x25519_keycheck(const EC_KEY *eckey) { const char *pubkey; if (eckey->pub_key == NULL) return 0; pubkey = eckey->pub_key->custom_data; if (pubkey == NULL) return 0; if (eckey->custom_data != NULL) { uint8_t tmp[EC_X25519_KEYLEN]; /* Check eckey->priv_key exists and matches eckey->custom_data */ if (eckey->priv_key == NULL) return 0; if (BN_bn2lebinpad(eckey->priv_key, tmp, EC_X25519_KEYLEN) != EC_X25519_KEYLEN || CRYPTO_memcmp(tmp, eckey->custom_data, EC_X25519_KEYLEN) != 0) { OPENSSL_cleanse(tmp, EC_X25519_KEYLEN); return 0; } X25519_public_from_private(tmp, eckey->custom_data); if (CRYPTO_memcmp(pubkey, tmp, EC_X25519_KEYLEN) == 0) return 1; return 0; } else { return 1; } }
static bool check_hmac(struct onion *onion, const struct hmackey *hmackey) { struct sha256 hmac; make_hmac(onion->hop, MAX_HOPS, NULL, hmackey, &hmac); return CRYPTO_memcmp(&hmac, &myhop(onion)->hmac, sizeof(hmac)) == 0; }
int ssl3_get_finished(SSL *s, int a, int b) { int al, i, ok; long n; unsigned char *p; #ifdef OPENSSL_NO_NEXTPROTONEG /* * the mac has already been generated when we received the change cipher * spec message and is in s->s3->tmp.peer_finish_md */ #endif /* 64 argument should actually be 36+4 :-) */ n = s->method->ssl_get_message(s, a, b, SSL3_MT_FINISHED, 64, &ok); if (!ok) return ((int)n); /* If this occurs, we have missed a message */ if (!s->s3->change_cipher_spec) { al = SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_GOT_A_FIN_BEFORE_A_CCS); goto f_err; } s->s3->change_cipher_spec = 0; p = (unsigned char *)s->init_msg; i = s->s3->tmp.peer_finish_md_len; if (i != n) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_BAD_DIGEST_LENGTH); goto f_err; } if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) { al = SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_DIGEST_CHECK_FAILED); goto f_err; } /* * Copy the finished so we can use it for renegotiation checks */ if (s->type == SSL_ST_ACCEPT) { OPENSSL_assert(i <= EVP_MAX_MD_SIZE); memcpy(s->s3->previous_client_finished, s->s3->tmp.peer_finish_md, i); s->s3->previous_client_finished_len = i; } else { OPENSSL_assert(i <= EVP_MAX_MD_SIZE); memcpy(s->s3->previous_server_finished, s->s3->tmp.peer_finish_md, i); s->s3->previous_server_finished_len = i; } return (1); f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); return (0); }
static int aead_aes_ctr_hmac_sha256_open_gather( const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *nonce, size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag, size_t in_tag_len, const uint8_t *ad, size_t ad_len) { const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = (struct aead_aes_ctr_hmac_sha256_ctx *) &ctx->state; if (in_tag_len != ctx->tag_len) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); return 0; } if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); return 0; } uint8_t hmac_result[SHA256_DIGEST_LENGTH]; hmac_calculate(hmac_result, &aes_ctx->inner_init_state, &aes_ctx->outer_init_state, ad, ad_len, nonce, in, in_len); if (CRYPTO_memcmp(hmac_result, in_tag, ctx->tag_len) != 0) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); return 0; } aead_aes_ctr_hmac_sha256_crypt(aes_ctx, out, in, in_len, nonce); return 1; }
static int aead_chacha20_poly1305_open(aead_poly1305_update poly1305_update, const void *ctx_buf, uint8_t *out, size_t *out_len, size_t max_out_len, const uint8_t nonce[12], const uint8_t *in, size_t in_len, const uint8_t *ad, size_t ad_len) { aead_assert_open_seal_preconditions(alignof(struct aead_chacha20_poly1305_ctx), ctx_buf, out, out_len, nonce, in, in_len, ad, ad_len); const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx_buf; if (!aead_open_out_max_out_in_tag_len(out_len, max_out_len, in_len, POLY1305_TAG_LEN)) { /* |aead_open_out_max_out_in_tag_len| already called * |OPENSSL_PUT_ERROR|. */ return 0; } size_t plaintext_len; plaintext_len = in_len - POLY1305_TAG_LEN; uint8_t tag[POLY1305_TAG_LEN] ALIGNED; aead_poly1305(poly1305_update, tag, c20_ctx, nonce, ad, ad_len, in, plaintext_len); if (CRYPTO_memcmp(tag, in + plaintext_len, POLY1305_TAG_LEN) != 0) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); return 0; } CRYPTO_chacha_20(out, in, plaintext_len, c20_ctx->key, nonce, 1); *out_len = plaintext_len; return 1; }
static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, size_t max_out_len, const uint8_t *nonce, size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *ad, size_t ad_len) { const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; uint8_t mac[POLY1305_TAG_LEN]; uint8_t poly1305_key[32] ALIGNED; size_t plaintext_len; poly1305_state poly1305; const uint64_t in_len_64 = in_len; if (in_len < c20_ctx->tag_len) { OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_BAD_DECRYPT); return 0; } /* The underlying ChaCha implementation may not overflow the block * counter into the second counter word. Therefore we disallow * individual operations that work on more than 256GB at a time. * |in_len_64| is needed because, on 32-bit platforms, size_t is only * 32-bits and this produces a warning because it's always false. * Casting to uint64_t inside the conditional is not sufficient to stop * the warning. */ if (in_len_64 >= (1ull << 32) * 64 - 64) { OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_TOO_LARGE); return 0; } if (nonce_len != CHACHA20_NONCE_LEN) { OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_IV_TOO_LARGE); return 0; } plaintext_len = in_len - c20_ctx->tag_len; if (max_out_len < plaintext_len) { OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_BUFFER_TOO_SMALL); return 0; } memset(poly1305_key, 0, sizeof(poly1305_key)); CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), c20_ctx->key, nonce, 0); CRYPTO_poly1305_init(&poly1305, poly1305_key); poly1305_update_with_length(&poly1305, ad, ad_len); poly1305_update_with_length(&poly1305, in, plaintext_len); CRYPTO_poly1305_finish(&poly1305, mac); if (CRYPTO_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) { OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_BAD_DECRYPT); return 0; } CRYPTO_chacha_20(out, in, plaintext_len, c20_ctx->key, nonce, 1); *out_len = plaintext_len; return 1; }
int detect_mode() { // Tamanho minimo: 5 + input + 5 = 10 + input // Tamanho maximo: 10 + input + 10 = 20 + input unsigned char input[] = "ParangaricoTirimirruaro"; unsigned int input_len = strlen((char*)input); unsigned int output_len, max_output_len; unsigned char* choosen_input = NULL; unsigned char* output = NULL; unsigned int choosen_len = 2*BLOCK_LEN + input_len + (input_len%BLOCK_LEN) + 2*BLOCK_LEN; int expected_method = 0; choosen_input = (unsigned char*) malloc(choosen_len); if ( NULL == choosen_input ) { printf("Out of memory!\n"); return -1; } max_output_len = choosen_len + 50; output = (unsigned char*) malloc(max_output_len); if ( NULL == output ) { free(choosen_input); printf("Out of memory!\n"); return -1; } memset((char*) choosen_input, 0, choosen_len); memcpy((char*) &choosen_input[2*BLOCK_LEN], input, input_len); if ( 0 == encryption_oracle_ex( choosen_input, choosen_len, output, &output_len, max_output_len, &expected_method ) ) { // Search for equal blocks -- if found, ECB has been used unsigned int i, found, iNumBlocks = output_len / BLOCK_LEN; unsigned char* pFirst = &output[ 1 * BLOCK_LEN ]; found = 0; for(i=2; i<iNumBlocks; i++){ unsigned char* pSecond = &output[ i * BLOCK_LEN ]; if ( 0 == CRYPTO_memcmp(pFirst, pSecond, BLOCK_LEN) ) { found = 1; break; } } if(found) { printf("ECB detected (expected %s)\n", (expected_method?"CBC":"ECB")); } else { printf("CBC detected (expected %s)\n", (expected_method?"CBC":"ECB")); } } else { printf("Encryption oracle error\n"); free(choosen_input); free(output); return -1; } free(choosen_input); free(output); return 0; }
int verify_authentication_token(int protocol, const KA_CTX *ka_ctx, BN_CTX *bn_ctx, enum eac_tr_version tr_version, const BUF_MEM *token) { int rv; BUF_MEM *token_verify = NULL; if (!ka_ctx || !token) { log_err("Invalid arguments"); return -1; } token_verify = compute_authentication_token(protocol, ka_ctx, ka_ctx->key, bn_ctx, tr_version); if (!token_verify) return -1; if (token_verify->length != token->length || CRYPTO_memcmp(token_verify->data, token->data, token_verify->length)) rv = 0; else rv = 1; BUF_MEM_free(token_verify); return rv; }
/** Milenage check * * @param[out] ik Buffer for IK = 128-bit integrity key (f4), or NULL. * @param[out] ck Buffer for CK = 128-bit confidentiality key (f3), or NULL. * @param[out] res Buffer for RES = 64-bit signed response (f2), or NULL. * @param[in] auts 112-bit buffer for AUTS. * @param[in] opc 128-bit operator variant algorithm configuration field (encr.). * @param[in] ki 128-bit subscriber key. * @param[in] sqn 48-bit sequence number. * @param[in] rand 128-bit random challenge. * @param[in] autn 128-bit authentication token. * @return * - 0 on success. * - -1 on failure. * - -2 on synchronization failure */ int milenage_check(uint8_t ik[MILENAGE_IK_SIZE], uint8_t ck[MILENAGE_CK_SIZE], uint8_t res[MILENAGE_RES_SIZE], uint8_t auts[MILENAGE_AUTS_SIZE], uint8_t const opc[MILENAGE_OPC_SIZE], uint8_t const ki[MILENAGE_KI_SIZE], uint64_t sqn, uint8_t const rand[MILENAGE_RAND_SIZE], uint8_t const autn[MILENAGE_AUTN_SIZE]) { uint8_t mac_a[MILENAGE_MAC_A_SIZE], ak[MILENAGE_AK_SIZE], rx_sqn[MILENAGE_SQN_SIZE]; uint8_t sqn_buff[MILENAGE_SQN_SIZE]; const uint8_t *amf; size_t i; uint48_to_buff(sqn_buff, sqn); FR_PROTO_HEX_DUMP(autn, MILENAGE_AUTN_SIZE, "AUTN"); FR_PROTO_HEX_DUMP(rand, MILENAGE_RAND_SIZE, "RAND"); if (milenage_f2345(res, ck, ik, ak, NULL, opc, ki, rand)) return -1; FR_PROTO_HEX_DUMP(res, MILENAGE_RES_SIZE, "RES"); FR_PROTO_HEX_DUMP(ck, MILENAGE_CK_SIZE, "CK"); FR_PROTO_HEX_DUMP(ik, MILENAGE_IK_SIZE, "IK"); FR_PROTO_HEX_DUMP(ak, MILENAGE_AK_SIZE, "AK"); /* AUTN = (SQN ^ AK) || AMF || MAC */ for (i = 0; i < 6; i++) rx_sqn[i] = autn[i] ^ ak[i]; FR_PROTO_HEX_DUMP(rx_sqn, MILENAGE_SQN_SIZE, "SQN"); if (memcmp(rx_sqn, sqn_buff, sizeof(rx_sqn)) <= 0) { uint8_t auts_amf[MILENAGE_AMF_SIZE] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */ if (milenage_f2345(NULL, NULL, NULL, NULL, ak, opc, ki, rand)) return -1; FR_PROTO_HEX_DUMP(ak, sizeof(ak), "AK*"); for (i = 0; i < 6; i++) auts[i] = sqn_buff[i] ^ ak[i]; if (milenage_f1(NULL, auts + 6, opc, ki, rand, sqn_buff, auts_amf) < 0) return -1; FR_PROTO_HEX_DUMP(auts, 14, "AUTS"); return -2; } amf = autn + 6; FR_PROTO_HEX_DUMP(amf, MILENAGE_AMF_SIZE, "AMF"); if (milenage_f1(mac_a, NULL, opc, ki, rand, rx_sqn, amf) < 0) return -1; FR_PROTO_HEX_DUMP(mac_a, MILENAGE_MAC_A_SIZE, "MAC_A"); if (CRYPTO_memcmp(mac_a, autn + 8, 8) != 0) { FR_PROTO_HEX_DUMP(autn + 8, 8, "Received MAC_A"); fr_strerror_printf("MAC mismatch"); return -1; } return 0; }
static void rand_get_seed(struct rand_state *state, uint8_t seed[CTR_DRBG_ENTROPY_LEN]) { if (!state->last_block_valid) { if (!hwrand(state->last_block, sizeof(state->last_block))) { CRYPTO_sysrand(state->last_block, sizeof(state->last_block)); } state->last_block_valid = 1; } // We overread from /dev/urandom or RDRAND by a factor of 10 and XOR to // whiten. #define FIPS_OVERREAD 10 uint8_t entropy[CTR_DRBG_ENTROPY_LEN * FIPS_OVERREAD]; if (!hwrand(entropy, sizeof(entropy))) { CRYPTO_sysrand(entropy, sizeof(entropy)); } // See FIPS 140-2, section 4.9.2. This is the “continuous random number // generator test” which causes the program to randomly abort. Hopefully the // rate of failure is small enough not to be a problem in practice. if (CRYPTO_memcmp(state->last_block, entropy, CRNGT_BLOCK_SIZE) == 0) { fprintf(stderr, "CRNGT failed.\n"); BORINGSSL_FIPS_abort(); } for (size_t i = CRNGT_BLOCK_SIZE; i < sizeof(entropy); i += CRNGT_BLOCK_SIZE) { if (CRYPTO_memcmp(entropy + i - CRNGT_BLOCK_SIZE, entropy + i, CRNGT_BLOCK_SIZE) == 0) { fprintf(stderr, "CRNGT failed.\n"); BORINGSSL_FIPS_abort(); } } OPENSSL_memcpy(state->last_block, entropy + sizeof(entropy) - CRNGT_BLOCK_SIZE, CRNGT_BLOCK_SIZE); OPENSSL_memcpy(seed, entropy, CTR_DRBG_ENTROPY_LEN); for (size_t i = 1; i < FIPS_OVERREAD; i++) { for (size_t j = 0; j < CTR_DRBG_ENTROPY_LEN; j++) { seed[j] ^= entropy[CTR_DRBG_ENTROPY_LEN * i + j]; } } }
int ssl3_get_finished(SSL *ssl) { int al, finished_len, ok; long message_len; uint8_t *p; message_len = ssl->method->ssl_get_message(ssl, SSL3_MT_FINISHED, ssl_dont_hash_message, &ok); if (!ok) { return message_len; } /* Snapshot the finished hash before incorporating the new message. */ ssl3_take_mac(ssl); if (!ssl3_hash_current_message(ssl)) { goto err; } p = ssl->init_msg; finished_len = ssl->s3->tmp.peer_finish_md_len; if (finished_len != message_len) { al = SSL_AD_DECODE_ERROR; OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_DIGEST_LENGTH); goto f_err; } int finished_ret = CRYPTO_memcmp(p, ssl->s3->tmp.peer_finish_md, finished_len); #if defined(BORINGSSL_UNSAFE_FUZZER_MODE) finished_ret = 0; #endif if (finished_ret != 0) { al = SSL_AD_DECRYPT_ERROR; OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED); goto f_err; } /* Copy the finished so we can use it for renegotiation checks */ if (ssl->server) { assert(finished_len <= EVP_MAX_MD_SIZE); memcpy(ssl->s3->previous_client_finished, ssl->s3->tmp.peer_finish_md, finished_len); ssl->s3->previous_client_finished_len = finished_len; } else { assert(finished_len <= EVP_MAX_MD_SIZE); memcpy(ssl->s3->previous_server_finished, ssl->s3->tmp.peer_finish_md, finished_len); ssl->s3->previous_server_finished_len = finished_len; } return 1; f_err: ssl3_send_alert(ssl, SSL3_AL_FATAL, al); err: return 0; }
static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { const ECX_KEY *akey = a->pkey.ecx; const ECX_KEY *bkey = b->pkey.ecx; if (akey == NULL || bkey == NULL) return -2; return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0; }
int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len, const uint8_t *sig, size_t sig_len, RSA *rsa) { const size_t rsa_size = RSA_size(rsa); uint8_t *buf = NULL; int ret = 0; uint8_t *signed_msg = NULL; size_t signed_msg_len, len; int signed_msg_is_alloced = 0; if (rsa->meth->verify) { return rsa->meth->verify(hash_nid, msg, msg_len, sig, sig_len, rsa); } if (sig_len != rsa_size) { OPENSSL_PUT_ERROR(RSA, RSA_verify, RSA_R_WRONG_SIGNATURE_LENGTH); return 0; } if (hash_nid == NID_md5_sha1 && msg_len != SSL_SIG_LENGTH) { OPENSSL_PUT_ERROR(RSA, RSA_verify, RSA_R_INVALID_MESSAGE_LENGTH); return 0; } buf = OPENSSL_malloc(rsa_size); if (!buf) { OPENSSL_PUT_ERROR(RSA, RSA_verify, ERR_R_MALLOC_FAILURE); return 0; } if (!RSA_verify_raw(rsa, &len, buf, rsa_size, sig, sig_len, RSA_PKCS1_PADDING)) { goto out; } if (!pkcs1_prefixed_msg(&signed_msg, &signed_msg_len, &signed_msg_is_alloced, hash_nid, msg, msg_len)) { goto out; } if (len != signed_msg_len || CRYPTO_memcmp(buf, signed_msg, len) != 0) { OPENSSL_PUT_ERROR(RSA, RSA_verify, RSA_R_BAD_SIGNATURE); goto out; } ret = 1; out: if (buf != NULL) { OPENSSL_free(buf); } if (signed_msg_is_alloced) { OPENSSL_free(signed_msg); } return ret; }
static int aria_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,ctx); int rv = -1; /* Encrypt/decrypt must be performed in place */ if (out != in || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN)) return -1; /* * Set IV from start of buffer or generate IV and write to start of * buffer. */ if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CIPHER_CTX_encrypting(ctx) ? EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) goto err; /* Use saved AAD */ if (CRYPTO_gcm128_aad(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), gctx->tls_aad_len)) goto err; /* Fix buffer and length to point to payload */ in += EVP_GCM_TLS_EXPLICIT_IV_LEN; out += EVP_GCM_TLS_EXPLICIT_IV_LEN; len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; if (EVP_CIPHER_CTX_encrypting(ctx)) { /* Encrypt payload */ if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) goto err; out += len; /* Finally write tag */ CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN); rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; } else { /* Decrypt */ if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len)) goto err; /* Retrieve tag */ CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), EVP_GCM_TLS_TAG_LEN); /* If tag mismatch wipe buffer */ if (CRYPTO_memcmp(EVP_CIPHER_CTX_buf_noconst(ctx), in + len, EVP_GCM_TLS_TAG_LEN)) { OPENSSL_cleanse(out, len); goto err; } rv = len; } err: gctx->iv_set = 0; gctx->tls_aad_len = -1; return rv; }
bool Server::validate_hmac(const unsigned char *_hmac) { // S->C // Send "OK" if HMAC-SHA256(K, salt) validates bool ret = false; if (hmac) { ret = (CRYPTO_memcmp(hmac, _hmac, SHA256_HASH_LEN) == 0); delete [] hmac; hmac = NULL; } return ret; }
int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b) { if (a->ssl_version != b->ssl_version || a->session_id_length != b->session_id_length) return 1; #if defined(_WIN32) return memcmp(a->session_id, b->session_id, a->session_id_length); #else return CRYPTO_memcmp(a->session_id, b->session_id, a->session_id_length); #endif }
static int x25519_point_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) { /* Shouldn't happen as initialised to non-zero */ if (a->custom_data == NULL || b->custom_data == NULL) return -1; if (CRYPTO_memcmp(a->custom_data, b->custom_data, EC_X25519_KEYLEN) == 0) return 0; return 1; }
int evp_aead_aes_gcm_open(const void *ctx_buf, uint8_t *out, size_t *out_len, size_t max_out_len, const uint8_t *nonce, const uint8_t *in, size_t in_len, const uint8_t *ad, size_t ad_len) { aead_assert_open_seal_preconditions(alignof(struct aead_aes_gcm_ctx), ctx_buf, out, out_len, nonce, in, in_len, ad, ad_len); const struct aead_aes_gcm_ctx *gcm_ctx = ctx_buf; if (!aead_open_out_max_out_in_tag_len(out_len, max_out_len, in_len, EVP_AEAD_AES_GCM_TAG_LEN)) { /* |aead_open_out_max_out_in_tag_len| already called |OPENSSL_PUT_ERROR|. */ return 0; } uint8_t tag[EVP_AEAD_AES_GCM_TAG_LEN]; size_t plaintext_len; GCM128_CONTEXT gcm; plaintext_len = in_len - EVP_AEAD_AES_GCM_TAG_LEN; const AES_KEY *key = &gcm_ctx->ks.ks; memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm)); CRYPTO_gcm128_set_96_bit_iv(&gcm, key, nonce); if (!CRYPTO_gcm128_aad(&gcm, ad, ad_len)) { return 0; } if (gcm_ctx->ctr) { if (!CRYPTO_gcm128_decrypt_ctr32(&gcm, key, in, out, in_len - EVP_AEAD_AES_GCM_TAG_LEN, gcm_ctx->ctr)) { return 0; } } else { if (!CRYPTO_gcm128_decrypt(&gcm, key, in, out, in_len - EVP_AEAD_AES_GCM_TAG_LEN)) { return 0; } } CRYPTO_gcm128_tag(&gcm, tag, EVP_AEAD_AES_GCM_TAG_LEN); if (CRYPTO_memcmp(tag, in + plaintext_len, EVP_AEAD_AES_GCM_TAG_LEN) != 0) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); return 0; } return 1; }
static int aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, size_t max_out_len, const uint8_t *nonce, size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *ad, size_t ad_len) { size_t bulk = 0; const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state; uint8_t tag[EVP_AEAD_AES_GCM_TAG_LEN]; size_t plaintext_len; GCM128_CONTEXT gcm; if (in_len < gcm_ctx->tag_len) { OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_open, CIPHER_R_BAD_DECRYPT); return 0; } plaintext_len = in_len - gcm_ctx->tag_len; if (max_out_len < plaintext_len) { OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_open, CIPHER_R_BUFFER_TOO_SMALL); return 0; } memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm)); CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len); if (!CRYPTO_gcm128_aad(&gcm, ad, ad_len)) { return 0; } if (gcm_ctx->ctr) { if (!CRYPTO_gcm128_decrypt_ctr32(&gcm, in + bulk, out + bulk, in_len - bulk - gcm_ctx->tag_len, gcm_ctx->ctr)) { return 0; } } else { if (!CRYPTO_gcm128_decrypt(&gcm, in + bulk, out + bulk, in_len - bulk - gcm_ctx->tag_len)) { return 0; } } CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len); if (CRYPTO_memcmp(tag, in + plaintext_len, gcm_ctx->tag_len) != 0) { OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_open, CIPHER_R_BAD_DECRYPT); return 0; } *out_len = plaintext_len; return 1; }
static int get_server_verify(SSL *s) { unsigned char *p; int i, n, len; p=(unsigned char *)s->init_buf->data; if (s->state == SSL2_ST_GET_SERVER_VERIFY_A) { i=ssl2_read(s,(char *)&(p[s->init_num]),1-s->init_num); if (i < (1-s->init_num)) return(ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i)); s->init_num += i; s->state= SSL2_ST_GET_SERVER_VERIFY_B; if (*p != SSL2_MT_SERVER_VERIFY) { if (p[0] != SSL2_MT_ERROR) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_SERVER_VERIFY, SSL_R_READ_WRONG_PACKET_TYPE); } else { SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_PEER_ERROR); /* try to read the error message */ i=ssl2_read(s,(char *)&(p[s->init_num]),3-s->init_num); return ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i); } return(-1); } } p=(unsigned char *)s->init_buf->data; len = 1 + s->s2->challenge_length; n = len - s->init_num; i = ssl2_read(s,(char *)&(p[s->init_num]),n); if (i < n) return(ssl2_part_read(s,SSL_F_GET_SERVER_VERIFY,i)); if (s->msg_callback) s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); /* SERVER-VERIFY */ p += 1; if (CRYPTO_memcmp(p,s->s2->challenge,s->s2->challenge_length) != 0) { ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); SSLerr(SSL_F_GET_SERVER_VERIFY,SSL_R_CHALLENGE_IS_DIFFERENT); return(-1); } return(1); }
static int aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len, size_t max_out_len, const unsigned char *nonce, size_t nonce_len, const unsigned char *in, size_t in_len, const unsigned char *ad, size_t ad_len) { const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state; unsigned char tag[EVP_AEAD_AES_GCM_TAG_LEN]; GCM128_CONTEXT gcm; size_t plaintext_len; size_t bulk = 0; if (in_len < gcm_ctx->tag_len) { EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BAD_DECRYPT); return 0; } plaintext_len = in_len - gcm_ctx->tag_len; if (max_out_len < plaintext_len) { EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BUFFER_TOO_SMALL); return 0; } memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm)); CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len); if (CRYPTO_gcm128_aad(&gcm, ad, ad_len)) return 0; if (gcm_ctx->ctr) { if (CRYPTO_gcm128_decrypt_ctr32(&gcm, in + bulk, out + bulk, in_len - bulk - gcm_ctx->tag_len, gcm_ctx->ctr)) return 0; } else { if (CRYPTO_gcm128_decrypt(&gcm, in + bulk, out + bulk, in_len - bulk - gcm_ctx->tag_len)) return 0; } CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len); if (CRYPTO_memcmp(tag, in + plaintext_len, gcm_ctx->tag_len) != 0) { EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BAD_DECRYPT); return 0; } *out_len = plaintext_len; return 1; }
static int aead_aes_gcm_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *nonce, size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag, size_t in_tag_len, const uint8_t *ad, size_t ad_len) { const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state; uint8_t tag[EVP_AEAD_AES_GCM_TAG_LEN]; if (nonce_len == 0) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); return 0; } if (in_tag_len != ctx->tag_len) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); return 0; } const AES_KEY *key = &gcm_ctx->ks.ks; GCM128_CONTEXT gcm; OPENSSL_memset(&gcm, 0, sizeof(gcm)); OPENSSL_memcpy(&gcm.gcm_key, &gcm_ctx->gcm_key, sizeof(gcm.gcm_key)); CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len); if (!CRYPTO_gcm128_aad(&gcm, ad, ad_len)) { return 0; } if (gcm_ctx->ctr) { if (!CRYPTO_gcm128_decrypt_ctr32(&gcm, key, in, out, in_len, gcm_ctx->ctr)) { return 0; } } else { if (!CRYPTO_gcm128_decrypt(&gcm, key, in, out, in_len)) { return 0; } } CRYPTO_gcm128_tag(&gcm, tag, ctx->tag_len); if (CRYPTO_memcmp(tag, in_tag, ctx->tag_len) != 0) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); return 0; } return 1; }
int tls13_process_finished(SSL *ssl) { uint8_t verify_data[EVP_MAX_MD_SIZE]; size_t verify_data_len; if (!tls13_finished_mac(ssl, verify_data, &verify_data_len, !ssl->server)) { return 0; } if (ssl->init_num != verify_data_len || CRYPTO_memcmp(verify_data, ssl->init_msg, verify_data_len) != 0) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED); return 0; } return 1; }
static int sms4_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t len) { EVP_SMS4_CCM_CTX *cctx = EVP_C_DATA(EVP_SMS4_CCM_CTX,ctx); CCM128_CONTEXT *ccm = &cctx->ccm; /* Encrypt/decrypt must be performed in place */ if (out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)cctx->M)) return -1; /* If encrypting set explicit IV from sequence number (start of AAD) */ if (EVP_CIPHER_CTX_encrypting(ctx)) memcpy(out, EVP_CIPHER_CTX_buf_noconst(ctx), EVP_CCM_TLS_EXPLICIT_IV_LEN); /* Get rest of IV from explicit IV */ memcpy(EVP_CIPHER_CTX_iv_noconst(ctx) + EVP_CCM_TLS_FIXED_IV_LEN, in, EVP_CCM_TLS_EXPLICIT_IV_LEN); /* Correct length value */ len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M; if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), 15 - cctx->L, len)) return -1; /* Use saved AAD */ CRYPTO_ccm128_aad(ccm, EVP_CIPHER_CTX_buf_noconst(ctx), cctx->tls_aad_len); /* Fix buffer to point to payload */ in += EVP_CCM_TLS_EXPLICIT_IV_LEN; out += EVP_CCM_TLS_EXPLICIT_IV_LEN; if (EVP_CIPHER_CTX_encrypting(ctx)) { if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, cctx->str) : CRYPTO_ccm128_encrypt(ccm, in, out, len)) return -1; if (!CRYPTO_ccm128_tag(ccm, out + len, cctx->M)) return -1; return len + EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M; } else { if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len, cctx->str) : !CRYPTO_ccm128_decrypt(ccm, in, out, len)) { unsigned char tag[16]; if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) { if (!CRYPTO_memcmp(tag, in + len, cctx->M)) return len; } } OPENSSL_cleanse(out, len); return -1; } }
/* Verify the mac */ int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen) { unsigned char mac[EVP_MAX_MD_SIZE]; unsigned int maclen; if (p12->mac == NULL) { PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_ABSENT); return 0; } if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) { PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_GENERATION_ERROR); return 0; } if ((maclen != (unsigned int)p12->mac->dinfo->digest->length) || CRYPTO_memcmp(mac, p12->mac->dinfo->digest->data, maclen)) return 0; return 1; }
static int aead_chacha20_poly1305_open_gather( const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *nonce, size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag, size_t in_tag_len, const uint8_t *ad, size_t ad_len) { const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; if (nonce_len != 12) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); return 0; } if (in_tag_len != ctx->tag_len) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); return 0; } // |CRYPTO_chacha_20| uses a 32-bit block counter. Therefore we disallow // individual operations that work on more than 256GB at a time. // |in_len_64| is needed because, on 32-bit platforms, size_t is only // 32-bits and this produces a warning because it's always false. // Casting to uint64_t inside the conditional is not sufficient to stop // the warning. const uint64_t in_len_64 = in_len; if (in_len_64 >= (UINT64_C(1) << 32) * 64 - 64) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); return 0; } union open_data data; if (asm_capable()) { OPENSSL_memcpy(data.in.key, c20_ctx->key, 32); data.in.counter = 0; OPENSSL_memcpy(data.in.nonce, nonce, 12); chacha20_poly1305_open(out, in, in_len, ad, ad_len, &data); } else { calc_tag(data.out.tag, c20_ctx, nonce, ad, ad_len, in, in_len, NULL, 0); CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1); } if (CRYPTO_memcmp(data.out.tag, in_tag, ctx->tag_len) != 0) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); return 0; } return 1; }
MSG_PROCESS_RETURN tls_process_finished(SSL *s, PACKET *pkt) { int al, i; /* If this occurs, we have missed a message */ if (!s->s3->change_cipher_spec) { al = SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_TLS_PROCESS_FINISHED, SSL_R_GOT_A_FIN_BEFORE_A_CCS); goto f_err; } s->s3->change_cipher_spec = 0; i = s->s3->tmp.peer_finish_md_len; if ((unsigned long)i != PACKET_remaining(pkt)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_FINISHED, SSL_R_BAD_DIGEST_LENGTH); goto f_err; } if (CRYPTO_memcmp(PACKET_data(pkt), s->s3->tmp.peer_finish_md, i) != 0) { al = SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_TLS_PROCESS_FINISHED, SSL_R_DIGEST_CHECK_FAILED); goto f_err; } /* * Copy the finished so we can use it for renegotiation checks */ if (s->server) { OPENSSL_assert(i <= EVP_MAX_MD_SIZE); memcpy(s->s3->previous_client_finished, s->s3->tmp.peer_finish_md, i); s->s3->previous_client_finished_len = i; } else { OPENSSL_assert(i <= EVP_MAX_MD_SIZE); memcpy(s->s3->previous_server_finished, s->s3->tmp.peer_finish_md, i); s->s3->previous_server_finished_len = i; } return MSG_PROCESS_FINISHED_READING; f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); ossl_statem_set_error(s); return MSG_PROCESS_ERROR; }
int s1c5_main() { const unsigned char test_data[] = "Burning 'em, if you ain't quick and nimble\nI go crazy when I hear a cymbal"; const unsigned char key[3] = {'I', 'C', 'E'}; const unsigned char expected_result[] = { 0x0B, 0x36, 0x37, 0x27, 0x2A, 0x2B, 0x2E, 0x63, 0x62, 0x2C, 0x2E, 0x69, 0x69, 0x2A, 0x23, 0x69, 0x3A, 0x2A, 0x3C, 0x63, 0x24, 0x20, 0x2D, 0x62, 0x3D, 0x63, 0x34, 0x3C, 0x2A, 0x26, 0x22, 0x63, 0x24, 0x27, 0x27, 0x65, 0x27, 0x2A, 0x28, 0x2B, 0x2F, 0x20, 0x43, 0x0A, 0x65, 0x2E, 0x2C, 0x65, 0x2A, 0x31, 0x24, 0x33, 0x3A, 0x65, 0x3E, 0x2B, 0x20, 0x27, 0x63, 0x0C, 0x69, 0x2B, 0x20, 0x28, 0x31, 0x65, 0x28, 0x63, 0x26, 0x30, 0x2E, 0x27, 0x28, 0x2F }; unsigned char *out = NULL; unsigned int out_len = 0; out = (unsigned char*) malloc(sizeof(test_data)); if ( NULL == out ) { printf("FATAL! Out of memory\n"); return 0; } repkxor(key, sizeof(key), test_data, sizeof(test_data) - 1, out, &out_len); printf("Generated output: "); print_hex(out, out_len); printf("\n"); printf("Checking..."); if ( 0 == CRYPTO_memcmp( (void*)expected_result, (void*)out, min(out_len, sizeof(expected_result)-1)) ) { free(out); printf("SUCCESS\n"); return 0; } else { free(out); printf("FAIL"); return -1; } }
/** Milenage AUTS validation * * @param[out] sqn Buffer for SQN = 48-bit sequence number (host byte order). * @param[in] opc 128-bit operator variant algorithm configuration field (encr.). * @param[in] ki 128-bit subscriber key. * @param[in] rand 128-bit random challenge. * @param[in] auts 112-bit authentication token from client. * @return * - 0 on success with sqn filled. * - -1 on failure. */ int milenage_auts(uint64_t sqn, uint8_t const opc[MILENAGE_OPC_SIZE], uint8_t const ki[MILENAGE_KI_SIZE], uint8_t const rand[MILENAGE_RAND_SIZE], uint8_t const auts[MILENAGE_AUTS_SIZE]) { uint8_t amf[MILENAGE_AMF_SIZE] = { 0x00, 0x00 }; /* TS 33.102 v7.0.0, 6.3.3 */ uint8_t ak[MILENAGE_AK_SIZE], mac_s[MILENAGE_MAC_S_SIZE]; uint8_t sqn_buff[MILENAGE_SQN_SIZE]; size_t i; uint48_to_buff(sqn_buff, sqn); if (milenage_f2345(NULL, NULL, NULL, NULL, ak, opc, ki, rand)) return -1; for (i = 0; i < sizeof(sqn_buff); i++) sqn_buff[i] = auts[i] ^ ak[i]; if (milenage_f1(NULL, mac_s, opc, ki, rand, sqn_buff, amf) || CRYPTO_memcmp(mac_s, auts + 6, 8) != 0) return -1; return 0; }
int tls13_process_finished(SSL *ssl) { uint8_t verify_data[EVP_MAX_MD_SIZE]; size_t verify_data_len; if (!tls13_finished_mac(ssl, verify_data, &verify_data_len, !ssl->server)) { return 0; } int finished_ok = ssl->init_num == verify_data_len && CRYPTO_memcmp(verify_data, ssl->init_msg, verify_data_len) == 0; #if defined(BORINGSSL_UNSAFE_FUZZER_MODE) finished_ok = 1; #endif if (!finished_ok) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED); return 0; } return 1; }