static u32 qce_auth_cfg(unsigned long flags, u32 key_size) { u32 cfg = 0; if (IS_AES(flags) && (IS_CCM(flags) || IS_CMAC(flags))) cfg |= AUTH_ALG_AES << AUTH_ALG_SHIFT; else cfg |= AUTH_ALG_SHA << AUTH_ALG_SHIFT; if (IS_CCM(flags) || IS_CMAC(flags)) { if (key_size == AES_KEYSIZE_128) cfg |= AUTH_KEY_SZ_AES128 << AUTH_KEY_SIZE_SHIFT; else if (key_size == AES_KEYSIZE_256) cfg |= AUTH_KEY_SZ_AES256 << AUTH_KEY_SIZE_SHIFT; } if (IS_SHA1(flags) || IS_SHA1_HMAC(flags)) cfg |= AUTH_SIZE_SHA1 << AUTH_SIZE_SHIFT; else if (IS_SHA256(flags) || IS_SHA256_HMAC(flags)) cfg |= AUTH_SIZE_SHA256 << AUTH_SIZE_SHIFT; else if (IS_CMAC(flags)) cfg |= AUTH_SIZE_ENUM_16_BYTES << AUTH_SIZE_SHIFT; if (IS_SHA1(flags) || IS_SHA256(flags)) cfg |= AUTH_MODE_HASH << AUTH_MODE_SHIFT; else if (IS_SHA1_HMAC(flags) || IS_SHA256_HMAC(flags) || IS_CBC(flags) || IS_CTR(flags)) cfg |= AUTH_MODE_HMAC << AUTH_MODE_SHIFT; else if (IS_AES(flags) && IS_CCM(flags)) cfg |= AUTH_MODE_CCM << AUTH_MODE_SHIFT; else if (IS_AES(flags) && IS_CMAC(flags)) cfg |= AUTH_MODE_CMAC << AUTH_MODE_SHIFT; if (IS_SHA(flags) || IS_SHA_HMAC(flags)) cfg |= AUTH_POS_BEFORE << AUTH_POS_SHIFT; if (IS_CCM(flags)) cfg |= QCE_MAX_NONCE_WORDS << AUTH_NONCE_NUM_WORDS_SHIFT; if (IS_CBC(flags) || IS_CTR(flags) || IS_CCM(flags) || IS_CMAC(flags)) cfg |= BIT(AUTH_LAST_SHIFT) | BIT(AUTH_FIRST_SHIFT); return cfg; }
/* Generates a signature of all the random data and the parameters. * Used in DHE_* ciphersuites. */ int _gnutls_handshake_sign_data(gnutls_session_t session, gnutls_pcert_st * cert, gnutls_privkey_t pkey, gnutls_datum_t * params, gnutls_datum_t * signature, gnutls_sign_algorithm_t * sign_algo) { gnutls_datum_t dconcat; int ret; digest_hd_st td_sha; uint8_t concat[MAX_SIG_SIZE]; const version_entry_st *ver = get_version(session); const mac_entry_st *hash_algo; *sign_algo = _gnutls_session_get_sign_algo(session, cert); if (*sign_algo == GNUTLS_SIGN_UNKNOWN) { gnutls_assert(); return GNUTLS_E_UNKNOWN_PK_ALGORITHM; } gnutls_sign_algorithm_set_server(session, *sign_algo); hash_algo = hash_to_entry(gnutls_sign_get_hash_algorithm(*sign_algo)); if (hash_algo == NULL) return gnutls_assert_val(GNUTLS_E_UNKNOWN_HASH_ALGORITHM); _gnutls_handshake_log ("HSK[%p]: signing handshake data: using %s\n", session, gnutls_sign_algorithm_get_name(*sign_algo)); ret = _gnutls_hash_init(&td_sha, hash_algo); if (ret < 0) { gnutls_assert(); return ret; } _gnutls_hash(&td_sha, session->security_parameters.client_random, GNUTLS_RANDOM_SIZE); _gnutls_hash(&td_sha, session->security_parameters.server_random, GNUTLS_RANDOM_SIZE); _gnutls_hash(&td_sha, params->data, params->size); switch (gnutls_privkey_get_pk_algorithm(pkey, NULL)) { case GNUTLS_PK_RSA: if (!_gnutls_version_has_selectable_sighash(ver)) { digest_hd_st td_md5; ret = _gnutls_hash_init(&td_md5, hash_to_entry (GNUTLS_DIG_MD5)); if (ret < 0) { gnutls_assert(); return ret; } _gnutls_hash(&td_md5, session->security_parameters. client_random, GNUTLS_RANDOM_SIZE); _gnutls_hash(&td_md5, session->security_parameters. server_random, GNUTLS_RANDOM_SIZE); _gnutls_hash(&td_md5, params->data, params->size); _gnutls_hash_deinit(&td_md5, concat); _gnutls_hash_deinit(&td_sha, &concat[16]); dconcat.data = concat; dconcat.size = 36; } else { /* TLS 1.2 way */ _gnutls_hash_deinit(&td_sha, concat); dconcat.data = concat; dconcat.size = _gnutls_hash_get_algo_len(hash_algo); } break; case GNUTLS_PK_DSA: case GNUTLS_PK_EC: _gnutls_hash_deinit(&td_sha, concat); if (!IS_SHA((gnutls_digest_algorithm_t)hash_algo->id)) { gnutls_assert(); return GNUTLS_E_INTERNAL_ERROR; } dconcat.data = concat; dconcat.size = _gnutls_hash_get_algo_len(hash_algo); break; default: gnutls_assert(); _gnutls_hash_deinit(&td_sha, NULL); return GNUTLS_E_INTERNAL_ERROR; } ret = sign_tls_hash(session, hash_algo, cert, pkey, &dconcat, signature); if (ret < 0) { gnutls_assert(); } return ret; }