NS_INTERNAL void *kr_cipher_setup(kr_cs_id cs, int decrypt, const uint8_t *key, const uint8_t *iv) { switch (cs) { #if ALLOW_NULL_CIPHERS case TLS_RSA_WITH_NULL_MD5: return NULL; #endif case TLS_RSA_WITH_RC4_128_MD5: case TLS_RSA_WITH_RC4_128_SHA: { kr_rc4_ctx *ctx = kr_rc4_ctx_new(); kr_rc4_setup(ctx, key, RC4_KEY_SIZE); return ctx; } case TLS_RSA_WITH_AES_128_CBC_SHA: case TLS_RSA_WITH_AES_128_CBC_SHA256: { AES_CTX *ctx = kr_aes_ctx_new(); AES_set_key(ctx, key, iv, AES_MODE_128); if (decrypt) AES_convert_key(ctx); return ctx; } } dprintf(("unsupported cipher suite: %d\n", cs)); abort(); return NULL; }
/** * Decrypt data * * @v ctx Context * @v src Data to decrypt * @v dst Buffer for decrypted data * @v len Length of data */ static void aes_decrypt ( void *ctx, const void *src, void *dst, size_t len ) { struct aes_context *aes_ctx = ctx; assert ( len == AES_BLOCKSIZE ); if ( ! aes_ctx->decrypting ) { AES_convert_key ( &aes_ctx->axtls_ctx ); aes_ctx->decrypting = 1; } aes_call_axtls ( &aes_ctx->axtls_ctx, src, dst, AES_decrypt ); }
/** * we are running the algoritm backwards to eliminate the need to remember too much state. */ bool aes128_cbc_decrypt(const uint8_t* key, uint8_t* input, uint16_t input_len) { if (input_len < 16) return false; // the input contains at most the iv. if ((input_len % 16) != 0) return false; // the input_len should be a multiple of the block size. { AES_set_key(&ctx, key, input, AES_MODE_128); input += 16; // iv input_len -= 16; AES_convert_key(&ctx); AES_cbc_decrypt(&ctx, input, input, (int)input_len); } return true; }
static void decrypt_payload(void *payload, size_t len, uint8_t encryptkey[16], uint8_t IV[16]){ AES_CTX ctx; int pad = (16 - len%16)% 16; /* blocks must be 16 bytes padded */ len += pad; #ifdef CRYPTO_DEBUG myprintf("Aes_decrypt (%x %d) = ", *(uint32_t *)payload, len); #endif AES_set_key(&ctx, encryptkey, IV, AES_MODE_128); AES_convert_key(&ctx); /* do the encryption in-place to spare memory */ AES_cbc_decrypt(&ctx, payload, payload, len); #ifdef CRYPTO_DEBUG myprintf("%x\n", *(uint32_t *)payload); #endif ZERO(ctx); }
/** * Take a base64 blob of data and decrypt it (using AES) into its * proper ASN.1 form. */ static int pem_decrypt(const char *where, const char *end, const char *password, SSLObjLoader *ssl_obj) { int ret = -1; int is_aes_256 = 0; char *start = NULL; uint8_t iv[IV_SIZE]; int i, pem_size; MD5_CTX md5_ctx; AES_CTX aes_ctx; uint8_t key[32]; /* AES256 size */ if (password == NULL || strlen(password) == 0) { #ifdef CONFIG_SSL_FULL_MODE printf("Error: Need a password for this PEM file\n"); TTY_FLUSH(); #endif goto error; } if ((start = strstr((const char *)where, aes_str[0]))) { /* AES128? */ start += strlen(aes_str[0]); } else if ((start = strstr((const char *)where, aes_str[1]))) { /* AES256? */ is_aes_256 = 1; start += strlen(aes_str[1]); } else { #ifdef CONFIG_SSL_FULL_MODE printf("Error: Unsupported password cipher\n"); TTY_FLUSH(); #endif goto error; } /* convert from hex to binary - assumes uppercase hex */ for (i = 0; i < IV_SIZE; i++) { char c = *start++ - '0'; iv[i] = (c > 9 ? c + '0' - 'A' + 10 : c) << 4; c = *start++ - '0'; iv[i] += (c > 9 ? c + '0' - 'A' + 10 : c); } while (*start == '\r' || *start == '\n') start++; /* turn base64 into binary */ pem_size = (int)(end - start); if (base64_decode(start, pem_size, ssl_obj->buf, &ssl_obj->len) != 0) goto error; /* work out the key */ MD5_Init(&md5_ctx); MD5_Update(&md5_ctx, (const uint8_t *)password, strlen(password)); MD5_Update(&md5_ctx, iv, SALT_SIZE); MD5_Final(key, &md5_ctx); if (is_aes_256) { MD5_Init(&md5_ctx); MD5_Update(&md5_ctx, key, MD5_SIZE); MD5_Update(&md5_ctx, (const uint8_t *)password, strlen(password)); MD5_Update(&md5_ctx, iv, SALT_SIZE); MD5_Final(&key[MD5_SIZE], &md5_ctx); } /* decrypt using the key/iv */ AES_set_key(&aes_ctx, key, iv, is_aes_256 ? AES_MODE_256 : AES_MODE_128); AES_convert_key(&aes_ctx); AES_cbc_decrypt(&aes_ctx, ssl_obj->buf, ssl_obj->buf, ssl_obj->len); ret = 0; error: return ret; }
static int AES_test(BI_CTX *bi_ctx) { AES_CTX aes_key; int res = 1; uint8_t key[TEST1_SIZE]; uint8_t iv[TEST1_SIZE]; { /* Case #1: Encrypting 16 bytes (1 block) using AES-CBC Key : 0x06a9214036b8a15b512e03d534120006 IV : 0x3dafba429d9eb430b422da802c9fac41 Plaintext : "Single block msg" Ciphertext: 0xe353779c1079aeb82708942dbe77181a */ char *in_str = "Single block msg"; uint8_t ct[TEST1_SIZE]; uint8_t enc_data[TEST1_SIZE]; uint8_t dec_data[TEST1_SIZE]; bigint *key_bi = bi_str_import( bi_ctx, "06A9214036B8A15B512E03D534120006"); bigint *iv_bi = bi_str_import( bi_ctx, "3DAFBA429D9EB430B422DA802C9FAC41"); bigint *ct_bi = bi_str_import( bi_ctx, "E353779C1079AEB82708942DBE77181A"); bi_export(bi_ctx, key_bi, key, TEST1_SIZE); bi_export(bi_ctx, iv_bi, iv, TEST1_SIZE); bi_export(bi_ctx, ct_bi, ct, TEST1_SIZE); AES_set_key(&aes_key, key, iv, AES_MODE_128); AES_cbc_encrypt(&aes_key, (const uint8_t *)in_str, enc_data, sizeof(enc_data)); if (memcmp(enc_data, ct, sizeof(ct))) { printf("Error: AES ENCRYPT #1 failed\n"); goto end; } AES_set_key(&aes_key, key, iv, AES_MODE_128); AES_convert_key(&aes_key); AES_cbc_decrypt(&aes_key, enc_data, dec_data, sizeof(enc_data)); if (memcmp(dec_data, in_str, sizeof(dec_data))) { printf("Error: AES DECRYPT #1 failed\n"); goto end; } } { /* Case #2: Encrypting 32 bytes (2 blocks) using AES-CBC Key : 0xc286696d887c9aa0611bbb3e2025a45a IV : 0x562e17996d093d28ddb3ba695a2e6f58 Plaintext : 0x000102030405060708090a0b0c0d0e0f 101112131415161718191a1b1c1d1e1f Ciphertext: 0xd296cd94c2cccf8a3a863028b5e1dc0a 7586602d253cfff91b8266bea6d61ab1 */ uint8_t in_data[TEST2_SIZE]; uint8_t ct[TEST2_SIZE]; uint8_t enc_data[TEST2_SIZE]; uint8_t dec_data[TEST2_SIZE]; bigint *in_bi = bi_str_import(bi_ctx, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"); bigint *key_bi = bi_str_import( bi_ctx, "C286696D887C9AA0611BBB3E2025A45A"); bigint *iv_bi = bi_str_import( bi_ctx, "562E17996D093D28DDB3BA695A2E6F58"); bigint *ct_bi = bi_str_import(bi_ctx, "D296CD94C2CCCF8A3A863028B5E1DC0A7586602D253CFFF91B8266BEA6D61AB1"); bi_export(bi_ctx, in_bi, in_data, TEST2_SIZE); bi_export(bi_ctx, key_bi, key, TEST1_SIZE); bi_export(bi_ctx, iv_bi, iv, TEST1_SIZE); bi_export(bi_ctx, ct_bi, ct, TEST2_SIZE); AES_set_key(&aes_key, key, iv, AES_MODE_128); AES_cbc_encrypt(&aes_key, (const uint8_t *)in_data, enc_data, sizeof(enc_data)); if (memcmp(enc_data, ct, sizeof(ct))) { printf("Error: ENCRYPT #2 failed\n"); goto end; } AES_set_key(&aes_key, key, iv, AES_MODE_128); AES_convert_key(&aes_key); AES_cbc_decrypt(&aes_key, enc_data, dec_data, sizeof(enc_data)); if (memcmp(dec_data, in_data, sizeof(dec_data))) { printf("Error: DECRYPT #2 failed\n"); goto end; } } res = 0; printf("All AES tests passed\n"); end: return res; }