static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, unsigned char *nonce_counter, unsigned char *stream_block, const unsigned char *input, unsigned char *output ) { return mbedtls_aes_crypt_ctr( (mbedtls_aes_context *) ctx, length, nc_off, nonce_counter, stream_block, input, output ); }
int eddy_aes_authcrypt_eax( mbedtls_aes_context *ctx, int mode, const unsigned char *nonce, size_t nonce_length, const unsigned char *header, size_t header_length, size_t message_length, const unsigned char *input, unsigned char *output, unsigned char *tag, size_t tag_length ) { unsigned char header_mac[16]; unsigned char nonce_mac[16]; unsigned char ciphertext_mac[16]; uint8_t i; compute_cmac_(ctx, header, header_length, 1, header_mac); compute_cmac_(ctx, nonce, nonce_length, 0, nonce_mac); if (mode == MBEDTLS_AES_DECRYPT) { compute_cmac_(ctx, input, message_length, 2, ciphertext_mac); unsigned char n_ok = 0; for (i = 0; i < tag_length; i++) { ciphertext_mac[i] ^= header_mac[i]; ciphertext_mac[i] ^= nonce_mac[i]; ciphertext_mac[i] ^= tag[i]; n_ok |= ciphertext_mac[i]; } if (n_ok) return EDDY_ERR_EAX_AUTH_FAILED; } size_t nc_off = 0; unsigned char nonce_copy[16]; memcpy(nonce_copy, nonce_mac, sizeof(nonce_mac)); unsigned char sb[16]; mbedtls_aes_crypt_ctr(ctx, message_length, &nc_off, nonce_copy, sb, input, output); if (mode == MBEDTLS_AES_ENCRYPT) { compute_cmac_(ctx, output, message_length, 2, ciphertext_mac); for (i = 0; i < tag_length; i++) tag[i] = header_mac[i] ^ nonce_mac[i] ^ ciphertext_mac[i]; } return 0; }
int AESContext::cryptCTR(State & state, mbedtls_aes_context * context){ Stack * stack = state.stack; if (stack->is<LUA_TNUMBER>(1) && stack->is<LUA_TSTRING>(2) && stack->is<LUA_TSTRING>(3)){ std::string nonceStr = stack->toLString(2); std::string input = stack->toLString(3); int length = input.length(); if (((length % 16) == 0) && (nonceStr.length() == 16)){ size_t ncOff = stack->to<int>(1);; unsigned char nonceCounter[16]; unsigned char streamBlock[16]; unsigned char * output = new unsigned char[length]; memcpy(nonceCounter, nonceStr.c_str(), 16); int result = mbedtls_aes_crypt_ctr(context, length, &ncOff, nonceCounter, streamBlock, reinterpret_cast<const unsigned char *>(input.c_str()), output); if (result == 0){ stack->push<int>(ncOff); stack->pushLString(std::string(reinterpret_cast<char*>(nonceCounter), 16)); stack->pushLString(std::string(reinterpret_cast<char*>(streamBlock), 16)); stack->pushLString(std::string(reinterpret_cast<char*>(output), length)); delete[] output; return 4; } else{ stack->push<int>(result); delete[] output; return 1; } } else{ stack->push<bool>(false); return 1; } } return 0; }
static NO_INLINE JsVar *jswrap_crypto_AEScrypt(JsVar *message, JsVar *key, JsVar *options, bool encrypt) { int err; unsigned char iv[16]; // initialisation vector memset(iv, 0, 16); CryptoMode mode = CM_CBC; if (jsvIsObject(options)) { JsVar *ivVar = jsvObjectGetChild(options, "iv", 0); if (ivVar) { jsvIterateCallbackToBytes(ivVar, iv, sizeof(iv)); jsvUnLock(ivVar); } JsVar *modeVar = jsvObjectGetChild(options, "mode", 0); if (!jsvIsUndefined(modeVar)) mode = jswrap_crypto_getMode(modeVar); jsvUnLock(modeVar); if (mode == CM_NONE) return 0; } else if (!jsvIsUndefined(options)) { jsError("'options' must be undefined, or an Object"); return 0; } mbedtls_aes_context aes; mbedtls_aes_init( &aes ); JSV_GET_AS_CHAR_ARRAY(messagePtr, messageLen, message); if (!messagePtr) return 0; JSV_GET_AS_CHAR_ARRAY(keyPtr, keyLen, key); if (!keyPtr) return 0; if (encrypt) err = mbedtls_aes_setkey_enc( &aes, (unsigned char*)keyPtr, (unsigned int)keyLen*8 ); else err = mbedtls_aes_setkey_dec( &aes, (unsigned char*)keyPtr, (unsigned int)keyLen*8 ); if (err) { jswrap_crypto_error(err); return 0; } char *outPtr = 0; JsVar *outVar = jsvNewArrayBufferWithPtr((unsigned int)messageLen, &outPtr); if (!outPtr) { jsError("Not enough memory for result"); return 0; } switch (mode) { case CM_CBC: err = mbedtls_aes_crypt_cbc( &aes, encrypt ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT, messageLen, iv, (unsigned char*)messagePtr, (unsigned char*)outPtr ); break; case CM_CFB: err = mbedtls_aes_crypt_cfb8( &aes, encrypt ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT, messageLen, iv, (unsigned char*)messagePtr, (unsigned char*)outPtr ); break; case CM_CTR: { size_t nc_off = 0; unsigned char nonce_counter[16]; unsigned char stream_block[16]; memset(nonce_counter, 0, sizeof(nonce_counter)); memset(stream_block, 0, sizeof(stream_block)); err = mbedtls_aes_crypt_ctr( &aes, messageLen, &nc_off, nonce_counter, stream_block, (unsigned char*)messagePtr, (unsigned char*)outPtr ); break; } case CM_ECB: { size_t i = 0; while (!err && i+15 < messageLen) { err = mbedtls_aes_crypt_ecb( &aes, encrypt ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT, (unsigned char*)&messagePtr[i], (unsigned char*)&outPtr[i] ); i += 16; } break; } default: err = MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE; break; } mbedtls_aes_free( &aes ); if (!err) { return outVar; } else { jswrap_crypto_error(err); jsvUnLock(outVar); return 0; } }