162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Minimal library implementation of GCM 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2022 Google LLC 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/module.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <crypto/algapi.h> 1162306a36Sopenharmony_ci#include <crypto/gcm.h> 1262306a36Sopenharmony_ci#include <crypto/ghash.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <asm/irqflags.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_cistatic void aesgcm_encrypt_block(const struct crypto_aes_ctx *ctx, void *dst, 1762306a36Sopenharmony_ci const void *src) 1862306a36Sopenharmony_ci{ 1962306a36Sopenharmony_ci unsigned long flags; 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci /* 2262306a36Sopenharmony_ci * In AES-GCM, both the GHASH key derivation and the CTR mode 2362306a36Sopenharmony_ci * encryption operate on known plaintext, making them susceptible to 2462306a36Sopenharmony_ci * timing attacks on the encryption key. The AES library already 2562306a36Sopenharmony_ci * mitigates this risk to some extent by pulling the entire S-box into 2662306a36Sopenharmony_ci * the caches before doing any substitutions, but this strategy is more 2762306a36Sopenharmony_ci * effective when running with interrupts disabled. 2862306a36Sopenharmony_ci */ 2962306a36Sopenharmony_ci local_irq_save(flags); 3062306a36Sopenharmony_ci aes_encrypt(ctx, dst, src); 3162306a36Sopenharmony_ci local_irq_restore(flags); 3262306a36Sopenharmony_ci} 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci/** 3562306a36Sopenharmony_ci * aesgcm_expandkey - Expands the AES and GHASH keys for the AES-GCM key 3662306a36Sopenharmony_ci * schedule 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci * @ctx: The data structure that will hold the AES-GCM key schedule 3962306a36Sopenharmony_ci * @key: The AES encryption input key 4062306a36Sopenharmony_ci * @keysize: The length in bytes of the input key 4162306a36Sopenharmony_ci * @authsize: The size in bytes of the GCM authentication tag 4262306a36Sopenharmony_ci * 4362306a36Sopenharmony_ci * Returns: 0 on success, or -EINVAL if @keysize or @authsize contain values 4462306a36Sopenharmony_ci * that are not permitted by the GCM specification. 4562306a36Sopenharmony_ci */ 4662306a36Sopenharmony_ciint aesgcm_expandkey(struct aesgcm_ctx *ctx, const u8 *key, 4762306a36Sopenharmony_ci unsigned int keysize, unsigned int authsize) 4862306a36Sopenharmony_ci{ 4962306a36Sopenharmony_ci u8 kin[AES_BLOCK_SIZE] = {}; 5062306a36Sopenharmony_ci int ret; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci ret = crypto_gcm_check_authsize(authsize) ?: 5362306a36Sopenharmony_ci aes_expandkey(&ctx->aes_ctx, key, keysize); 5462306a36Sopenharmony_ci if (ret) 5562306a36Sopenharmony_ci return ret; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci ctx->authsize = authsize; 5862306a36Sopenharmony_ci aesgcm_encrypt_block(&ctx->aes_ctx, &ctx->ghash_key, kin); 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci return 0; 6162306a36Sopenharmony_ci} 6262306a36Sopenharmony_ciEXPORT_SYMBOL(aesgcm_expandkey); 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cistatic void aesgcm_ghash(be128 *ghash, const be128 *key, const void *src, 6562306a36Sopenharmony_ci int len) 6662306a36Sopenharmony_ci{ 6762306a36Sopenharmony_ci while (len > 0) { 6862306a36Sopenharmony_ci crypto_xor((u8 *)ghash, src, min(len, GHASH_BLOCK_SIZE)); 6962306a36Sopenharmony_ci gf128mul_lle(ghash, key); 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci src += GHASH_BLOCK_SIZE; 7262306a36Sopenharmony_ci len -= GHASH_BLOCK_SIZE; 7362306a36Sopenharmony_ci } 7462306a36Sopenharmony_ci} 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_cistatic void aesgcm_mac(const struct aesgcm_ctx *ctx, const u8 *src, int src_len, 7762306a36Sopenharmony_ci const u8 *assoc, int assoc_len, __be32 *ctr, u8 *authtag) 7862306a36Sopenharmony_ci{ 7962306a36Sopenharmony_ci be128 tail = { cpu_to_be64(assoc_len * 8), cpu_to_be64(src_len * 8) }; 8062306a36Sopenharmony_ci u8 buf[AES_BLOCK_SIZE]; 8162306a36Sopenharmony_ci be128 ghash = {}; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci aesgcm_ghash(&ghash, &ctx->ghash_key, assoc, assoc_len); 8462306a36Sopenharmony_ci aesgcm_ghash(&ghash, &ctx->ghash_key, src, src_len); 8562306a36Sopenharmony_ci aesgcm_ghash(&ghash, &ctx->ghash_key, &tail, sizeof(tail)); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci ctr[3] = cpu_to_be32(1); 8862306a36Sopenharmony_ci aesgcm_encrypt_block(&ctx->aes_ctx, buf, ctr); 8962306a36Sopenharmony_ci crypto_xor_cpy(authtag, buf, (u8 *)&ghash, ctx->authsize); 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci memzero_explicit(&ghash, sizeof(ghash)); 9262306a36Sopenharmony_ci memzero_explicit(buf, sizeof(buf)); 9362306a36Sopenharmony_ci} 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_cistatic void aesgcm_crypt(const struct aesgcm_ctx *ctx, u8 *dst, const u8 *src, 9662306a36Sopenharmony_ci int len, __be32 *ctr) 9762306a36Sopenharmony_ci{ 9862306a36Sopenharmony_ci u8 buf[AES_BLOCK_SIZE]; 9962306a36Sopenharmony_ci unsigned int n = 2; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci while (len > 0) { 10262306a36Sopenharmony_ci /* 10362306a36Sopenharmony_ci * The counter increment below must not result in overflow or 10462306a36Sopenharmony_ci * carry into the next 32-bit word, as this could result in 10562306a36Sopenharmony_ci * inadvertent IV reuse, which must be avoided at all cost for 10662306a36Sopenharmony_ci * stream ciphers such as AES-CTR. Given the range of 'int 10762306a36Sopenharmony_ci * len', this cannot happen, so no explicit test is necessary. 10862306a36Sopenharmony_ci */ 10962306a36Sopenharmony_ci ctr[3] = cpu_to_be32(n++); 11062306a36Sopenharmony_ci aesgcm_encrypt_block(&ctx->aes_ctx, buf, ctr); 11162306a36Sopenharmony_ci crypto_xor_cpy(dst, src, buf, min(len, AES_BLOCK_SIZE)); 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci dst += AES_BLOCK_SIZE; 11462306a36Sopenharmony_ci src += AES_BLOCK_SIZE; 11562306a36Sopenharmony_ci len -= AES_BLOCK_SIZE; 11662306a36Sopenharmony_ci } 11762306a36Sopenharmony_ci memzero_explicit(buf, sizeof(buf)); 11862306a36Sopenharmony_ci} 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci/** 12162306a36Sopenharmony_ci * aesgcm_encrypt - Perform AES-GCM encryption on a block of data 12262306a36Sopenharmony_ci * 12362306a36Sopenharmony_ci * @ctx: The AES-GCM key schedule 12462306a36Sopenharmony_ci * @dst: Pointer to the ciphertext output buffer 12562306a36Sopenharmony_ci * @src: Pointer the plaintext (may equal @dst for encryption in place) 12662306a36Sopenharmony_ci * @crypt_len: The size in bytes of the plaintext and ciphertext. 12762306a36Sopenharmony_ci * @assoc: Pointer to the associated data, 12862306a36Sopenharmony_ci * @assoc_len: The size in bytes of the associated data 12962306a36Sopenharmony_ci * @iv: The initialization vector (IV) to use for this block of data 13062306a36Sopenharmony_ci * (must be 12 bytes in size as per the GCM spec recommendation) 13162306a36Sopenharmony_ci * @authtag: The address of the buffer in memory where the authentication 13262306a36Sopenharmony_ci * tag should be stored. The buffer is assumed to have space for 13362306a36Sopenharmony_ci * @ctx->authsize bytes. 13462306a36Sopenharmony_ci */ 13562306a36Sopenharmony_civoid aesgcm_encrypt(const struct aesgcm_ctx *ctx, u8 *dst, const u8 *src, 13662306a36Sopenharmony_ci int crypt_len, const u8 *assoc, int assoc_len, 13762306a36Sopenharmony_ci const u8 iv[GCM_AES_IV_SIZE], u8 *authtag) 13862306a36Sopenharmony_ci{ 13962306a36Sopenharmony_ci __be32 ctr[4]; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci memcpy(ctr, iv, GCM_AES_IV_SIZE); 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci aesgcm_crypt(ctx, dst, src, crypt_len, ctr); 14462306a36Sopenharmony_ci aesgcm_mac(ctx, dst, crypt_len, assoc, assoc_len, ctr, authtag); 14562306a36Sopenharmony_ci} 14662306a36Sopenharmony_ciEXPORT_SYMBOL(aesgcm_encrypt); 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci/** 14962306a36Sopenharmony_ci * aesgcm_decrypt - Perform AES-GCM decryption on a block of data 15062306a36Sopenharmony_ci * 15162306a36Sopenharmony_ci * @ctx: The AES-GCM key schedule 15262306a36Sopenharmony_ci * @dst: Pointer to the plaintext output buffer 15362306a36Sopenharmony_ci * @src: Pointer the ciphertext (may equal @dst for decryption in place) 15462306a36Sopenharmony_ci * @crypt_len: The size in bytes of the plaintext and ciphertext. 15562306a36Sopenharmony_ci * @assoc: Pointer to the associated data, 15662306a36Sopenharmony_ci * @assoc_len: The size in bytes of the associated data 15762306a36Sopenharmony_ci * @iv: The initialization vector (IV) to use for this block of data 15862306a36Sopenharmony_ci * (must be 12 bytes in size as per the GCM spec recommendation) 15962306a36Sopenharmony_ci * @authtag: The address of the buffer in memory where the authentication 16062306a36Sopenharmony_ci * tag is stored. 16162306a36Sopenharmony_ci * 16262306a36Sopenharmony_ci * Returns: true on success, or false if the ciphertext failed authentication. 16362306a36Sopenharmony_ci * On failure, no plaintext will be returned. 16462306a36Sopenharmony_ci */ 16562306a36Sopenharmony_cibool __must_check aesgcm_decrypt(const struct aesgcm_ctx *ctx, u8 *dst, 16662306a36Sopenharmony_ci const u8 *src, int crypt_len, const u8 *assoc, 16762306a36Sopenharmony_ci int assoc_len, const u8 iv[GCM_AES_IV_SIZE], 16862306a36Sopenharmony_ci const u8 *authtag) 16962306a36Sopenharmony_ci{ 17062306a36Sopenharmony_ci u8 tagbuf[AES_BLOCK_SIZE]; 17162306a36Sopenharmony_ci __be32 ctr[4]; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci memcpy(ctr, iv, GCM_AES_IV_SIZE); 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci aesgcm_mac(ctx, src, crypt_len, assoc, assoc_len, ctr, tagbuf); 17662306a36Sopenharmony_ci if (crypto_memneq(authtag, tagbuf, ctx->authsize)) { 17762306a36Sopenharmony_ci memzero_explicit(tagbuf, sizeof(tagbuf)); 17862306a36Sopenharmony_ci return false; 17962306a36Sopenharmony_ci } 18062306a36Sopenharmony_ci aesgcm_crypt(ctx, dst, src, crypt_len, ctr); 18162306a36Sopenharmony_ci return true; 18262306a36Sopenharmony_ci} 18362306a36Sopenharmony_ciEXPORT_SYMBOL(aesgcm_decrypt); 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ciMODULE_DESCRIPTION("Generic AES-GCM library"); 18662306a36Sopenharmony_ciMODULE_AUTHOR("Ard Biesheuvel <ardb@kernel.org>"); 18762306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci#ifndef CONFIG_CRYPTO_MANAGER_DISABLE_TESTS 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci/* 19262306a36Sopenharmony_ci * Test code below. Vectors taken from crypto/testmgr.h 19362306a36Sopenharmony_ci */ 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_cistatic const u8 __initconst ctext0[16] = 19662306a36Sopenharmony_ci "\x58\xe2\xfc\xce\xfa\x7e\x30\x61" 19762306a36Sopenharmony_ci "\x36\x7f\x1d\x57\xa4\xe7\x45\x5a"; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_cistatic const u8 __initconst ptext1[16]; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_cistatic const u8 __initconst ctext1[32] = 20262306a36Sopenharmony_ci "\x03\x88\xda\xce\x60\xb6\xa3\x92" 20362306a36Sopenharmony_ci "\xf3\x28\xc2\xb9\x71\xb2\xfe\x78" 20462306a36Sopenharmony_ci "\xab\x6e\x47\xd4\x2c\xec\x13\xbd" 20562306a36Sopenharmony_ci "\xf5\x3a\x67\xb2\x12\x57\xbd\xdf"; 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_cistatic const u8 __initconst ptext2[64] = 20862306a36Sopenharmony_ci "\xd9\x31\x32\x25\xf8\x84\x06\xe5" 20962306a36Sopenharmony_ci "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" 21062306a36Sopenharmony_ci "\x86\xa7\xa9\x53\x15\x34\xf7\xda" 21162306a36Sopenharmony_ci "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" 21262306a36Sopenharmony_ci "\x1c\x3c\x0c\x95\x95\x68\x09\x53" 21362306a36Sopenharmony_ci "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" 21462306a36Sopenharmony_ci "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57" 21562306a36Sopenharmony_ci "\xba\x63\x7b\x39\x1a\xaf\xd2\x55"; 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_cistatic const u8 __initconst ctext2[80] = 21862306a36Sopenharmony_ci "\x42\x83\x1e\xc2\x21\x77\x74\x24" 21962306a36Sopenharmony_ci "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c" 22062306a36Sopenharmony_ci "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0" 22162306a36Sopenharmony_ci "\x35\xc1\x7e\x23\x29\xac\xa1\x2e" 22262306a36Sopenharmony_ci "\x21\xd5\x14\xb2\x54\x66\x93\x1c" 22362306a36Sopenharmony_ci "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05" 22462306a36Sopenharmony_ci "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97" 22562306a36Sopenharmony_ci "\x3d\x58\xe0\x91\x47\x3f\x59\x85" 22662306a36Sopenharmony_ci "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6" 22762306a36Sopenharmony_ci "\x2c\xf3\x5a\xbd\x2b\xa6\xfa\xb4"; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_cistatic const u8 __initconst ptext3[60] = 23062306a36Sopenharmony_ci "\xd9\x31\x32\x25\xf8\x84\x06\xe5" 23162306a36Sopenharmony_ci "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" 23262306a36Sopenharmony_ci "\x86\xa7\xa9\x53\x15\x34\xf7\xda" 23362306a36Sopenharmony_ci "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" 23462306a36Sopenharmony_ci "\x1c\x3c\x0c\x95\x95\x68\x09\x53" 23562306a36Sopenharmony_ci "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" 23662306a36Sopenharmony_ci "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57" 23762306a36Sopenharmony_ci "\xba\x63\x7b\x39"; 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_cistatic const u8 __initconst ctext3[76] = 24062306a36Sopenharmony_ci "\x42\x83\x1e\xc2\x21\x77\x74\x24" 24162306a36Sopenharmony_ci "\x4b\x72\x21\xb7\x84\xd0\xd4\x9c" 24262306a36Sopenharmony_ci "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0" 24362306a36Sopenharmony_ci "\x35\xc1\x7e\x23\x29\xac\xa1\x2e" 24462306a36Sopenharmony_ci "\x21\xd5\x14\xb2\x54\x66\x93\x1c" 24562306a36Sopenharmony_ci "\x7d\x8f\x6a\x5a\xac\x84\xaa\x05" 24662306a36Sopenharmony_ci "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97" 24762306a36Sopenharmony_ci "\x3d\x58\xe0\x91" 24862306a36Sopenharmony_ci "\x5b\xc9\x4f\xbc\x32\x21\xa5\xdb" 24962306a36Sopenharmony_ci "\x94\xfa\xe9\x5a\xe7\x12\x1a\x47"; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_cistatic const u8 __initconst ctext4[16] = 25262306a36Sopenharmony_ci "\xcd\x33\xb2\x8a\xc7\x73\xf7\x4b" 25362306a36Sopenharmony_ci "\xa0\x0e\xd1\xf3\x12\x57\x24\x35"; 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_cistatic const u8 __initconst ctext5[32] = 25662306a36Sopenharmony_ci "\x98\xe7\x24\x7c\x07\xf0\xfe\x41" 25762306a36Sopenharmony_ci "\x1c\x26\x7e\x43\x84\xb0\xf6\x00" 25862306a36Sopenharmony_ci "\x2f\xf5\x8d\x80\x03\x39\x27\xab" 25962306a36Sopenharmony_ci "\x8e\xf4\xd4\x58\x75\x14\xf0\xfb"; 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_cistatic const u8 __initconst ptext6[64] = 26262306a36Sopenharmony_ci "\xd9\x31\x32\x25\xf8\x84\x06\xe5" 26362306a36Sopenharmony_ci "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" 26462306a36Sopenharmony_ci "\x86\xa7\xa9\x53\x15\x34\xf7\xda" 26562306a36Sopenharmony_ci "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" 26662306a36Sopenharmony_ci "\x1c\x3c\x0c\x95\x95\x68\x09\x53" 26762306a36Sopenharmony_ci "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" 26862306a36Sopenharmony_ci "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57" 26962306a36Sopenharmony_ci "\xba\x63\x7b\x39\x1a\xaf\xd2\x55"; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_cistatic const u8 __initconst ctext6[80] = 27262306a36Sopenharmony_ci "\x39\x80\xca\x0b\x3c\x00\xe8\x41" 27362306a36Sopenharmony_ci "\xeb\x06\xfa\xc4\x87\x2a\x27\x57" 27462306a36Sopenharmony_ci "\x85\x9e\x1c\xea\xa6\xef\xd9\x84" 27562306a36Sopenharmony_ci "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c" 27662306a36Sopenharmony_ci "\x7d\x77\x3d\x00\xc1\x44\xc5\x25" 27762306a36Sopenharmony_ci "\xac\x61\x9d\x18\xc8\x4a\x3f\x47" 27862306a36Sopenharmony_ci "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9" 27962306a36Sopenharmony_ci "\xcc\xda\x27\x10\xac\xad\xe2\x56" 28062306a36Sopenharmony_ci "\x99\x24\xa7\xc8\x58\x73\x36\xbf" 28162306a36Sopenharmony_ci "\xb1\x18\x02\x4d\xb8\x67\x4a\x14"; 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_cistatic const u8 __initconst ctext7[16] = 28462306a36Sopenharmony_ci "\x53\x0f\x8a\xfb\xc7\x45\x36\xb9" 28562306a36Sopenharmony_ci "\xa9\x63\xb4\xf1\xc4\xcb\x73\x8b"; 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_cistatic const u8 __initconst ctext8[32] = 28862306a36Sopenharmony_ci "\xce\xa7\x40\x3d\x4d\x60\x6b\x6e" 28962306a36Sopenharmony_ci "\x07\x4e\xc5\xd3\xba\xf3\x9d\x18" 29062306a36Sopenharmony_ci "\xd0\xd1\xc8\xa7\x99\x99\x6b\xf0" 29162306a36Sopenharmony_ci "\x26\x5b\x98\xb5\xd4\x8a\xb9\x19"; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_cistatic const u8 __initconst ptext9[64] = 29462306a36Sopenharmony_ci "\xd9\x31\x32\x25\xf8\x84\x06\xe5" 29562306a36Sopenharmony_ci "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" 29662306a36Sopenharmony_ci "\x86\xa7\xa9\x53\x15\x34\xf7\xda" 29762306a36Sopenharmony_ci "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" 29862306a36Sopenharmony_ci "\x1c\x3c\x0c\x95\x95\x68\x09\x53" 29962306a36Sopenharmony_ci "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" 30062306a36Sopenharmony_ci "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57" 30162306a36Sopenharmony_ci "\xba\x63\x7b\x39\x1a\xaf\xd2\x55"; 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_cistatic const u8 __initconst ctext9[80] = 30462306a36Sopenharmony_ci "\x52\x2d\xc1\xf0\x99\x56\x7d\x07" 30562306a36Sopenharmony_ci "\xf4\x7f\x37\xa3\x2a\x84\x42\x7d" 30662306a36Sopenharmony_ci "\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9" 30762306a36Sopenharmony_ci "\x75\x98\xa2\xbd\x25\x55\xd1\xaa" 30862306a36Sopenharmony_ci "\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d" 30962306a36Sopenharmony_ci "\xa7\xb0\x8b\x10\x56\x82\x88\x38" 31062306a36Sopenharmony_ci "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a" 31162306a36Sopenharmony_ci "\xbc\xc9\xf6\x62\x89\x80\x15\xad" 31262306a36Sopenharmony_ci "\xb0\x94\xda\xc5\xd9\x34\x71\xbd" 31362306a36Sopenharmony_ci "\xec\x1a\x50\x22\x70\xe3\xcc\x6c"; 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_cistatic const u8 __initconst ptext10[60] = 31662306a36Sopenharmony_ci "\xd9\x31\x32\x25\xf8\x84\x06\xe5" 31762306a36Sopenharmony_ci "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" 31862306a36Sopenharmony_ci "\x86\xa7\xa9\x53\x15\x34\xf7\xda" 31962306a36Sopenharmony_ci "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" 32062306a36Sopenharmony_ci "\x1c\x3c\x0c\x95\x95\x68\x09\x53" 32162306a36Sopenharmony_ci "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" 32262306a36Sopenharmony_ci "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57" 32362306a36Sopenharmony_ci "\xba\x63\x7b\x39"; 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_cistatic const u8 __initconst ctext10[76] = 32662306a36Sopenharmony_ci "\x52\x2d\xc1\xf0\x99\x56\x7d\x07" 32762306a36Sopenharmony_ci "\xf4\x7f\x37\xa3\x2a\x84\x42\x7d" 32862306a36Sopenharmony_ci "\x64\x3a\x8c\xdc\xbf\xe5\xc0\xc9" 32962306a36Sopenharmony_ci "\x75\x98\xa2\xbd\x25\x55\xd1\xaa" 33062306a36Sopenharmony_ci "\x8c\xb0\x8e\x48\x59\x0d\xbb\x3d" 33162306a36Sopenharmony_ci "\xa7\xb0\x8b\x10\x56\x82\x88\x38" 33262306a36Sopenharmony_ci "\xc5\xf6\x1e\x63\x93\xba\x7a\x0a" 33362306a36Sopenharmony_ci "\xbc\xc9\xf6\x62" 33462306a36Sopenharmony_ci "\x76\xfc\x6e\xce\x0f\x4e\x17\x68" 33562306a36Sopenharmony_ci "\xcd\xdf\x88\x53\xbb\x2d\x55\x1b"; 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_cistatic const u8 __initconst ptext11[60] = 33862306a36Sopenharmony_ci "\xd9\x31\x32\x25\xf8\x84\x06\xe5" 33962306a36Sopenharmony_ci "\xa5\x59\x09\xc5\xaf\xf5\x26\x9a" 34062306a36Sopenharmony_ci "\x86\xa7\xa9\x53\x15\x34\xf7\xda" 34162306a36Sopenharmony_ci "\x2e\x4c\x30\x3d\x8a\x31\x8a\x72" 34262306a36Sopenharmony_ci "\x1c\x3c\x0c\x95\x95\x68\x09\x53" 34362306a36Sopenharmony_ci "\x2f\xcf\x0e\x24\x49\xa6\xb5\x25" 34462306a36Sopenharmony_ci "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57" 34562306a36Sopenharmony_ci "\xba\x63\x7b\x39"; 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_cistatic const u8 __initconst ctext11[76] = 34862306a36Sopenharmony_ci "\x39\x80\xca\x0b\x3c\x00\xe8\x41" 34962306a36Sopenharmony_ci "\xeb\x06\xfa\xc4\x87\x2a\x27\x57" 35062306a36Sopenharmony_ci "\x85\x9e\x1c\xea\xa6\xef\xd9\x84" 35162306a36Sopenharmony_ci "\x62\x85\x93\xb4\x0c\xa1\xe1\x9c" 35262306a36Sopenharmony_ci "\x7d\x77\x3d\x00\xc1\x44\xc5\x25" 35362306a36Sopenharmony_ci "\xac\x61\x9d\x18\xc8\x4a\x3f\x47" 35462306a36Sopenharmony_ci "\x18\xe2\x44\x8b\x2f\xe3\x24\xd9" 35562306a36Sopenharmony_ci "\xcc\xda\x27\x10" 35662306a36Sopenharmony_ci "\x25\x19\x49\x8e\x80\xf1\x47\x8f" 35762306a36Sopenharmony_ci "\x37\xba\x55\xbd\x6d\x27\x61\x8c"; 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_cistatic const u8 __initconst ptext12[719] = 36062306a36Sopenharmony_ci "\x42\xc1\xcc\x08\x48\x6f\x41\x3f" 36162306a36Sopenharmony_ci "\x2f\x11\x66\x8b\x2a\x16\xf0\xe0" 36262306a36Sopenharmony_ci "\x58\x83\xf0\xc3\x70\x14\xc0\x5b" 36362306a36Sopenharmony_ci "\x3f\xec\x1d\x25\x3c\x51\xd2\x03" 36462306a36Sopenharmony_ci "\xcf\x59\x74\x1f\xb2\x85\xb4\x07" 36562306a36Sopenharmony_ci "\xc6\x6a\x63\x39\x8a\x5b\xde\xcb" 36662306a36Sopenharmony_ci "\xaf\x08\x44\xbd\x6f\x91\x15\xe1" 36762306a36Sopenharmony_ci "\xf5\x7a\x6e\x18\xbd\xdd\x61\x50" 36862306a36Sopenharmony_ci "\x59\xa9\x97\xab\xbb\x0e\x74\x5c" 36962306a36Sopenharmony_ci "\x00\xa4\x43\x54\x04\x54\x9b\x3b" 37062306a36Sopenharmony_ci "\x77\xec\xfd\x5c\xa6\xe8\x7b\x08" 37162306a36Sopenharmony_ci "\xae\xe6\x10\x3f\x32\x65\xd1\xfc" 37262306a36Sopenharmony_ci "\xa4\x1d\x2c\x31\xfb\x33\x7a\xb3" 37362306a36Sopenharmony_ci "\x35\x23\xf4\x20\x41\xd4\xad\x82" 37462306a36Sopenharmony_ci "\x8b\xa4\xad\x96\x1c\x20\x53\xbe" 37562306a36Sopenharmony_ci "\x0e\xa6\xf4\xdc\x78\x49\x3e\x72" 37662306a36Sopenharmony_ci "\xb1\xa9\xb5\x83\xcb\x08\x54\xb7" 37762306a36Sopenharmony_ci "\xad\x49\x3a\xae\x98\xce\xa6\x66" 37862306a36Sopenharmony_ci "\x10\x30\x90\x8c\x55\x83\xd7\x7c" 37962306a36Sopenharmony_ci "\x8b\xe6\x53\xde\xd2\x6e\x18\x21" 38062306a36Sopenharmony_ci "\x01\x52\xd1\x9f\x9d\xbb\x9c\x73" 38162306a36Sopenharmony_ci "\x57\xcc\x89\x09\x75\x9b\x78\x70" 38262306a36Sopenharmony_ci "\xed\x26\x97\x4d\xb4\xe4\x0c\xa5" 38362306a36Sopenharmony_ci "\xfa\x70\x04\x70\xc6\x96\x1c\x7d" 38462306a36Sopenharmony_ci "\x54\x41\x77\xa8\xe3\xb0\x7e\x96" 38562306a36Sopenharmony_ci "\x82\xd9\xec\xa2\x87\x68\x55\xf9" 38662306a36Sopenharmony_ci "\x8f\x9e\x73\x43\x47\x6a\x08\x36" 38762306a36Sopenharmony_ci "\x93\x67\xa8\x2d\xde\xac\x41\xa9" 38862306a36Sopenharmony_ci "\x5c\x4d\x73\x97\x0f\x70\x68\xfa" 38962306a36Sopenharmony_ci "\x56\x4d\x00\xc2\x3b\x1f\xc8\xb9" 39062306a36Sopenharmony_ci "\x78\x1f\x51\x07\xe3\x9a\x13\x4e" 39162306a36Sopenharmony_ci "\xed\x2b\x2e\xa3\xf7\x44\xb2\xe7" 39262306a36Sopenharmony_ci "\xab\x19\x37\xd9\xba\x76\x5e\xd2" 39362306a36Sopenharmony_ci "\xf2\x53\x15\x17\x4c\x6b\x16\x9f" 39462306a36Sopenharmony_ci "\x02\x66\x49\xca\x7c\x91\x05\xf2" 39562306a36Sopenharmony_ci "\x45\x36\x1e\xf5\x77\xad\x1f\x46" 39662306a36Sopenharmony_ci "\xa8\x13\xfb\x63\xb6\x08\x99\x63" 39762306a36Sopenharmony_ci "\x82\xa2\xed\xb3\xac\xdf\x43\x19" 39862306a36Sopenharmony_ci "\x45\xea\x78\x73\xd9\xb7\x39\x11" 39962306a36Sopenharmony_ci "\xa3\x13\x7c\xf8\x3f\xf7\xad\x81" 40062306a36Sopenharmony_ci "\x48\x2f\xa9\x5c\x5f\xa0\xf0\x79" 40162306a36Sopenharmony_ci "\xa4\x47\x7d\x80\x20\x26\xfd\x63" 40262306a36Sopenharmony_ci "\x0a\xc7\x7e\x6d\x75\x47\xff\x76" 40362306a36Sopenharmony_ci "\x66\x2e\x8a\x6c\x81\x35\xaf\x0b" 40462306a36Sopenharmony_ci "\x2e\x6a\x49\x60\xc1\x10\xe1\xe1" 40562306a36Sopenharmony_ci "\x54\x03\xa4\x09\x0c\x37\x7a\x15" 40662306a36Sopenharmony_ci "\x23\x27\x5b\x8b\x4b\xa5\x64\x97" 40762306a36Sopenharmony_ci "\xae\x4a\x50\x73\x1f\x66\x1c\x5c" 40862306a36Sopenharmony_ci "\x03\x25\x3c\x8d\x48\x58\x71\x34" 40962306a36Sopenharmony_ci "\x0e\xec\x4e\x55\x1a\x03\x6a\xe5" 41062306a36Sopenharmony_ci "\xb6\x19\x2b\x84\x2a\x20\xd1\xea" 41162306a36Sopenharmony_ci "\x80\x6f\x96\x0e\x05\x62\xc7\x78" 41262306a36Sopenharmony_ci "\x87\x79\x60\x38\x46\xb4\x25\x57" 41362306a36Sopenharmony_ci "\x6e\x16\x63\xf8\xad\x6e\xd7\x42" 41462306a36Sopenharmony_ci "\x69\xe1\x88\xef\x6e\xd5\xb4\x9a" 41562306a36Sopenharmony_ci "\x3c\x78\x6c\x3b\xe5\xa0\x1d\x22" 41662306a36Sopenharmony_ci "\x86\x5c\x74\x3a\xeb\x24\x26\xc7" 41762306a36Sopenharmony_ci "\x09\xfc\x91\x96\x47\x87\x4f\x1a" 41862306a36Sopenharmony_ci "\xd6\x6b\x2c\x18\x47\xc0\xb8\x24" 41962306a36Sopenharmony_ci "\xa8\x5a\x4a\x9e\xcb\x03\xe7\x2a" 42062306a36Sopenharmony_ci "\x09\xe6\x4d\x9c\x6d\x86\x60\xf5" 42162306a36Sopenharmony_ci "\x2f\x48\x69\x37\x9f\xf2\xd2\xcb" 42262306a36Sopenharmony_ci "\x0e\x5a\xdd\x6e\x8a\xfb\x6a\xfe" 42362306a36Sopenharmony_ci "\x0b\x63\xde\x87\x42\x79\x8a\x68" 42462306a36Sopenharmony_ci "\x51\x28\x9b\x7a\xeb\xaf\xb8\x2f" 42562306a36Sopenharmony_ci "\x9d\xd1\xc7\x45\x90\x08\xc9\x83" 42662306a36Sopenharmony_ci "\xe9\x83\x84\xcb\x28\x69\x09\x69" 42762306a36Sopenharmony_ci "\xce\x99\x46\x00\x54\xcb\xd8\x38" 42862306a36Sopenharmony_ci "\xf9\x53\x4a\xbf\x31\xce\x57\x15" 42962306a36Sopenharmony_ci "\x33\xfa\x96\x04\x33\x42\xe3\xc0" 43062306a36Sopenharmony_ci "\xb7\x54\x4a\x65\x7a\x7c\x02\xe6" 43162306a36Sopenharmony_ci "\x19\x95\xd0\x0e\x82\x07\x63\xf9" 43262306a36Sopenharmony_ci "\xe1\x2b\x2a\xfc\x55\x92\x52\xc9" 43362306a36Sopenharmony_ci "\xb5\x9f\x23\x28\x60\xe7\x20\x51" 43462306a36Sopenharmony_ci "\x10\xd3\xed\x6d\x9b\xab\xb8\xe2" 43562306a36Sopenharmony_ci "\x5d\x9a\x34\xb3\xbe\x9c\x64\xcb" 43662306a36Sopenharmony_ci "\x78\xc6\x91\x22\x40\x91\x80\xbe" 43762306a36Sopenharmony_ci "\xd7\x78\x5c\x0e\x0a\xdc\x08\xe9" 43862306a36Sopenharmony_ci "\x67\x10\xa4\x83\x98\x79\x23\xe7" 43962306a36Sopenharmony_ci "\x92\xda\xa9\x22\x16\xb1\xe7\x78" 44062306a36Sopenharmony_ci "\xa3\x1c\x6c\x8f\x35\x7c\x4d\x37" 44162306a36Sopenharmony_ci "\x2f\x6e\x0b\x50\x5c\x34\xb9\xf9" 44262306a36Sopenharmony_ci "\xe6\x3d\x91\x0d\x32\x95\xaa\x3d" 44362306a36Sopenharmony_ci "\x48\x11\x06\xbb\x2d\xf2\x63\x88" 44462306a36Sopenharmony_ci "\x3f\x73\x09\xe2\x45\x56\x31\x51" 44562306a36Sopenharmony_ci "\xfa\x5e\x4e\x62\xf7\x90\xf9\xa9" 44662306a36Sopenharmony_ci "\x7d\x7b\x1b\xb1\xc8\x26\x6e\x66" 44762306a36Sopenharmony_ci "\xf6\x90\x9a\x7f\xf2\x57\xcc\x23" 44862306a36Sopenharmony_ci "\x59\xfa\xfa\xaa\x44\x04\x01\xa7" 44962306a36Sopenharmony_ci "\xa4\x78\xdb\x74\x3d\x8b\xb5"; 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_cistatic const u8 __initconst ctext12[735] = 45262306a36Sopenharmony_ci "\x84\x0b\xdb\xd5\xb7\xa8\xfe\x20" 45362306a36Sopenharmony_ci "\xbb\xb1\x12\x7f\x41\xea\xb3\xc0" 45462306a36Sopenharmony_ci "\xa2\xb4\x37\x19\x11\x58\xb6\x0b" 45562306a36Sopenharmony_ci "\x4c\x1d\x38\x05\x54\xd1\x16\x73" 45662306a36Sopenharmony_ci "\x8e\x1c\x20\x90\xa2\x9a\xb7\x74" 45762306a36Sopenharmony_ci "\x47\xe6\xd8\xfc\x18\x3a\xb4\xea" 45862306a36Sopenharmony_ci "\xd5\x16\x5a\x2c\x53\x01\x46\xb3" 45962306a36Sopenharmony_ci "\x18\x33\x74\x6c\x50\xf2\xe8\xc0" 46062306a36Sopenharmony_ci "\x73\xda\x60\x22\xeb\xe3\xe5\x9b" 46162306a36Sopenharmony_ci "\x20\x93\x6c\x4b\x37\x99\xb8\x23" 46262306a36Sopenharmony_ci "\x3b\x4e\xac\xe8\x5b\xe8\x0f\xb7" 46362306a36Sopenharmony_ci "\xc3\x8f\xfb\x4a\x37\xd9\x39\x95" 46462306a36Sopenharmony_ci "\x34\xf1\xdb\x8f\x71\xd9\xc7\x0b" 46562306a36Sopenharmony_ci "\x02\xf1\x63\xfc\x9b\xfc\xc5\xab" 46662306a36Sopenharmony_ci "\xb9\x14\x13\x21\xdf\xce\xaa\x88" 46762306a36Sopenharmony_ci "\x44\x30\x1e\xce\x26\x01\x92\xf8" 46862306a36Sopenharmony_ci "\x9f\x00\x4b\x0c\x4b\xf7\x5f\xe0" 46962306a36Sopenharmony_ci "\x89\xca\x94\x66\x11\x21\x97\xca" 47062306a36Sopenharmony_ci "\x3e\x83\x74\x2d\xdb\x4d\x11\xeb" 47162306a36Sopenharmony_ci "\x97\xc2\x14\xff\x9e\x1e\xa0\x6b" 47262306a36Sopenharmony_ci "\x08\xb4\x31\x2b\x85\xc6\x85\x6c" 47362306a36Sopenharmony_ci "\x90\xec\x39\xc0\xec\xb3\xb5\x4e" 47462306a36Sopenharmony_ci "\xf3\x9c\xe7\x83\x3a\x77\x0a\xf4" 47562306a36Sopenharmony_ci "\x56\xfe\xce\x18\x33\x6d\x0b\x2d" 47662306a36Sopenharmony_ci "\x33\xda\xc8\x05\x5c\xb4\x09\x2a" 47762306a36Sopenharmony_ci "\xde\x6b\x52\x98\x01\xef\x36\x3d" 47862306a36Sopenharmony_ci "\xbd\xf9\x8f\xa8\x3e\xaa\xcd\xd1" 47962306a36Sopenharmony_ci "\x01\x2d\x42\x49\xc3\xb6\x84\xbb" 48062306a36Sopenharmony_ci "\x48\x96\xe0\x90\x93\x6c\x48\x64" 48162306a36Sopenharmony_ci "\xd4\xfa\x7f\x93\x2c\xa6\x21\xc8" 48262306a36Sopenharmony_ci "\x7a\x23\x7b\xaa\x20\x56\x12\xae" 48362306a36Sopenharmony_ci "\x16\x9d\x94\x0f\x54\xa1\xec\xca" 48462306a36Sopenharmony_ci "\x51\x4e\xf2\x39\xf4\xf8\x5f\x04" 48562306a36Sopenharmony_ci "\x5a\x0d\xbf\xf5\x83\xa1\x15\xe1" 48662306a36Sopenharmony_ci "\xf5\x3c\xd8\x62\xa3\xed\x47\x89" 48762306a36Sopenharmony_ci "\x85\x4c\xe5\xdb\xac\x9e\x17\x1d" 48862306a36Sopenharmony_ci "\x0c\x09\xe3\x3e\x39\x5b\x4d\x74" 48962306a36Sopenharmony_ci "\x0e\xf5\x34\xee\x70\x11\x4c\xfd" 49062306a36Sopenharmony_ci "\xdb\x34\xb1\xb5\x10\x3f\x73\xb7" 49162306a36Sopenharmony_ci "\xf5\xfa\xed\xb0\x1f\xa5\xcd\x3c" 49262306a36Sopenharmony_ci "\x8d\x35\x83\xd4\x11\x44\x6e\x6c" 49362306a36Sopenharmony_ci "\x5b\xe0\x0e\x69\xa5\x39\xe5\xbb" 49462306a36Sopenharmony_ci "\xa9\x57\x24\x37\xe6\x1f\xdd\xcf" 49562306a36Sopenharmony_ci "\x16\x2a\x13\xf9\x6a\x2d\x90\xa0" 49662306a36Sopenharmony_ci "\x03\x60\x7a\xed\x69\xd5\x00\x8b" 49762306a36Sopenharmony_ci "\x7e\x4f\xcb\xb9\xfa\x91\xb9\x37" 49862306a36Sopenharmony_ci "\xc1\x26\xce\x90\x97\x22\x64\x64" 49962306a36Sopenharmony_ci "\xc1\x72\x43\x1b\xf6\xac\xc1\x54" 50062306a36Sopenharmony_ci "\x8a\x10\x9c\xdd\x8d\xd5\x8e\xb2" 50162306a36Sopenharmony_ci "\xe4\x85\xda\xe0\x20\x5f\xf4\xb4" 50262306a36Sopenharmony_ci "\x15\xb5\xa0\x8d\x12\x74\x49\x23" 50362306a36Sopenharmony_ci "\x3a\xdf\x4a\xd3\xf0\x3b\x89\xeb" 50462306a36Sopenharmony_ci "\xf8\xcc\x62\x7b\xfb\x93\x07\x41" 50562306a36Sopenharmony_ci "\x61\x26\x94\x58\x70\xa6\x3c\xe4" 50662306a36Sopenharmony_ci "\xff\x58\xc4\x13\x3d\xcb\x36\x6b" 50762306a36Sopenharmony_ci "\x32\xe5\xb2\x6d\x03\x74\x6f\x76" 50862306a36Sopenharmony_ci "\x93\x77\xde\x48\xc4\xfa\x30\x4a" 50962306a36Sopenharmony_ci "\xda\x49\x80\x77\x0f\x1c\xbe\x11" 51062306a36Sopenharmony_ci "\xc8\x48\xb1\xe5\xbb\xf2\x8a\xe1" 51162306a36Sopenharmony_ci "\x96\x2f\x9f\xd1\x8e\x8a\x5c\xe2" 51262306a36Sopenharmony_ci "\xf7\xd7\xd8\x54\xf3\x3f\xc4\x91" 51362306a36Sopenharmony_ci "\xb8\xfb\x86\xdc\x46\x24\x91\x60" 51462306a36Sopenharmony_ci "\x6c\x2f\xc9\x41\x37\x51\x49\x54" 51562306a36Sopenharmony_ci "\x09\x81\x21\xf3\x03\x9f\x2b\xe3" 51662306a36Sopenharmony_ci "\x1f\x39\x63\xaf\xf4\xd7\x53\x60" 51762306a36Sopenharmony_ci "\xa7\xc7\x54\xf9\xee\xb1\xb1\x7d" 51862306a36Sopenharmony_ci "\x75\x54\x65\x93\xfe\xb1\x68\x6b" 51962306a36Sopenharmony_ci "\x57\x02\xf9\xbb\x0e\xf9\xf8\xbf" 52062306a36Sopenharmony_ci "\x01\x12\x27\xb4\xfe\xe4\x79\x7a" 52162306a36Sopenharmony_ci "\x40\x5b\x51\x4b\xdf\x38\xec\xb1" 52262306a36Sopenharmony_ci "\x6a\x56\xff\x35\x4d\x42\x33\xaa" 52362306a36Sopenharmony_ci "\x6f\x1b\xe4\xdc\xe0\xdb\x85\x35" 52462306a36Sopenharmony_ci "\x62\x10\xd4\xec\xeb\xc5\x7e\x45" 52562306a36Sopenharmony_ci "\x1c\x6f\x17\xca\x3b\x8e\x2d\x66" 52662306a36Sopenharmony_ci "\x4f\x4b\x36\x56\xcd\x1b\x59\xaa" 52762306a36Sopenharmony_ci "\xd2\x9b\x17\xb9\x58\xdf\x7b\x64" 52862306a36Sopenharmony_ci "\x8a\xff\x3b\x9c\xa6\xb5\x48\x9e" 52962306a36Sopenharmony_ci "\xaa\xe2\x5d\x09\x71\x32\x5f\xb6" 53062306a36Sopenharmony_ci "\x29\xbe\xe7\xc7\x52\x7e\x91\x82" 53162306a36Sopenharmony_ci "\x6b\x6d\x33\xe1\x34\x06\x36\x21" 53262306a36Sopenharmony_ci "\x5e\xbe\x1e\x2f\x3e\xc1\xfb\xea" 53362306a36Sopenharmony_ci "\x49\x2c\xb5\xca\xf7\xb0\x37\xea" 53462306a36Sopenharmony_ci "\x1f\xed\x10\x04\xd9\x48\x0d\x1a" 53562306a36Sopenharmony_ci "\x1c\xfb\xe7\x84\x0e\x83\x53\x74" 53662306a36Sopenharmony_ci "\xc7\x65\xe2\x5c\xe5\xba\x73\x4c" 53762306a36Sopenharmony_ci "\x0e\xe1\xb5\x11\x45\x61\x43\x46" 53862306a36Sopenharmony_ci "\xaa\x25\x8f\xbd\x85\x08\xfa\x4c" 53962306a36Sopenharmony_ci "\x15\xc1\xc0\xd8\xf5\xdc\x16\xbb" 54062306a36Sopenharmony_ci "\x7b\x1d\xe3\x87\x57\xa7\x2a\x1d" 54162306a36Sopenharmony_ci "\x38\x58\x9e\x8a\x43\xdc\x57" 54262306a36Sopenharmony_ci "\xd1\x81\x7d\x2b\xe9\xff\x99\x3a" 54362306a36Sopenharmony_ci "\x4b\x24\x52\x58\x55\xe1\x49\x14"; 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_cistatic struct { 54662306a36Sopenharmony_ci const u8 *ptext; 54762306a36Sopenharmony_ci const u8 *ctext; 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ci u8 key[AES_MAX_KEY_SIZE]; 55062306a36Sopenharmony_ci u8 iv[GCM_AES_IV_SIZE]; 55162306a36Sopenharmony_ci u8 assoc[20]; 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci int klen; 55462306a36Sopenharmony_ci int clen; 55562306a36Sopenharmony_ci int plen; 55662306a36Sopenharmony_ci int alen; 55762306a36Sopenharmony_ci} const aesgcm_tv[] __initconst = { 55862306a36Sopenharmony_ci { /* From McGrew & Viega - http://citeseer.ist.psu.edu/656989.html */ 55962306a36Sopenharmony_ci .klen = 16, 56062306a36Sopenharmony_ci .ctext = ctext0, 56162306a36Sopenharmony_ci .clen = sizeof(ctext0), 56262306a36Sopenharmony_ci }, { 56362306a36Sopenharmony_ci .klen = 16, 56462306a36Sopenharmony_ci .ptext = ptext1, 56562306a36Sopenharmony_ci .plen = sizeof(ptext1), 56662306a36Sopenharmony_ci .ctext = ctext1, 56762306a36Sopenharmony_ci .clen = sizeof(ctext1), 56862306a36Sopenharmony_ci }, { 56962306a36Sopenharmony_ci .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 57062306a36Sopenharmony_ci "\x6d\x6a\x8f\x94\x67\x30\x83\x08", 57162306a36Sopenharmony_ci .klen = 16, 57262306a36Sopenharmony_ci .iv = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad" 57362306a36Sopenharmony_ci "\xde\xca\xf8\x88", 57462306a36Sopenharmony_ci .ptext = ptext2, 57562306a36Sopenharmony_ci .plen = sizeof(ptext2), 57662306a36Sopenharmony_ci .ctext = ctext2, 57762306a36Sopenharmony_ci .clen = sizeof(ctext2), 57862306a36Sopenharmony_ci }, { 57962306a36Sopenharmony_ci .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 58062306a36Sopenharmony_ci "\x6d\x6a\x8f\x94\x67\x30\x83\x08", 58162306a36Sopenharmony_ci .klen = 16, 58262306a36Sopenharmony_ci .iv = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad" 58362306a36Sopenharmony_ci "\xde\xca\xf8\x88", 58462306a36Sopenharmony_ci .ptext = ptext3, 58562306a36Sopenharmony_ci .plen = sizeof(ptext3), 58662306a36Sopenharmony_ci .assoc = "\xfe\xed\xfa\xce\xde\xad\xbe\xef" 58762306a36Sopenharmony_ci "\xfe\xed\xfa\xce\xde\xad\xbe\xef" 58862306a36Sopenharmony_ci "\xab\xad\xda\xd2", 58962306a36Sopenharmony_ci .alen = 20, 59062306a36Sopenharmony_ci .ctext = ctext3, 59162306a36Sopenharmony_ci .clen = sizeof(ctext3), 59262306a36Sopenharmony_ci }, { 59362306a36Sopenharmony_ci .klen = 24, 59462306a36Sopenharmony_ci .ctext = ctext4, 59562306a36Sopenharmony_ci .clen = sizeof(ctext4), 59662306a36Sopenharmony_ci }, { 59762306a36Sopenharmony_ci .klen = 24, 59862306a36Sopenharmony_ci .ptext = ptext1, 59962306a36Sopenharmony_ci .plen = sizeof(ptext1), 60062306a36Sopenharmony_ci .ctext = ctext5, 60162306a36Sopenharmony_ci .clen = sizeof(ctext5), 60262306a36Sopenharmony_ci }, { 60362306a36Sopenharmony_ci .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 60462306a36Sopenharmony_ci "\x6d\x6a\x8f\x94\x67\x30\x83\x08" 60562306a36Sopenharmony_ci "\xfe\xff\xe9\x92\x86\x65\x73\x1c", 60662306a36Sopenharmony_ci .klen = 24, 60762306a36Sopenharmony_ci .iv = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad" 60862306a36Sopenharmony_ci "\xde\xca\xf8\x88", 60962306a36Sopenharmony_ci .ptext = ptext6, 61062306a36Sopenharmony_ci .plen = sizeof(ptext6), 61162306a36Sopenharmony_ci .ctext = ctext6, 61262306a36Sopenharmony_ci .clen = sizeof(ctext6), 61362306a36Sopenharmony_ci }, { 61462306a36Sopenharmony_ci .klen = 32, 61562306a36Sopenharmony_ci .ctext = ctext7, 61662306a36Sopenharmony_ci .clen = sizeof(ctext7), 61762306a36Sopenharmony_ci }, { 61862306a36Sopenharmony_ci .klen = 32, 61962306a36Sopenharmony_ci .ptext = ptext1, 62062306a36Sopenharmony_ci .plen = sizeof(ptext1), 62162306a36Sopenharmony_ci .ctext = ctext8, 62262306a36Sopenharmony_ci .clen = sizeof(ctext8), 62362306a36Sopenharmony_ci }, { 62462306a36Sopenharmony_ci .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 62562306a36Sopenharmony_ci "\x6d\x6a\x8f\x94\x67\x30\x83\x08" 62662306a36Sopenharmony_ci "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 62762306a36Sopenharmony_ci "\x6d\x6a\x8f\x94\x67\x30\x83\x08", 62862306a36Sopenharmony_ci .klen = 32, 62962306a36Sopenharmony_ci .iv = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad" 63062306a36Sopenharmony_ci "\xde\xca\xf8\x88", 63162306a36Sopenharmony_ci .ptext = ptext9, 63262306a36Sopenharmony_ci .plen = sizeof(ptext9), 63362306a36Sopenharmony_ci .ctext = ctext9, 63462306a36Sopenharmony_ci .clen = sizeof(ctext9), 63562306a36Sopenharmony_ci }, { 63662306a36Sopenharmony_ci .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 63762306a36Sopenharmony_ci "\x6d\x6a\x8f\x94\x67\x30\x83\x08" 63862306a36Sopenharmony_ci "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 63962306a36Sopenharmony_ci "\x6d\x6a\x8f\x94\x67\x30\x83\x08", 64062306a36Sopenharmony_ci .klen = 32, 64162306a36Sopenharmony_ci .iv = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad" 64262306a36Sopenharmony_ci "\xde\xca\xf8\x88", 64362306a36Sopenharmony_ci .ptext = ptext10, 64462306a36Sopenharmony_ci .plen = sizeof(ptext10), 64562306a36Sopenharmony_ci .assoc = "\xfe\xed\xfa\xce\xde\xad\xbe\xef" 64662306a36Sopenharmony_ci "\xfe\xed\xfa\xce\xde\xad\xbe\xef" 64762306a36Sopenharmony_ci "\xab\xad\xda\xd2", 64862306a36Sopenharmony_ci .alen = 20, 64962306a36Sopenharmony_ci .ctext = ctext10, 65062306a36Sopenharmony_ci .clen = sizeof(ctext10), 65162306a36Sopenharmony_ci }, { 65262306a36Sopenharmony_ci .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 65362306a36Sopenharmony_ci "\x6d\x6a\x8f\x94\x67\x30\x83\x08" 65462306a36Sopenharmony_ci "\xfe\xff\xe9\x92\x86\x65\x73\x1c", 65562306a36Sopenharmony_ci .klen = 24, 65662306a36Sopenharmony_ci .iv = "\xca\xfe\xba\xbe\xfa\xce\xdb\xad" 65762306a36Sopenharmony_ci "\xde\xca\xf8\x88", 65862306a36Sopenharmony_ci .ptext = ptext11, 65962306a36Sopenharmony_ci .plen = sizeof(ptext11), 66062306a36Sopenharmony_ci .assoc = "\xfe\xed\xfa\xce\xde\xad\xbe\xef" 66162306a36Sopenharmony_ci "\xfe\xed\xfa\xce\xde\xad\xbe\xef" 66262306a36Sopenharmony_ci "\xab\xad\xda\xd2", 66362306a36Sopenharmony_ci .alen = 20, 66462306a36Sopenharmony_ci .ctext = ctext11, 66562306a36Sopenharmony_ci .clen = sizeof(ctext11), 66662306a36Sopenharmony_ci }, { 66762306a36Sopenharmony_ci .key = "\x62\x35\xf8\x95\xfc\xa5\xeb\xf6" 66862306a36Sopenharmony_ci "\x0e\x92\x12\x04\xd3\xa1\x3f\x2e" 66962306a36Sopenharmony_ci "\x8b\x32\xcf\xe7\x44\xed\x13\x59" 67062306a36Sopenharmony_ci "\x04\x38\x77\xb0\xb9\xad\xb4\x38", 67162306a36Sopenharmony_ci .klen = 32, 67262306a36Sopenharmony_ci .iv = "\x00\xff\xff\xff\xff\x00\x00\xff" 67362306a36Sopenharmony_ci "\xff\xff\x00\xff", 67462306a36Sopenharmony_ci .ptext = ptext12, 67562306a36Sopenharmony_ci .plen = sizeof(ptext12), 67662306a36Sopenharmony_ci .ctext = ctext12, 67762306a36Sopenharmony_ci .clen = sizeof(ctext12), 67862306a36Sopenharmony_ci } 67962306a36Sopenharmony_ci}; 68062306a36Sopenharmony_ci 68162306a36Sopenharmony_cistatic int __init libaesgcm_init(void) 68262306a36Sopenharmony_ci{ 68362306a36Sopenharmony_ci for (int i = 0; i < ARRAY_SIZE(aesgcm_tv); i++) { 68462306a36Sopenharmony_ci u8 tagbuf[AES_BLOCK_SIZE]; 68562306a36Sopenharmony_ci int plen = aesgcm_tv[i].plen; 68662306a36Sopenharmony_ci struct aesgcm_ctx ctx; 68762306a36Sopenharmony_ci u8 buf[sizeof(ptext12)]; 68862306a36Sopenharmony_ci 68962306a36Sopenharmony_ci if (aesgcm_expandkey(&ctx, aesgcm_tv[i].key, aesgcm_tv[i].klen, 69062306a36Sopenharmony_ci aesgcm_tv[i].clen - plen)) { 69162306a36Sopenharmony_ci pr_err("aesgcm_expandkey() failed on vector %d\n", i); 69262306a36Sopenharmony_ci return -ENODEV; 69362306a36Sopenharmony_ci } 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci if (!aesgcm_decrypt(&ctx, buf, aesgcm_tv[i].ctext, plen, 69662306a36Sopenharmony_ci aesgcm_tv[i].assoc, aesgcm_tv[i].alen, 69762306a36Sopenharmony_ci aesgcm_tv[i].iv, aesgcm_tv[i].ctext + plen) 69862306a36Sopenharmony_ci || memcmp(buf, aesgcm_tv[i].ptext, plen)) { 69962306a36Sopenharmony_ci pr_err("aesgcm_decrypt() #1 failed on vector %d\n", i); 70062306a36Sopenharmony_ci return -ENODEV; 70162306a36Sopenharmony_ci } 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci /* encrypt in place */ 70462306a36Sopenharmony_ci aesgcm_encrypt(&ctx, buf, buf, plen, aesgcm_tv[i].assoc, 70562306a36Sopenharmony_ci aesgcm_tv[i].alen, aesgcm_tv[i].iv, tagbuf); 70662306a36Sopenharmony_ci if (memcmp(buf, aesgcm_tv[i].ctext, plen)) { 70762306a36Sopenharmony_ci pr_err("aesgcm_encrypt() failed on vector %d\n", i); 70862306a36Sopenharmony_ci return -ENODEV; 70962306a36Sopenharmony_ci } 71062306a36Sopenharmony_ci 71162306a36Sopenharmony_ci /* decrypt in place */ 71262306a36Sopenharmony_ci if (!aesgcm_decrypt(&ctx, buf, buf, plen, aesgcm_tv[i].assoc, 71362306a36Sopenharmony_ci aesgcm_tv[i].alen, aesgcm_tv[i].iv, tagbuf) 71462306a36Sopenharmony_ci || memcmp(buf, aesgcm_tv[i].ptext, plen)) { 71562306a36Sopenharmony_ci pr_err("aesgcm_decrypt() #2 failed on vector %d\n", i); 71662306a36Sopenharmony_ci return -ENODEV; 71762306a36Sopenharmony_ci } 71862306a36Sopenharmony_ci } 71962306a36Sopenharmony_ci return 0; 72062306a36Sopenharmony_ci} 72162306a36Sopenharmony_cimodule_init(libaesgcm_init); 72262306a36Sopenharmony_ci 72362306a36Sopenharmony_cistatic void __exit libaesgcm_exit(void) 72462306a36Sopenharmony_ci{ 72562306a36Sopenharmony_ci} 72662306a36Sopenharmony_cimodule_exit(libaesgcm_exit); 72762306a36Sopenharmony_ci#endif 728