Пример #1
0
int cipher_finish( cipher_context_t *ctx, unsigned char *output, size_t *olen)
{
    int ret = 0;

    if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
        return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;

    *olen = 0;

    if( POLARSSL_MODE_CFB == ctx->cipher_info->mode ||
        POLARSSL_MODE_CTR == ctx->cipher_info->mode ||
        POLARSSL_MODE_NULL == ctx->cipher_info->mode )
    {
        return 0;
    }

    if( POLARSSL_MODE_CBC == ctx->cipher_info->mode )
    {
        if( POLARSSL_ENCRYPT == ctx->operation )
        {
            add_pkcs_padding( ctx->unprocessed_data, cipher_get_iv_size( ctx ),
                    ctx->unprocessed_len );
        }
        else if ( cipher_get_block_size( ctx ) != ctx->unprocessed_len )
        {
            /* For decrypt operations, expect a full block */
            return POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED;
        }

        /* cipher block */
        if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
                ctx->operation, cipher_get_block_size( ctx ), ctx->iv,
                ctx->unprocessed_data, output ) ) )
        {
            return ret;
        }

        /* Set output size for decryption */
        if( POLARSSL_DECRYPT == ctx->operation )
            return get_pkcs_padding( output, cipher_get_block_size( ctx ), olen );

        /* Set output size for encryption */
        *olen = cipher_get_block_size( ctx );
        return 0;
    }

    return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
}
Пример #2
0
result_t Cipher::process(const operation_t operation, Buffer_base *data,
                         obj_ptr<Buffer_base> &retVal)
{
    int ret;

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

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

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

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

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

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

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

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

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

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

    return 0;
}
Пример #3
0
int cipher_finish( cipher_context_t *ctx,
                   unsigned char *output, size_t *olen )
{
    if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
        return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );

    *olen = 0;

    if( POLARSSL_MODE_CFB == ctx->cipher_info->mode ||
        POLARSSL_MODE_CTR == ctx->cipher_info->mode ||
        POLARSSL_MODE_GCM == ctx->cipher_info->mode ||
        POLARSSL_MODE_STREAM == ctx->cipher_info->mode )
    {
        return( 0 );
    }

    if( POLARSSL_MODE_ECB == ctx->cipher_info->mode )
    {
        if( ctx->unprocessed_len != 0 )
            return( POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED );

        return( 0 );
    }

#if defined(POLARSSL_CIPHER_MODE_CBC)
    if( POLARSSL_MODE_CBC == ctx->cipher_info->mode )
    {
        int ret = 0;

        if( POLARSSL_ENCRYPT == ctx->operation )
        {
            /* check for 'no padding' mode */
            if( NULL == ctx->add_padding )
            {
                if( 0 != ctx->unprocessed_len )
                    return( POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED );

                return( 0 );
            }

            ctx->add_padding( ctx->unprocessed_data, cipher_get_iv_size( ctx ),
                    ctx->unprocessed_len );
        }
        else if( cipher_get_block_size( ctx ) != ctx->unprocessed_len )
        {
            /*
             * For decrypt operations, expect a full block,
             * or an empty block if no padding
             */
            if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len )
                return( 0 );

            return( POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED );
        }

        /* cipher block */
        if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
                ctx->operation, cipher_get_block_size( ctx ), ctx->iv,
                ctx->unprocessed_data, output ) ) )
        {
            return( ret );
        }

        /* Set output size for decryption */
        if( POLARSSL_DECRYPT == ctx->operation )
            return ctx->get_padding( output, cipher_get_block_size( ctx ),
                                     olen );

        /* Set output size for encryption */
        *olen = cipher_get_block_size( ctx );
        return( 0 );
    }
#else
    ((void) output);
#endif /* POLARSSL_CIPHER_MODE_CBC */

    return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE );
}
Пример #4
0
int cipher_update( cipher_context_t *ctx, const unsigned char *input,
                   size_t ilen, unsigned char *output, size_t *olen )
{
    int ret;

    if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen )
    {
        return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
    }

    *olen = 0;

    if( ctx->cipher_info->mode == POLARSSL_MODE_ECB )
    {
        if( ilen != cipher_get_block_size( ctx ) )
            return( POLARSSL_ERR_CIPHER_FULL_BLOCK_EXPECTED );

        *olen = ilen;

        if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx,
                    ctx->operation, input, output ) ) )
        {
            return( ret );
        }

        return( 0 );
    }

#if defined(POLARSSL_GCM_C)
    if( ctx->cipher_info->mode == POLARSSL_MODE_GCM )
    {
        *olen = ilen;
        return gcm_update( (gcm_context *) ctx->cipher_ctx, ilen, input,
                           output );
    }
#endif

    if( input == output &&
       ( ctx->unprocessed_len != 0 || ilen % cipher_get_block_size( ctx ) ) )
    {
        return( POLARSSL_ERR_CIPHER_BAD_INPUT_DATA );
    }

#if defined(POLARSSL_CIPHER_MODE_CBC)
    if( ctx->cipher_info->mode == POLARSSL_MODE_CBC )
    {
        size_t copy_len = 0;

        /*
         * If there is not enough data for a full block, cache it.
         */
        if( ( ctx->operation == POLARSSL_DECRYPT &&
                ilen <= cipher_get_block_size( ctx ) - ctx->unprocessed_len ) ||
             ( ctx->operation == POLARSSL_ENCRYPT &&
                ilen < cipher_get_block_size( ctx ) - ctx->unprocessed_len ) )
        {
            memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
                    ilen );

            ctx->unprocessed_len += ilen;
            return( 0 );
        }

        /*
         * Process cached data first
         */
        if( ctx->unprocessed_len != 0 )
        {
            copy_len = cipher_get_block_size( ctx ) - ctx->unprocessed_len;

            memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
                    copy_len );

            if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
                    ctx->operation, cipher_get_block_size( ctx ), ctx->iv,
                    ctx->unprocessed_data, output ) ) )
            {
                return( ret );
            }

            *olen += cipher_get_block_size( ctx );
            output += cipher_get_block_size( ctx );
            ctx->unprocessed_len = 0;

            input += copy_len;
            ilen -= copy_len;
        }

        /*
         * Cache final, incomplete block
         */
        if( 0 != ilen )
        {
            copy_len = ilen % cipher_get_block_size( ctx );
            if( copy_len == 0 && ctx->operation == POLARSSL_DECRYPT )
                copy_len = cipher_get_block_size( ctx );

            memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
                    copy_len );

            ctx->unprocessed_len += copy_len;
            ilen -= copy_len;
        }

        /*
         * Process remaining full blocks
         */
        if( ilen )
        {
            if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
                    ctx->operation, ilen, ctx->iv, input, output ) ) )
            {
                return( ret );
            }

            *olen += ilen;
        }

        return( 0 );
    }
#endif /* POLARSSL_CIPHER_MODE_CBC */

#if defined(POLARSSL_CIPHER_MODE_CFB)
    if( ctx->cipher_info->mode == POLARSSL_MODE_CFB )
    {
        if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx,
                ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv,
                input, output ) ) )
        {
            return( ret );
        }

        *olen = ilen;

        return( 0 );
    }
#endif /* POLARSSL_CIPHER_MODE_CFB */

#if defined(POLARSSL_CIPHER_MODE_CTR)
    if( ctx->cipher_info->mode == POLARSSL_MODE_CTR )
    {
        if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx,
                ilen, &ctx->unprocessed_len, ctx->iv,
                ctx->unprocessed_data, input, output ) ) )
        {
            return( ret );
        }

        *olen = ilen;

        return( 0 );
    }
#endif /* POLARSSL_CIPHER_MODE_CTR */

#if defined(POLARSSL_CIPHER_MODE_STREAM)
    if( ctx->cipher_info->mode == POLARSSL_MODE_STREAM )
    {
        if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx,
                                                    ilen, input, output ) ) )
        {
            return( ret );
        }

        *olen = ilen;

        return( 0 );
    }
#endif /* POLARSSL_CIPHER_MODE_STREAM */

    return( POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE );
}
Пример #5
0
int cipher_ctx_block_size(const cipher_context_t *ctx)
{
  return cipher_get_block_size(ctx);
}
Пример #6
0
int cipher_update( cipher_context_t *ctx, const unsigned char *input, size_t ilen,
        unsigned char *output, size_t *olen )
{
    int ret;
    size_t copy_len = 0;

    if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ||
        input == output )
    {
        return POLARSSL_ERR_CIPHER_BAD_INPUT_DATA;
    }

    *olen = 0;

#if defined(POLARSSL_CIPHER_NULL_CIPHER)
    if( ctx->cipher_info->mode == POLARSSL_MODE_NULL )
    {
        memcpy( output, input, ilen );
        *olen = ilen;
        return 0;
    }
#endif /* defined(POLARSSL_CIPHER_NULL_CIPHER) */

    if( ctx->cipher_info->mode == POLARSSL_MODE_CBC )
    {
        /*
         * If there is not enough data for a full block, cache it.
         */
        if( ( ctx->operation == POLARSSL_DECRYPT &&
                ilen + ctx->unprocessed_len <= cipher_get_block_size( ctx ) ) ||
             ( ctx->operation == POLARSSL_ENCRYPT &&
                ilen + ctx->unprocessed_len < cipher_get_block_size( ctx ) ) )
        {
            memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
                    ilen );

            ctx->unprocessed_len += ilen;
            return 0;
        }

        /*
         * Process cached data first
         */
        if( ctx->unprocessed_len != 0 )
        {
            copy_len = cipher_get_block_size( ctx ) - ctx->unprocessed_len;

            memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
                    copy_len );

            if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
                    ctx->operation, cipher_get_block_size( ctx ), ctx->iv,
                    ctx->unprocessed_data, output ) ) )
            {
                return ret;
            }

            *olen += cipher_get_block_size( ctx );
            output += cipher_get_block_size( ctx );
            ctx->unprocessed_len = 0;

            input += copy_len;
            ilen -= copy_len;
        }

        /*
         * Cache final, incomplete block
         */
        if( 0 != ilen )
        {
            copy_len = ilen % cipher_get_block_size( ctx );
            if( copy_len == 0 && ctx->operation == POLARSSL_DECRYPT )
                copy_len = cipher_get_block_size(ctx);

            memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ),
                    copy_len );

            ctx->unprocessed_len += copy_len;
            ilen -= copy_len;
        }

        /*
         * Process remaining full blocks
         */
        if( ilen )
        {
            if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx,
                    ctx->operation, ilen, ctx->iv, input, output ) ) )
            {
                return ret;
            }
            *olen += ilen;
        }

        return 0;
    }

    if( ctx->cipher_info->mode == POLARSSL_MODE_CFB )
    {
        if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx,
                ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv,
                input, output ) ) )
        {
            return ret;
        }

        *olen = ilen;

        return 0;
    }

    if( ctx->cipher_info->mode == POLARSSL_MODE_CTR )
    {
        if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx,
                ilen, &ctx->unprocessed_len, ctx->iv,
                ctx->unprocessed_data, input, output ) ) )
        {
            return ret;
        }

        *olen = ilen;

        return 0;
    }

    return POLARSSL_ERR_CIPHER_FEATURE_UNAVAILABLE;
}
Пример #7
0
result_t Cipher::get_blockSize(int32_t &retVal)
{
    retVal = cipher_get_block_size(&m_ctx);
    return 0;
}