예제 #1
0
static void cipher_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
        unsigned long len)
{
    size_t outlen = 0;
    size_t total_len = 0;
    int rc = 0;
    rc = mbedtls_cipher_update(&cipher->encrypt_ctx, in, len, out, &outlen);
    if (rc != 0) {
        SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_update failed during encryption");
        return;
    }

    total_len += outlen;

    if (total_len == len) {
        return;
    }

    rc = mbedtls_cipher_finish(&cipher->encrypt_ctx, (unsigned char *) out + outlen,
            &outlen);

    total_len += outlen;

    if (rc != 0) {
        SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_finish failed during encryption");
        return;
    }

    if (total_len != len) {
        SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_update: output size %zu for %zu",
                outlen, len);
        return;
    }

}
예제 #2
0
static void cipher_decrypt_cbc(struct ssh_cipher_struct *cipher, void *in, void *out,
        unsigned long len)
{
    size_t outlen = 0;
    int rc = 0;
    rc = mbedtls_cipher_update(&cipher->decrypt_ctx, in, len, out, &outlen);
    if (rc != 0) {
        SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_update failed during decryption");
        return;
    }

    /* MbedTLS caches the last block when decrypting with cbc.
     * By calling finish the block is flushed to out, however the unprocessed
     * data counter is not reset.
     * Calling mbedtls_cipher_reset resets the unprocessed data counter.
     */
    if (outlen == 0) {
        rc = mbedtls_cipher_finish(&cipher->decrypt_ctx, out, &outlen);
    } else if (outlen == len) {
        return;
    } else {
        rc = mbedtls_cipher_finish(&cipher->decrypt_ctx, (unsigned char *) out +
                outlen , &outlen);
    }

    if (rc != 0) {
        SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_finish failed during decryption");
        return;
    }

    rc = mbedtls_cipher_reset(&cipher->decrypt_ctx);

    if (rc != 0) {
        SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_reset failed during decryption");
        return;
    }

    if (outlen != len) {
        SSH_LOG(SSH_LOG_WARNING, "mbedtls_cipher_update: output size %zu for %zu",
                outlen, len);
        return;
    }

}
예제 #3
0
파일: Cipher.cpp 프로젝트: asionius92/fibjs
result_t Cipher::process(const mbedtls_operation_t operation, Buffer_base *data,
                         obj_ptr<Buffer_base> &retVal)
{
    int32_t ret;

    ret = mbedtls_cipher_setkey(&m_ctx, (unsigned char *)m_key.c_str(), (int32_t)m_key.length() * 8,
                                operation);
    if (ret != 0)
        return CHECK_ERROR(_ssl::setError(ret));

    ret = mbedtls_cipher_reset(&m_ctx);
    if (ret != 0)
        return CHECK_ERROR(_ssl::setError(ret));

    exlib::string input;
    exlib::string output;
    unsigned char buffer[1024];
    size_t olen, ilen, offset, block_size, data_size;

    data->toString(input);
    block_size = mbedtls_cipher_get_block_size(&m_ctx);
    data_size = input.length();

    for (offset = 0; offset < data_size; offset += block_size)
    {
        ilen = ((uint32_t)data_size - offset > block_size) ?
               block_size : (uint32_t)(data_size - offset);

        ret = mbedtls_cipher_update(&m_ctx, (unsigned char *)input.c_str() + offset,
                                    ilen, buffer, &olen);
        if (ret != 0)
        {
            reset();
            return CHECK_ERROR(_ssl::setError(ret));
        }

        output.append((const char *)buffer, olen);
    }

    ret = mbedtls_cipher_finish(&m_ctx, buffer, &olen);
    reset();

    if (ret != 0)
        return CHECK_ERROR(_ssl::setError(ret));

    output.append((const char *)buffer, olen);
    retVal = new Buffer(output);

    return 0;
}
예제 #4
0
int
cipher_ctx_final(mbedtls_cipher_context_t *ctx, uint8_t *dst, int *dst_len)
{
    size_t s_dst_len = *dst_len;

    if (!mbed_ok(mbedtls_cipher_finish(ctx, dst, &s_dst_len)))
    {
        return 0;
    }

    *dst_len = s_dst_len;

    return 1;
}
예제 #5
0
	int CipherContext::finish(State & state, mbedtls_cipher_context_t * context){
		Stack * stack = state.stack;
		if (stack->is<LUA_TNUMBER>(1)){
			size_t outputSize = stack->to<int>(1);
			unsigned char * output = new unsigned char[outputSize];

			int result = mbedtls_cipher_finish(context,	output, &outputSize);
			if (result == 0){
				stack->pushLString(std::string(reinterpret_cast<char*>(output), outputSize));
			}
			else{
				stack->push<int>(result);
			}
			return 1;
		}
		return 0;
	}
예제 #6
0
int
cipher_ctx_final_check_tag(mbedtls_cipher_context_t *ctx, uint8_t *dst,
                           int *dst_len, uint8_t *tag, size_t tag_len)
{
#ifdef HAVE_AEAD_CIPHER_MODES
    size_t olen = 0;

    if (MBEDTLS_DECRYPT != ctx->operation)
    {
        return 0;
    }

    if (tag_len > SIZE_MAX)
    {
        return 0;
    }

    if (!mbed_ok(mbedtls_cipher_finish(ctx, dst, &olen)))
    {
        msg(D_CRYPT_ERRORS, "%s: cipher_ctx_final() failed", __func__);
        return 0;
    }

    if (olen > INT_MAX)
    {
        return 0;
    }
    *dst_len = olen;

    if (!mbed_ok(mbedtls_cipher_check_tag(ctx, (const unsigned char *) tag,
                                          tag_len)))
    {
        return 0;
    }

    return 1;
#else  /* ifdef HAVE_AEAD_CIPHER_MODES */
    ASSERT(0);
#endif /* HAVE_AEAD_CIPHER_MODES */
}
예제 #7
0
/*
 * Packet-oriented wrapper for non-AEAD modes
 */
int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx,
                          const unsigned char *iv, size_t iv_len,
                          const unsigned char *input, size_t ilen,
                          unsigned char *output, size_t *olen )
{
    int ret;
    size_t finish_olen;

    if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
        return( ret );

    if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 )
        return( ret );

    if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 )
        return( ret );

    if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 )
        return( ret );

    *olen += finish_olen;

    return( 0 );
}