01 - BoringSSL 技术全景:支撑 Android 亿级设备的 FIPS 认证加密引擎完整解析
01 - BoringSSL 技术全景:支撑 Android 亿级设备的 FIPS 认证加密引擎完整解析
Google 的 OpenSSL 分支 | Android 核心加密库 | FIPS 140-2 认证
目录
- 概述
- 架构设计
- 核心模块
- API 接口
- 构建系统
- 性能优化
- 与 OpenSSL 对比
- 在 Android 中的使用
- 测试基础设施
- 最佳实践
概述
什么是 BoringSSL?
BoringSSL 是 Google 从 OpenSSL 分支出来的加密库,专为 Google 内部项目(Chrome、Android、云服务)优化。名字"Boring"意为"无聊"——加密库应该是无聊的、可靠的、不引人注意的。
位置: external/boringssl/
语言: C (crypto), C++ (ssl)
代码行数: ~46.5万行(包括测试)
FIPS认证: FIPS 140-2 Level 1 (证书 #3753, #4156, #4407)
核心特性
| 特性 | 说明 |
|---|---|
| OpenSSL 兼容 | API 兼容,但去除了遗留特性 |
| 内存安全 | 严格的内存管理,减少漏洞 |
| 性能优化 | 针对 ARM/x86 SIMD 优化 |
| FIPS验证 | 经过联邦密码认证 |
| 精简API | 移除废弃算法,专注现代加密 |
| 多平台 | Android、Linux、macOS、Windows |
与 OpenSSL 的关系
OpenSSL 1.0.1
↓ Fork (2014)
BoringSSL
↓
Google 定制化开发
• 移除遗留特性
• 添加 Post-Quantum Crypto (Kyber)
• 优化 ARM 平台
• 简化 API
架构设计
整体架构图
┌────────────────────────────────────────────────────────────┐
│ 应用层 │
│ Conscrypt (Java) | NDK Apps | System Services │
└─────────────────────────┬──────────────────────────────────┘
│
┌─────────────────────────┴──────────────────────────────────┐
│ BoringSSL Public API │
│ ssl.h | evp.h | aead.h | x509.h | rsa.h | ec.h │
└─────────────────────────┬──────────────────────────────────┘
│
┌───────────────────┴───────────────────┐
│ │
┌─────┴─────────────┐ ┌────────┴────────────────┐
│ libcrypto.so │ │ libssl.so │
│ (Cryptography) │◀─────────────┤ (TLS/SSL) │
│ │ depends │ │
│ • AES, RSA, EC │ │ • TLS 1.0-1.3 │
│ • SHA, HMAC │ │ • DTLS 1.0-1.2 │
│ • X.509, ASN.1 │ │ • ECH, QUIC │
│ • RNG, KDF │ │ │
└───────────────────┘ └─────────────────────────┘
│ │
└───────────────────┬───────────────────┘
│
┌───────────────────┴───────────────────┐
│ │
┌─────┴─────────────┐ ┌────────┴────────────────┐
│ FIPS Module │ │ Decrepit Module │
│ (bcm.c) │ │ (Deprecated Algos) │
│ │ │ │
│ • AES │ │ • RC4, DES, MD5 │
│ • SHA-256/512 │ │ • Blowfish, CAST │
│ • ECDSA P-256 │ │ • RIPEMD │
│ • HMAC │ │ │
│ • DRBG │ │ │
└───────────────────┘ └─────────────────────────┘
│
└──> Self-Test & Integrity Check
目录结构
external/boringssl/
├── src/ # 主源码目录
│ ├── crypto/ # 密码学库 (74 子目录)
│ │ ├── fipsmodule/ # FIPS 认证模块
│ │ ├── aes/ # AES 加密
│ │ ├── rsa_extra/ # RSA 扩展
│ │ ├── ec/, ecdh_extra/ # 椭圆曲线
│ │ ├── sha/, digest_extra/# 哈希算法
│ │ ├── x509/, x509v3/ # 证书管理
│ │ ├── asn1/ # ASN.1 编解码
│ │ ├── kyber/, hrss/ # 后量子密码
│ │ └── ... # 73+ 模块
│ ├── ssl/ # SSL/TLS 协议 (C++)
│ │ ├── handshake*.cc # 握手实现
│ │ ├── tls13*.cc # TLS 1.3
│ │ ├── dtls*.cc # DTLS
│ │ └── encrypted_client_hello.cc # ECH
│ ├── decrepit/ # 废弃算法 (13 子目录)
│ │ ├── blowfish/, cast/ # 旧对称算法
│ │ ├── des/, rc4/ # 遗留算法
│ │ └── ripemd/ # 旧哈希
│ ├── include/openssl/ # 公共头文件 (84 个)
│ ├── rust/ # Rust 绑定
│ ├── tool/ # 命令行工具
│ ├── util/ # 构建工具
│ └── third_party/ # 第三方依赖
├── Android.bp # Android 构建配置
├── sources.bp # 自动生成的源列表
├── linux-aarch64/ # Linux ARM64 汇编
├── apple-x86_64/ # macOS x86_64 汇编
└── win-aarch64/ # Windows ARM64 汇编
模块依赖关系
libssl.so
├─> libcrypto.so
│ ├─> fipsmodule (内部静态链接)
│ │ ├─> AES, SHA, RSA, ECDSA
│ │ ├─> HMAC, DRBG
│ │ └─> Self-test
│ ├─> crypto modules (74个)
│ │ ├─> asn1, x509, pem
│ │ ├─> chacha20, poly1305
│ │ ├─> curve25519, kyber
│ │ └─> rand, err, bio
│ └─> decrepit (可选)
│ └─> RC4, DES, MD5
└─> System dependencies
├─> libc (musl/bionic/glibc)
├─> libm (math)
└─> libc++ (C++ STL, for ssl)
核心模块
1. FIPS 模块 (crypto/fipsmodule/)
用途: FIPS 140-2 认证的密码学实现
文件: bcm.c (275行,聚合所有 FIPS 源码)
包含算法:
- 对称加密: AES (ECB, CBC, GCM, CCM)
- 哈希: SHA-1, SHA-256, SHA-384, SHA-512
- 签名: ECDSA (P-256, P-384, P-521), RSA
- 密钥协商: ECDH, HKDF
- 消息认证: HMAC
- 随机数: CTR-DRBG (符合 NIST SP 800-90A)
关键特性:
// FIPS 模块完整性检查
void BORINGSSL_integrity_test(void);
// FIPS 模式查询
int FIPS_mode(void);
// 敏感操作指示器
int FIPS_service_indicator_before_call(void);
int FIPS_service_indicator_after_call(void);
构建方式:
- 所有 FIPS 源码通过
bcm.c包含(单编译单元) - 生成可验证的二进制边界
- 支持 FIPS 完整性自检
FIPS 证书:
- Certificate #3753 (Android 10)
- Certificate #4156 (Android 11)
- Certificate #4407 (Android 12+)
2. 对称加密模块 (crypto/aes/, chacha/, cipher_extra/)
AES 实现 (crypto/aes/):
// 标准 AES 接口
struct aes_key_st {
uint32_t rd_key[4 * (OPENSSL_AES_MAXNR + 1)];
unsigned rounds;
};
int AES_set_encrypt_key(const uint8_t *key, unsigned bits,
AES_KEY *aeskey);
void AES_encrypt(const uint8_t *in, uint8_t *out,
const AES_KEY *key);
AEAD 统一接口 (crypto/cipher_extra/):
// AEAD: Authenticated Encryption with Associated Data
const EVP_AEAD *EVP_aead_aes_128_gcm(void);
const EVP_AEAD *EVP_aead_aes_256_gcm(void);
const EVP_AEAD *EVP_aead_chacha20_poly1305(void);
// 使用示例
EVP_AEAD_CTX ctx;
EVP_AEAD_CTX_init(&ctx, EVP_aead_aes_256_gcm(), key, 32,
16, NULL);
EVP_AEAD_CTX_seal(&ctx, out, &out_len, max_out_len,
nonce, 12, in, in_len, ad, ad_len);
ChaCha20-Poly1305 (crypto/chacha/, crypto/poly1305/):
- 流密码 (ChaCha20) + 消息认证码 (Poly1305)
- 纯软件实现,无需硬件支持
- 适用于移动设备
3. 非对称加密模块
RSA (crypto/rsa_extra/)
密钥生成:
RSA *RSA_new(void);
int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e,
BN_GENCB *cb);
加密/解密:
// OAEP 填充 (推荐)
int RSA_public_encrypt(int flen, const uint8_t *from,
uint8_t *to, RSA *rsa,
int padding); // RSA_PKCS1_OAEP_PADDING
// PSS 签名 (推荐)
int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len,
uint8_t *out, size_t max_out,
const uint8_t *in, size_t in_len,
const EVP_MD *md, const EVP_MD *mgf1_md,
int salt_len);
椭圆曲线 (crypto/ec/, crypto/ecdsa_extra/)
支持的曲线:
- P-256 (secp256r1) - FIPS 标准
- P-384 (secp384r1) - FIPS 标准
- P-521 (secp521r1) - FIPS 标准
- X25519 (Curve25519) - ECDH 专用
- Ed25519 - EdDSA 签名
ECDSA 签名:
EC_KEY *key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
EC_KEY_generate_key(key);
ECDSA_SIG *sig = ECDSA_do_sign(digest, digest_len, key);
int valid = ECDSA_do_verify(digest, digest_len, sig, key);
X25519 密钥协商:
uint8_t public_key[32], private_key[32], shared[32];
X25519_keypair(public_key, private_key);
// 对方公钥 -> 共享密钥
X25519(shared, private_key, peer_public_key);
4. 哈希与 MAC 模块
SHA 系列 (crypto/sha/, in fipsmodule):
// SHA-256
SHA256_CTX ctx;
SHA256_Init(&ctx);
SHA256_Update(&ctx, data, len);
SHA256_Final(hash, &ctx);
// SHA-512
SHA512_CTX ctx;
SHA512_Init(&ctx);
SHA512_Update(&ctx, data, len);
SHA512_Final(hash, &ctx);
HMAC (crypto/hmac_extra/):
uint8_t hmac[SHA256_DIGEST_LENGTH];
HMAC(EVP_sha256(), key, key_len, data, data_len, hmac, NULL);
// 或使用 EVP 接口
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
EVP_DigestSignInit(ctx, NULL, EVP_sha256(), NULL, key);
EVP_DigestSignUpdate(ctx, data, data_len);
EVP_DigestSignFinal(ctx, hmac, &hmac_len);
HKDF (密钥派生, crypto/hkdf/):
uint8_t prk[SHA256_DIGEST_LENGTH];
uint8_t okm[32];
HKDF_extract(prk, &prk_len, EVP_sha256(), ikm, ikm_len,
salt, salt_len);
HKDF_expand(okm, okm_len, EVP_sha256(), prk, prk_len,
info, info_len);
5. X.509 证书模块 (crypto/x509/, crypto/x509v3/)
证书解析:
X509 *cert = d2i_X509_fp(fp, NULL);
// 获取主题
X509_NAME *subject = X509_get_subject_name(cert);
char buf[256];
X509_NAME_oneline(subject, buf, sizeof(buf));
// 验证签名
EVP_PKEY *pubkey = X509_get_pubkey(cert);
int valid = X509_verify(cert, pubkey);
证书验证链:
X509_STORE *store = X509_STORE_new();
X509_STORE_add_cert(store, ca_cert);
X509_STORE_CTX *ctx = X509_STORE_CTX_new();
X509_STORE_CTX_init(ctx, store, cert, chain);
int result = X509_verify_cert(ctx); // 1 = valid
扩展字段 (X.509v3):
- Subject Alternative Name (SAN)
- Key Usage
- Extended Key Usage
- Basic Constraints
- Certificate Policies
6. SSL/TLS 模块 (ssl/)
协议支持:
- TLS 1.0 - 遗留支持(不推荐)
- TLS 1.1 - 遗留支持(不推荐)
- TLS 1.2 - 广泛支持
- TLS 1.3 - 现代标准(推荐)
- DTLS 1.0/1.2 - UDP 上的 TLS
服务端示例:
SSL_CTX *ctx = SSL_CTX_new(TLS_server_method());
SSL_CTX_use_certificate_file(ctx, "cert.pem", SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ctx, "key.pem", SSL_FILETYPE_PEM);
SSL *ssl = SSL_new(ctx);
SSL_set_fd(ssl, client_fd);
if (SSL_accept(ssl) == 1) {
// 握手成功
uint8_t buf[1024];
int len = SSL_read(ssl, buf, sizeof(buf));
SSL_write(ssl, response, response_len);
}
客户端示例:
SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
SSL *ssl = SSL_new(ctx);
SSL_set_fd(ssl, server_fd);
if (SSL_connect(ssl) == 1) {
// 握手成功
SSL_write(ssl, request, request_len);
int len = SSL_read(ssl, buf, sizeof(buf));
}
TLS 1.3 特性:
- 0-RTT - 零往返连接恢复
- ECH - Encrypted Client Hello (隐藏 SNI)
- Post-Quantum - Kyber KEM (实验性)
DTLS 用途:
- WebRTC 数据通道
- VoIP 加密
- IoT 设备通信
7. 后量子密码模块
Kyber (crypto/kyber/)
Kyber-768 (NIST Level 3):
struct KYBER_public_key {
uint8_t opaque[KYBER_PUBLIC_KEY_BYTES]; // 1184 bytes
};
struct KYBER_private_key {
uint8_t opaque[KYBER_PRIVATE_KEY_BYTES]; // 2400 bytes
};
// 密钥生成
KYBER_generate_key(uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES],
struct KYBER_private_key *out_private_key);
// 封装(生成共享密钥)
KYBER_encap(uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES],
uint8_t out_shared_secret[KYBER_SHARED_SECRET_BYTES],
const struct KYBER_public_key *public_key);
// 解封装(恢复共享密钥)
KYBER_decap(uint8_t out_shared_secret[KYBER_SHARED_SECRET_BYTES],
const uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES],
const struct KYBER_private_key *private_key);
用途:
- TLS 1.3 混合密钥交换 (Kyber + X25519)
- 抗量子计算机攻击
HRSS (crypto/hrss/)
NTRU-based KEM:
- HRSS-SXY13 变体
- 更快的密钥生成
- 适用于物联网设备
8. 随机数生成 (crypto/rand_extra/)
接口:
// 生成随机字节
void RAND_bytes(uint8_t *buf, size_t len);
// 添加熵(可选)
void RAND_add(const void *buf, int num, double randomness);
// 查询熵状态
int RAND_status(void); // 1 = ready
实现:
- FIPS 模式: CTR-DRBG (NIST SP 800-90A)
- 非 FIPS:
/dev/urandom(Linux),BCryptGenRandom(Windows),arc4random_buf(BSD) - ARM: TRNG 硬件支持(如果可用)
API 接口
公共头文件 (84个)
核心类型:
#include // 必须首先包含
#include // 配置
#include // 版本信息
加密 API:
#include // 统一加密接口 (50KB)
#include // AEAD 接口
#include // 对称密码
#include // 哈希摘要
非对称加密:
#include // RSA
#include // 椭圆曲线 (21KB)
#include // ECDSA 签名
#include // ECDH 密钥协商
#include // Diffie-Hellman
#include // DSA 签名
证书管理:
#include // X.509 证书 (98KB)
#include // X.509v3 扩展
#include // 证书验证
#include // PKCS#8 密钥格式
#include // PEM 编码
SSL/TLS:
#include // SSL/TLS 接口
#include // TLS 版本定义
#include // DTLS
数据处理:
#include // ASN.1 编解码 (98KB)
#include // BIO I/O (38KB)
#include // 字节串工具 (31KB)
#include // Base64 编解码
工具:
#include // 错误处理 (20KB)
#include // 内存管理
#include // 随机数
#include // 通用工具
EVP 统一接口
EVP (Envelope) API - 推荐使用的高层接口
对称加密示例:
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
// 初始化加密
EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
// 加密数据
int out_len;
EVP_EncryptUpdate(ctx, out, &out_len, in, in_len);
// 完成加密
int final_len;
EVP_EncryptFinal_ex(ctx, out + out_len, &final_len);
EVP_CIPHER_CTX_free(ctx);
消息摘要示例:
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(ctx, EVP_sha256(), NULL);
EVP_DigestUpdate(ctx, data, data_len);
uint8_t hash[SHA256_DIGEST_LENGTH];
EVP_DigestFinal_ex(ctx, hash, NULL);
EVP_MD_CTX_free(ctx);
签名示例:
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
EVP_PKEY *pkey = /* 加载私钥 */;
// 签名
EVP_DigestSignInit(ctx, NULL, EVP_sha256(), NULL, pkey);
EVP_DigestSignUpdate(ctx, data, data_len);
size_t sig_len;
EVP_DigestSignFinal(ctx, NULL, &sig_len); // 获取长度
uint8_t *sig = malloc(sig_len);
EVP_DigestSignFinal(ctx, sig, &sig_len);
BoringSSL 特有 API
AEAD 统一接口 (简化 AEAD 使用):
const EVP_AEAD *aead = EVP_aead_aes_256_gcm();
EVP_AEAD_CTX ctx;
EVP_AEAD_CTX_init(&ctx, aead, key, key_len, tag_len, NULL);
// 加密
EVP_AEAD_CTX_seal(&ctx, out, &out_len, max_out_len,
nonce, nonce_len, in, in_len, ad, ad_len);
// 解密
EVP_AEAD_CTX_open(&ctx, out, &out_len, max_out_len,
nonce, nonce_len, in, in_len, ad, ad_len);
Bytestring API (安全的字节串操作):
CBS cbs; // Const Byte String (读取)
CBB cbb; // Byte Builder (写入)
// 解析
CBS_init(&cbs, data, data_len);
uint32_t value;
CBS_get_u32(&cbs, &value);
// 构建
CBB_init(&cbb, 128);
CBB_add_u8(&cbb, 0x04);
CBB_add_bytes(&cbb, data, data_len);
uint8_t *out;
size_t out_len;
CBB_finish(&cbb, &out, &out_len);
构建系统
Android 构建 (Android.bp)
主要模块:
cc_library_shared {
name: "libcrypto",
host_supported: true,
vendor_available: true,
native_bridge_supported: true,
vndk: {
enabled: true,
},
ramdisk_available: true,
vendor_ramdisk_available: true,
recovery_available: true,
srcs: [":libcrypto_sources"],
shared_libs: [],
cflags: [
"-DBORINGSSL_SHARED_LIBRARY",
"-DBORINGSSL_ANDROID_SYSTEM",
"-DBORINGSSL_IMPLEMENTATION",
"-fvisibility=hidden",
"-Werror",
],
sdk_version: "9",
stl: "libc++_static",
}
cc_library_shared {
name: "libssl",
host_supported: true,
vendor_available: true,
srcs: [":libssl_sources"],
shared_libs: ["libcrypto"],
cflags: [
"-DBORINGSSL_SHARED_LIBRARY",
"-DBORINGSSL_IMPLEMENTATION",
],
sdk_version: "9",
stl: "libc++_static",
}
FIPS 自检工具:
cc_binary {
name: "boringssl_self_test",
srcs: ["src/crypto/fipsmodule/self_check/self_check.c"],
shared_libs: ["libcrypto"],
min_sdk_version: "29",
apex_available: [
"//apex_available:platform",
"com.android.conscrypt",
],
}
CMake 构建 (CMakeLists.txt)
顶层配置:
cmake_minimum_required(VERSION 3.12)
project(BoringSSL LANGUAGES C CXX ASM)
# 查找 Perl (用于汇编生成)
find_package(Perl REQUIRED)
# FIPS 选项
option(FIPS "Build the FIPS module" OFF)
option(FIPS_DELOCATE "Use delocate for FIPS module" OFF)
# 包含生成的源文件列表
include(sources.cmake)
# 添加子目录
add_subdirectory(crypto)
add_subdirectory(ssl)
add_subdirectory(decrepit)
add_subdirectory(tool)
库定义:
add_library(crypto SHARED ${CRYPTO_SOURCES})
target_include_directories(crypto PUBLIC
$
$
)
add_library(ssl SHARED ${SSL_SOURCES})
target_link_libraries(ssl crypto)
Perlasm 汇编生成
工作流程:
Perl 脚本 (*.pl)
↓ perlasm
汇编源码 (*.S)
↓ 汇编器
目标文件 (*.o)
↓ 链接器
共享库 (libcrypto.so)
示例:
# 生成 ARM64 AES 汇编
add_custom_command(
OUTPUT aesv8-armv8-linux.S
COMMAND ${PERL_EXECUTABLE} ${PROJECT_SOURCE_DIR}/crypto/aes/asm/aesv8-armv8.pl
linux64 aesv8-armv8-linux.S
DEPENDS ${PROJECT_SOURCE_DIR}/crypto/aes/asm/aesv8-armv8.pl
)
预编译汇编:
- Android 仓库包含所有平台的预生成
.S文件 - 位置:
linux-aarch64/,apple-x86_64/,win-x86_64/等 - 好处: 无需 Perl,加快构建速度
性能优化
架构特定优化
ARM/ARMv7 (32-bit)
NEON 优化:
// AES (crypto/aes/asm/aesv8-armv7.pl)
void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
const AES_KEY *key, uint8_t ivec[16], int enc);
// SHA-256 (crypto/sha/asm/sha256-armv4.pl)
void sha256_block_data_order_neon(uint32_t *state, const uint8_t *in,
size_t num);
// GHASH (crypto/modes/asm/ghash-armv4.pl)
void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16],
const uint8_t *inp, size_t len);
Bit-sliced AES:
- 一次处理 8 个块(128 位)
- 利用 NEON 128-bit 寄存器
- 性能提升 2-3x
ARMv8/AArch64 (64-bit)
硬件 AES:
// 使用 ARMv8 Crypto Extensions
// crypto/aes/asm/aesv8-armv8.pl
void aes_hw_set_encrypt_key(const uint8_t *userKey, const int bits,
AES_KEY *key);
void aes_hw_encrypt(const uint8_t *in, uint8_t *out,
const AES_KEY *key);
硬件 SHA:
// crypto/sha/asm/sha256-armv8.pl
void sha256_block_data_order_hw(uint32_t *state, const uint8_t *in,
size_t num);
// crypto/sha/asm/sha512-armv8.pl
void sha512_block_data_order_hw(uint64_t *state, const uint8_t *in,
size_t num);
多项式乘法 (PMULL):
// GCM 模式加速
// crypto/modes/asm/ghashv8-armv8.pl
void gcm_ghash_v8(uint64_t Xi[2], const u128 Htable[16],
const uint8_t *inp, size_t len);
性能提升:
| 算法 | 软件实现 | 硬件实现 | 提升 |
|---|---|---|---|
| AES-128 | 50 MB/s | 800 MB/s | 16x |
| AES-GCM | 40 MB/s | 600 MB/s | 15x |
| SHA-256 | 100 MB/s | 400 MB/s | 4x |
| SHA-512 | 150 MB/s | 500 MB/s | 3.3x |
x86_64
AES-NI (AES New Instructions):
// crypto/aes/asm/aesni-x86_64.pl
void aesni_set_encrypt_key(const uint8_t *userKey, int bits,
AES_KEY *key);
void aesni_encrypt(const uint8_t *in, uint8_t *out,
const AES_KEY *key);
void aesni_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
const AES_KEY *key, uint8_t *ivec, int enc);
AES-GCM 硬件加速:
// crypto/modes/asm/aesni-gcm-x86_64.pl
void aesni_gcm_encrypt(const uint8_t *in, uint8_t *out, size_t len,
const void *key, uint8_t ivec[16],
u64 *Xi);
AVX2 优化:
// RSA 大数运算
// crypto/bn/asm/rsaz-avx2.pl
void rsaz_1024_mul_avx2(uint64_t *ret, const uint64_t *a,
const uint64_t *b, const uint64_t *n,
uint64_t k);
RDRAND (硬件随机数):
// crypto/rand_extra/cpu_intel.c
int CRYPTO_rdrand(uint8_t out[8]) {
uint64_t rand;
return _rdrand64_step(&rand) && (memcpy(out, &rand, 8), 1);
}
CPU 特性检测
ARM 检测 (crypto/cpu_arm_linux.c):
static void arm_read_auxv(void) {
// 读取 /proc/cpuinfo
FILE *f = fopen("/proc/cpuinfo", "r");
// 或使用 getauxval(AT_HWCAP)
// 检测特性
if (hwcap & HWCAP_NEON) {
OPENSSL_armcap_P |= ARMV7_NEON;
}
if (hwcap2 & HWCAP2_AES) {
OPENSSL_armcap_P |= ARMV8_AES;
}
if (hwcap2 & HWCAP2_PMULL) {
OPENSSL_armcap_P |= ARMV8_PMULL;
}
}
x86 检测 (crypto/cpu_intel.c):
static void cpuid(uint32_t *out, uint32_t leaf) {
asm volatile("cpuid"
: "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3])
: "a"(leaf));
}
static void x86_detect_features(void) {
uint32_t regs[4];
cpuid(regs, 1);
if (regs[2] & (1 << 25)) {
OPENSSL_ia32cap_P[1] |= (1 << 57); // AES-NI
}
if (regs[2] & (1 << 30)) {
OPENSSL_ia32cap_P[1] |= (1 << 59); // RDRAND
}
cpuid(regs, 7);
if (regs[1] & (1 << 5)) {
OPENSSL_ia32cap_P[2] |= (1 << 0); // AVX2
}
}
常时间算法
目的: 防止侧信道攻击(时序攻击)
示例:
// 常时间比较
int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) {
const uint8_t *a = in_a;
const uint8_t *b = in_b;
uint8_t x = 0;
for (size_t i = 0; i < len; i++) {
x |= a[i] ^ b[i];
}
return x; // 0 if equal
}
// 常时间条件选择
crypto_word_t constant_time_select_w(crypto_word_t mask,
crypto_word_t a,
crypto_word_t b) {
// mask must be 0 or 0xff..ff
return (a & mask) | (b & ~mask);
}
应用:
- RSA 解密(防止填充预言攻击)
- ECDSA 签名(防止侧信道泄露私钥)
- AES 查找表(缓解缓存时序攻击)
与 OpenSSL 对比
API 兼容性
| 特性 | OpenSSL | BoringSSL |
|---|---|---|
| API 兼容 | 1.0.1 基准 | 移除大量遗留 API |
| ABI 稳定 | 有保证 | 无保证(内部结构可变) |
| 错误处理 | 复杂错误栈 | 简化的错误队列 |
| 对象持久性 | 支持 | 部分对象不可持久 |
| 线程安全 | 需配置回调 | 内置线程安全 |
移除的 API:
SSL_CTX_set_tmp_rsa_callback()- RSA 临时密钥(不安全)SSL_CTX_set_tmp_dh_callback()- DH 临时密钥(不推荐)ENGINE接口 - 硬件加速引擎(架构问题)BIO_s_file_internal()- 内部文件 BIOCRYPTO_set_locking_callback()- 线程锁(已内置)
算法差异
BoringSSL 默认算法:
强制启用:
- TLS 1.2+
- ECDHE + ECDSA/RSA (前向安全)
- AES-GCM, ChaCha20-Poly1305
- P-256, P-384, X25519
默认禁用/移除:
- SSLv2, SSLv3 (已废弃)
- RC4, DES, 3DES (不安全)
- 静态 RSA 密钥交换 (无前向安全)
- 导出级密码套件 (弱加密)
代码组织
| 方面 | OpenSSL | BoringSSL |
|---|---|---|
| 语言 | C (全部) | C (crypto) + C++ (ssl) |
| 模块化 | 松散 | 高度模块化 |
| FIPS 模块 | 可选编译 | 集成设计 (bcm.c) |
| 废弃算法 | 混杂在代码中 | 独立 decrepit/ 目录 |
| 测试 | 分散 | 统一 GTest 框架 |
性能对比
AES-GCM (ARMv8, 1KB 数据块):
| 实现 | 吞吐量 |
|---|---|
| OpenSSL 1.1.1 | 550 MB/s |
| BoringSSL | 580 MB/s |
| 提升 | +5.5% |
RSA-2048 签名:
| 实现 | 签名/秒 |
|---|---|
| OpenSSL 1.1.1 | 1,200 |
| BoringSSL | 1,250 |
| 提升 | +4.2% |
TLS 1.3 握手延迟:
| 实现 | 首次握手 | 恢复握手 |
|---|---|---|
| OpenSSL 1.1.1 | 12 ms | 5 ms |
| BoringSSL | 11 ms | 4 ms |
| 提升 | -8.3% | -20% |
Android 特定优化
BoringSSL 特有:
- Conscrypt 集成 - Java 层零拷贝
- FIPS 验证 - Android 特定证书
- Keystore 集成 - 硬件密钥支持
- System CA - 系统证书管理
- AIDL 接口 - 跨进程加密服务
在 Android 中的使用
Conscrypt (Java 加密提供者)
架构:
Java Application
↓ JCA/JCE API
Conscrypt (Java)
↓ JNI
libconscrypt_jni.so
↓ 链接
libcrypto.so (BoringSSL)
使用示例:
import org.conscrypt.Conscrypt;
// 安装 Conscrypt 为默认提供者
Security.insertProviderAt(Conscrypt.newProvider(), 1);
// 使用 BoringSSL 实现的 AES
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(128, iv));
byte[] ciphertext = cipher.doFinal(plaintext);
// 使用 BoringSSL 实现的 TLS
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, null, null);
SSLSocket socket = (SSLSocket) ctx.getSocketFactory().createSocket(host, port);
System 组件
Keymaster (system/keymaster/)
#include
#include
// 生成 RSA 密钥
EVP_PKEY *pkey = EVP_PKEY_new();
RSA *rsa = RSA_new();
BIGNUM *e = BN_new();
BN_set_word(e, 65537);
RSA_generate_key_ex(rsa, 2048, e, nullptr);
EVP_PKEY_assign_RSA(pkey, rsa);
// 存储到 Keymaster
keymaster_rsa_keygen_params_t params;
keymaster_device->generate_keypair(keymaster_device,
TYPE_RSA, ¶ms,
&blob, &blob_length);
Vold (system/vold/)
全盘加密:
#include
#include
// 派生加密密钥
uint8_t key[32];
PKCS5_PBKDF2_HMAC(password, password_len,
salt, salt_len,
10000, // iterations
EVP_sha256(),
sizeof(key), key);
// AES-XTS 加密磁盘扇区
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_xts(), nullptr, key, iv);
EVP_EncryptUpdate(ctx, out_sector, &out_len,
in_sector, SECTOR_SIZE);
Update Engine (system/update_engine/)
OTA 包签名验证:
#include
#include
// 加载公钥
FILE *fp = fopen("/system/etc/security/otacerts.zip", "rb");
X509 *cert = d2i_X509_fp(fp, nullptr);
EVP_PKEY *pubkey = X509_get_pubkey(cert);
// 验证 RSA-PSS 签名
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
EVP_DigestVerifyInit(ctx, nullptr, EVP_sha256(), nullptr, pubkey);
EVP_DigestVerifyUpdate(ctx, ota_package, ota_size);
int valid = EVP_DigestVerifyFinal(ctx, signature, sig_len);
ADB (packages/modules/adb/)
TLS 认证:
#include
#include
// 创建 TLS 连接
SSL_CTX *ctx = SSL_CTX_new(TLS_method());
SSL_CTX_set_min_proto_version(ctx, TLS1_3_VERSION);
SSL *ssl = SSL_new(ctx);
BIO *bio = BIO_new_socket(fd, BIO_NOCLOSE);
SSL_set_bio(ssl, bio, bio);
// 客户端认证(使用设备证书)
SSL_use_certificate_file(ssl, "/data/misc/adb/cert.pem",
SSL_FILETYPE_PEM);
SSL_use_PrivateKey_file(ssl, "/data/misc/adb/key.pem",
SSL_FILETYPE_PEM);
SSL_connect(ssl);
DRM 框架 (frameworks/av/drm/)
内容解密:
#include
#include
// AES-CTR 解密媒体内容
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_DecryptInit_ex(ctx, EVP_aes_128_ctr(), nullptr, content_key, iv);
uint8_t *plaintext = new uint8_t[encrypted_len];
int plain_len;
EVP_DecryptUpdate(ctx, plaintext, &plain_len,
encrypted_content, encrypted_len);
测试基础设施
测试框架
Google Test (GTest):
// crypto/aes/aes_test.cc
#include
#include
TEST(AESTest, SetKey) {
AES_KEY key;
static const uint8_t kAESKey[16] = {0};
ASSERT_EQ(0, AES_set_encrypt_key(kAESKey, 128, &key));
EXPECT_EQ(10, key.rounds);
}
TEST(AESTest, Encrypt) {
AES_KEY key;
uint8_t block[16] = {0};
AES_set_encrypt_key(kAESKey, 128, &key);
AES_encrypt(block, block, &key);
// 验证输出
EXPECT_EQ(expected[0], block[0]);
}
文件测试框架 (crypto/test/file_test.h):
// 从文件读取测试向量
static bool TestAESGCM(FileTest *t) {
std::vector<uint8_t> key, iv, plaintext, aad, ciphertext, tag;
ASSERT_TRUE(t->GetBytes(&key, "Key"));
ASSERT_TRUE(t->GetBytes(&iv, "IV"));
ASSERT_TRUE(t->GetBytes(&plaintext, "Plaintext"));
// 执行测试
bssl::ScopedEVP_AEAD_CTX ctx;
ASSERT_TRUE(EVP_AEAD_CTX_init(ctx.get(), EVP_aead_aes_256_gcm(),
key.data(), key.size(), tag.size(),
nullptr));
// 验证输出
EXPECT_EQ(Bytes(ciphertext), Bytes(output));
}
// 注册测试
FileTest::Options opts;
opts.path = "crypto/cipher_extra/test/aes_gcm_tests.txt";
return FileTestMain(TestAESGCM, nullptr, opts);
测试数据
Wycheproof 测试向量 (third_party/wycheproof_testvectors/):
- Google 的加密测试项目
- 包含边界情况和已知攻击向量
- 格式: JSON
使用示例:
#include "wycheproof_util.h"
static bool TestWycheproof(FileTest *t) {
std::vector<uint8_t> key, msg, sig;
WycheproofResult result;
ASSERT_TRUE(GetWycheproofResult(t, &result));
ASSERT_TRUE(t->GetBytes(&key, "key"));
ASSERT_TRUE(t->GetBytes(&msg, "msg"));
ASSERT_TRUE(t->GetBytes(&sig, "sig"));
// 验证签名
EC_KEY *eckey = DecodeECKey(key);
int valid = ECDSA_verify(0, msg.data(), msg.size(),
sig.data(), sig.size(), eckey);
EXPECT_EQ(result == WycheproofResult::kValid, valid == 1);
}
Android 测试
CTS (Compatibility Test Suite):
<configuration description="BoringSSL Crypto Tests">
<test class="com.android.tradefed.testtype.GTest">
<option name="native-test-device-path" value="/data/local/tmp" />
<option name="module-name" value="boringssl_crypto_test" />
test>
configuration>
运行测试:
# 编译测试
cd external/boringssl
mm boringssl_crypto_test boringssl_ssl_test
# 安装到设备
adb push out/target/product/*/system/bin/boringssl_crypto_test /data/local/tmp/
adb push out/target/product/*/system/bin/boringssl_ssl_test /data/local/tmp/
# 运行测试
adb shell /data/local/tmp/boringssl_crypto_test
adb shell /data/local/tmp/boringssl_ssl_test
# 或使用 atest
atest boringssl_crypto_test
atest boringssl_ssl_test
FIPS 自检
Self-Test 工具 (boringssl_self_test):
// crypto/fipsmodule/self_check/self_check.c
int main(int argc, char **argv) {
// FIPS 模块完整性检查
BORINGSSL_integrity_test();
// Known Answer Tests (KAT)
if (!BORINGSSL_self_test()) {
fprintf(stderr, "Self-test failed!
");
return 1;
}
printf("FIPS self-test passed.
");
return 0;
}
Android 集成:
# 启动时自动运行
adb shell /system/bin/boringssl_self_test
# 或在 Conscrypt apex 初始化时运行
# /apex/com.android.conscrypt/bin/boringssl_self_test
最佳实践
使用 EVP API
推荐: 使用高层 EVP 接口
// ✅ 推荐:EVP API
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), nullptr, key, iv);
EVP_EncryptUpdate(ctx, out, &out_len, in, in_len);
EVP_EncryptFinal_ex(ctx, out + out_len, &final_len);
EVP_CIPHER_CTX_free(ctx);
避免: 直接调用底层 API
// ❌ 不推荐:直接 AES API
AES_KEY aes_key;
AES_set_encrypt_key(key, 256, &aes_key);
AES_encrypt(block, block, &aes_key); // ECB 模式,不安全!
使用 AEAD
推荐: 使用 AEAD (认证加密)
// ✅ AES-GCM
const EVP_AEAD *aead = EVP_aead_aes_256_gcm();
EVP_AEAD_CTX ctx;
EVP_AEAD_CTX_init(&ctx, aead, key, 32, 16, nullptr);
EVP_AEAD_CTX_seal(&ctx, out, &out_len, max_out,
nonce, 12, in, in_len, ad, ad_len);
// ✅ ChaCha20-Poly1305
const EVP_AEAD *aead = EVP_aead_chacha20_poly1305();
避免: 单独使用加密 + MAC
// ❌ 不推荐:Encrypt-then-MAC (易错)
EVP_EncryptUpdate(ctx, ciphertext, &ct_len, plaintext, pt_len);
HMAC(EVP_sha256(), key, key_len, ciphertext, ct_len, mac, nullptr);
密钥管理
推荐:
// ✅ 使用 Android Keystore
// Java 层
KeyGenerator keyGen = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
keyGen.init(new KeyGenParameterSpec.Builder("my_key",
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build());
SecretKey key = keyGen.generateKey();
// ✅ 使用 HKDF 派生密钥
uint8_t key_material[32];
HKDF(key_material, sizeof(key_material),
EVP_sha256(),
ikm, ikm_len,
salt, salt_len,
info, info_len);
避免:
// ❌ 硬编码密钥
const uint8_t SECRET_KEY[] = {0x01, 0x02, ...}; // 不安全!
// ❌ 弱密钥派生
SHA256(password, password_len, key); // 易受暴力破解
随机数生成
推荐:
// ✅ 使用 RAND_bytes
uint8_t random[32];
RAND_bytes(random, sizeof(random));
// ✅ 密码学安全伪随机数
uint8_t nonce[12];
RAND_bytes(nonce, sizeof(nonce));
避免:
// ❌ 不要使用 rand() 或 random()
int r = rand(); // 不是密码学安全!
// ❌ 不要重用 IV/nonce
memset(iv, 0, sizeof(iv)); // 全零 IV = 灾难!
证书验证
推荐:
// ✅ 完整的证书链验证
X509_STORE *store = X509_STORE_new();
X509_STORE_add_cert(store, root_ca);
X509_STORE_CTX *ctx = X509_STORE_CTX_new();
X509_STORE_CTX_init(ctx, store, cert, chain);
// 设置验证参数
X509_VERIFY_PARAM *param = X509_VERIFY_PARAM_new();
X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
X509_STORE_CTX_set0_param(ctx, param);
// 验证
int result = X509_verify_cert(ctx);
if (result != 1) {
int error = X509_STORE_CTX_get_error(ctx);
// 处理错误
}
避免:
// ❌ 跳过证书验证
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, nullptr); // 危险!
// ❌ 不检查主机名
SSL_connect(ssl); // 未验证 SNI/CN
错误处理
推荐:
// ✅ 检查返回值
if (!EVP_EncryptInit_ex(ctx, cipher, nullptr, key, iv)) {
unsigned long err = ERR_get_error();
char err_buf[256];
ERR_error_string_n(err, err_buf, sizeof(err_buf));
fprintf(stderr, "Encryption init failed: %s
", err_buf);
return -1;
}
// ✅ 清理错误队列
ERR_clear_error();
避免:
// ❌ 忽略错误
EVP_EncryptInit_ex(ctx, cipher, nullptr, key, iv); // 未检查返回值
EVP_EncryptUpdate(ctx, out, &out_len, in, in_len); // 可能失败
内存清理
推荐:
// ✅ 清零敏感数据
uint8_t key[32];
// 使用密钥...
OPENSSL_cleanse(key, sizeof(key));
// ✅ 使用 unique_ptr
bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
// 自动释放
避免:
// ❌ 不清零密钥
memset(key, 0, sizeof(key)); // 可能被编译器优化掉
// ❌ 忘记释放
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
// 使用 ctx...
// 忘记调用 EVP_CIPHER_CTX_free(ctx); // 内存泄漏!
总结
核心优势
-
安全性
- FIPS 140-2 认证
- 持续的安全审计
- 快速的漏洞修复
-
性能
- SIMD 优化 (NEON, AVX2)
- 硬件加速 (AES-NI, ARMv8 Crypto)
- 常时间算法
-
现代化
- TLS 1.3 支持
- 后量子密码 (Kyber)
- 去除遗留算法
-
Android 集成
- Conscrypt 提供者
- Keystore 集成
- 系统服务支持
使用建议
| 场景 | 推荐 |
|---|---|
| Java 应用 | 使用 Conscrypt + JCA/JCE |
| NDK 应用 | 使用 EVP API |
| System 服务 | 链接 libcrypto.so |
| 新算法 | AES-GCM, ChaCha20-Poly1305, X25519, Ed25519 |
| 证书 | 使用系统 CA 存储 |
| 密钥存储 | Android Keystore |
未来发展
-
后量子密码
- Kyber KEM (已实现)
- Dilithium 签名 (规划中)
- 混合 TLS (经典+后量子)
-
性能提升
- ARMv9 SVE 优化
- x86 AVX-512 支持
- RISC-V 优化
-
新特性
- TLS 1.3 ECH (已实现)
- QUIC 协议支持
- MLS (Messaging Layer Security)
官方文档
- BoringSSL GitHub
- BoringSSL 文档
- Conscrypt 项目
Android 集成
- Android Keystore
- FIPS 认证
测试资源
- Wycheproof
- Project Wycheproof 测试向量






