Exemple #1
0
static int cipher_ctrl(EVP_CIPHER_CTX *ctx, int type, int p1, void* p2)
{
    struct cipher_ctx *cipher_ctx =
        (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
    EVP_CIPHER_CTX *to_ctx = (EVP_CIPHER_CTX *)p2;
    struct cipher_ctx *to_cipher_ctx;

    switch (type) {

    case EVP_CTRL_COPY:
        if (cipher_ctx == NULL)
            return 1;
        /* when copying the context, a new session needs to be initialized */
        to_cipher_ctx =
            (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(to_ctx);
        memset(&to_cipher_ctx->sess, 0, sizeof(to_cipher_ctx->sess));
        return cipher_init(to_ctx, cipher_ctx->sess.key, EVP_CIPHER_CTX_iv(ctx),
                           (cipher_ctx->op == COP_ENCRYPT));

    case EVP_CTRL_INIT:
        memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess));
        return 1;

    default:
        break;
    }

    return -1;
}
Exemple #2
0
static int dasync_cipher_init_key_helper(EVP_CIPHER_CTX *ctx,
                                         const unsigned char *key,
                                         const unsigned char *iv, int enc,
                                         const EVP_CIPHER *cipher)
{
    int ret;
    struct dasync_pipeline_ctx *pipe_ctx =
        (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);

    if (pipe_ctx->inner_cipher_data == NULL
            && EVP_CIPHER_impl_ctx_size(cipher) != 0) {
        pipe_ctx->inner_cipher_data = OPENSSL_zalloc(
            EVP_CIPHER_impl_ctx_size(cipher));
        if (pipe_ctx->inner_cipher_data == NULL) {
            DASYNCerr(DASYNC_F_DASYNC_CIPHER_INIT_KEY_HELPER,
                        ERR_R_MALLOC_FAILURE);
            return 0;
        }
    }

    pipe_ctx->numpipes = 0;
    pipe_ctx->aadctr = 0;

    EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data);
    ret = EVP_CIPHER_meth_get_init(cipher)(ctx, key, iv, enc);
    EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx);

    return ret;
}
Exemple #3
0
static int afalg_cipher_cleanup(EVP_CIPHER_CTX *ctx)
{
    afalg_ctx *actx;

    if (ctx == NULL) {
        ALG_WARN("NULL parameter passed to function %s\n", __func__);
        return 0;
    }

    actx = (afalg_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
    if (actx == NULL || actx->init_done != MAGIC_INIT_NUM) {
        ALG_WARN("%s afalg ctx passed\n",
                 ctx == NULL ? "NULL" : "Uninitialised");
        return 0;
    }

    close(actx->sfd);
    close(actx->bfd);
# ifdef ALG_ZERO_COPY
    close(actx->zc_pipe[0]);
    close(actx->zc_pipe[1]);
# endif
    /* close efd in sync mode, async mode is closed in afalg_waitfd_cleanup() */
    if (actx->aio.mode == MODE_SYNC)
        close(actx->aio.efd);
    io_destroy(actx->aio.aio_ctx);

    return 1;
}
Exemple #4
0
static int cipher_cleanup(EVP_CIPHER_CTX *ctx)
{
    struct cipher_ctx *cipher_ctx =
        (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);

    return clean_devcrypto_session(&cipher_ctx->sess);
}
Exemple #5
0
static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                       const unsigned char *iv, int enc)
{
    struct cipher_ctx *cipher_ctx =
        (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
    const struct cipher_data_st *cipher_d =
        get_cipher_data(EVP_CIPHER_CTX_nid(ctx));

    /* cleanup a previous session */
    if (cipher_ctx->sess.ses != 0 &&
        clean_devcrypto_session(&cipher_ctx->sess) == 0)
        return 0;

    cipher_ctx->sess.cipher = cipher_d->devcryptoid;
    cipher_ctx->sess.keylen = cipher_d->keylen;
    cipher_ctx->sess.key = (void *)key;
    cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT;
    cipher_ctx->mode = cipher_d->flags & EVP_CIPH_MODE;
    cipher_ctx->blocksize = cipher_d->blocksize;
    if (ioctl(cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) {
        SYSerr(SYS_F_IOCTL, errno);
        return 0;
    }

    return 1;
}
Exemple #6
0
static int cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                       const unsigned char *iv, int enc)
{
    struct cipher_ctx *cipher_ctx =
        (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
    const struct cipher_data_st *cipher_d =
        get_cipher_data(EVP_CIPHER_CTX_nid(ctx));

    if ((cipher_ctx->cfd = open("/dev/crypto", O_RDWR, 0)) < 0) {
        SYSerr(SYS_F_OPEN, errno);
        return 0;
    }

    memset(&cipher_ctx->sess, 0, sizeof(cipher_ctx->sess));
    cipher_ctx->sess.cipher = cipher_d->devcryptoid;
    cipher_ctx->sess.keylen = cipher_d->keylen;
    cipher_ctx->sess.key = (void *)key;
    cipher_ctx->op = enc ? COP_ENCRYPT : COP_DECRYPT;
    if (ioctl(cipher_ctx->cfd, CIOCGSESSION, &cipher_ctx->sess) < 0) {
        SYSerr(SYS_F_IOCTL, errno);
        close(cipher_ctx->cfd);
        return 0;
    }

    return 1;
}
Exemple #7
0
/* The subkey for ARIA is generated. */
static int aria_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                            const unsigned char *iv, int enc)
{
    int ret;
    int mode = EVP_CIPHER_CTX_mode(ctx);

    if (enc || (mode != EVP_CIPH_ECB_MODE && mode != EVP_CIPH_CBC_MODE))
        ret = aria_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
                                        EVP_CIPHER_CTX_get_cipher_data(ctx));
    else
        ret = aria_set_decrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
                                        EVP_CIPHER_CTX_get_cipher_data(ctx));
    if (ret < 0) {
        EVPerr(EVP_F_ARIA_INIT_KEY,EVP_R_ARIA_KEY_SETUP_FAILED);
        return 0;
    }
    return 1;
}
Exemple #8
0
static int dasync_cipher_cleanup_helper(EVP_CIPHER_CTX *ctx,
                                        const EVP_CIPHER *cipher)
{
    struct dasync_pipeline_ctx *pipe_ctx =
        (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);

    OPENSSL_clear_free(pipe_ctx->inner_cipher_data,
                       EVP_CIPHER_impl_ctx_size(cipher));

    return 1;
}
Exemple #9
0
static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                            const unsigned char *in, size_t inl)
{
    struct cipher_ctx *cipher_ctx =
        (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
    struct crypt_op cryp;
#if !defined(COP_FLAG_WRITE_IV)
    unsigned char saved_iv[EVP_MAX_IV_LENGTH];
#endif

    memset(&cryp, 0, sizeof(cryp));
    cryp.ses = cipher_ctx->sess.ses;
    cryp.len = inl;
    cryp.src = (void *)in;
    cryp.dst = (void *)out;
    cryp.iv = (void *)EVP_CIPHER_CTX_iv_noconst(ctx);
    cryp.op = cipher_ctx->op;
#if !defined(COP_FLAG_WRITE_IV)
    cryp.flags = 0;

    if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
        assert(inl >= EVP_CIPHER_CTX_iv_length(ctx));
        if (!EVP_CIPHER_CTX_encrypting(ctx)) {
            unsigned char *ivptr = in + inl - EVP_CIPHER_CTX_iv_length(ctx);

            memcpy(saved_iv, ivptr, EVP_CIPHER_CTX_iv_length(ctx));
        }
    }
#else
    cryp.flags = COP_FLAG_WRITE_IV;
#endif

    if (ioctl(cipher_ctx->cfd, CIOCCRYPT, &cryp) < 0) {
        SYSerr(SYS_F_IOCTL, errno);
        return 0;
    }

#if !defined(COP_FLAG_WRITE_IV)
    if (EVP_CIPHER_CTX_iv_length(ctx) > 0) {
        unsigned char *ivptr = saved_iv;

        assert(inl >= EVP_CIPHER_CTX_iv_length(ctx));
        if (!EVP_CIPHER_CTX_encrypting(ctx))
            ivptr = out + inl - EVP_CIPHER_CTX_iv_length(ctx);

        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), ivptr,
               EVP_CIPHER_CTX_iv_length(ctx));
    }
#endif

    return 1;
}
Exemple #10
0
static int afalg_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                           const unsigned char *in, size_t inl)
{
    afalg_ctx *actx;
    int ret;
    char nxtiv[ALG_AES_IV_LEN] = { 0 };

    if (ctx == NULL || out == NULL || in == NULL) {
        ALG_WARN("NULL parameter passed to function %s(%d)\n", __FILE__,
                 __LINE__);
        return 0;
    }

    actx = (afalg_ctx *) EVP_CIPHER_CTX_get_cipher_data(ctx);
    if (actx == NULL || actx->init_done != MAGIC_INIT_NUM) {
        ALG_WARN("%s afalg ctx passed\n",
                 ctx == NULL ? "NULL" : "Uninitialised");
        return 0;
    }

    /*
     * set iv now for decrypt operation as the input buffer can be
     * overwritten for inplace operation where in = out.
     */
    if (EVP_CIPHER_CTX_encrypting(ctx) == 0) {
        memcpy(nxtiv, in + (inl - ALG_AES_IV_LEN), ALG_AES_IV_LEN);
    }

    /* Send input data to kernel space */
    ret = afalg_start_cipher_sk(actx, (unsigned char *)in, inl,
                                EVP_CIPHER_CTX_iv(ctx),
                                EVP_CIPHER_CTX_encrypting(ctx));
    if (ret < 1) {
        return 0;
    }

    /* Perform async crypto operation in kernel space */
    ret = afalg_fin_cipher_aio(&actx->aio, actx->sfd, out, inl);
    if (ret < 1)
        return 0;

    if (EVP_CIPHER_CTX_encrypting(ctx)) {
        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), out + (inl - ALG_AES_IV_LEN),
               ALG_AES_IV_LEN);
    } else {
        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), nxtiv, ALG_AES_IV_LEN);
    }

    return 1;
}
Exemple #11
0
static int cipher_cleanup(EVP_CIPHER_CTX *ctx)
{
    struct cipher_ctx *cipher_ctx =
        (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);

    if (ioctl(cipher_ctx->cfd, CIOCFSESSION, &cipher_ctx->sess) < 0) {
        SYSerr(SYS_F_IOCTL, errno);
        return 0;
    }
    if (close(cipher_ctx->cfd) < 0) {
        SYSerr(SYS_F_CLOSE, errno);
        return 0;
    }

    return 1;
}
Exemple #12
0
static int dasync_cipher_helper(EVP_CIPHER_CTX *ctx, unsigned char *out,
                                const unsigned char *in, size_t inl,
                                const EVP_CIPHER *cipher)
{
    int ret = 1;
    unsigned int i, pipes;
    struct dasync_pipeline_ctx *pipe_ctx =
        (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);

    pipes = pipe_ctx->numpipes;
    EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data);
    if (pipes == 0) {
        if (pipe_ctx->aadctr != 0) {
            if (pipe_ctx->aadctr != 1)
                return -1;
            EVP_CIPHER_meth_get_ctrl(cipher)
                                    (ctx, EVP_CTRL_AEAD_TLS1_AAD,
                                     EVP_AEAD_TLS1_AAD_LEN,
                                     pipe_ctx->tlsaad[0]);
        }
        ret = EVP_CIPHER_meth_get_do_cipher(cipher)
                                           (ctx, out, in, inl);
    } else {
        if (pipe_ctx->aadctr > 0 && pipe_ctx->aadctr != pipes)
            return -1;
        for (i = 0; i < pipes; i++) {
            if (pipe_ctx->aadctr > 0) {
                EVP_CIPHER_meth_get_ctrl(cipher)
                                        (ctx, EVP_CTRL_AEAD_TLS1_AAD,
                                         EVP_AEAD_TLS1_AAD_LEN,
                                         pipe_ctx->tlsaad[i]);
            }
            ret = ret && EVP_CIPHER_meth_get_do_cipher(cipher)
                                (ctx, pipe_ctx->outbufs[i], pipe_ctx->inbufs[i],
                                 pipe_ctx->lens[i]);
        }
        pipe_ctx->numpipes = 0;
    }
    pipe_ctx->aadctr = 0;
    EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx);
    return ret;
}
Exemple #13
0
static int ctr_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                         const unsigned char *in, size_t inl)
{
    struct cipher_ctx *cipher_ctx =
        (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
    size_t nblocks, len;

    /* initial partial block */
    while (cipher_ctx->num && inl) {
        (*out++) = *(in++) ^ cipher_ctx->partial[cipher_ctx->num];
        --inl;
        cipher_ctx->num = (cipher_ctx->num + 1) % cipher_ctx->blocksize;
    }

    /* full blocks */
    if (inl > (unsigned int) cipher_ctx->blocksize) {
        nblocks = inl/cipher_ctx->blocksize;
        len = nblocks * cipher_ctx->blocksize;
        if (cipher_do_cipher(ctx, out, in, len) < 1)
            return 0;
        inl -= len;
        out += len;
        in += len;
    }

    /* final partial block */
    if (inl) {
        memset(cipher_ctx->partial, 0, cipher_ctx->blocksize);
        if (cipher_do_cipher(ctx, cipher_ctx->partial, cipher_ctx->partial,
            cipher_ctx->blocksize) < 1)
            return 0;
        while (inl--) {
            out[cipher_ctx->num] = in[cipher_ctx->num]
                                   ^ cipher_ctx->partial[cipher_ctx->num];
            cipher_ctx->num++;
        }
    }

    return 1;
}
Exemple #14
0
static int dasync_cipher_ctrl_helper(EVP_CIPHER_CTX *ctx, int type, int arg,
                                     void *ptr, int aeadcapable)
{
    int ret;
    struct dasync_pipeline_ctx *pipe_ctx =
        (struct dasync_pipeline_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);

    if (pipe_ctx == NULL)
        return 0;

    switch (type) {
        case EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS:
            pipe_ctx->numpipes = arg;
            pipe_ctx->outbufs = (unsigned char **)ptr;
            break;

        case EVP_CTRL_SET_PIPELINE_INPUT_BUFS:
            pipe_ctx->numpipes = arg;
            pipe_ctx->inbufs = (unsigned char **)ptr;
            break;

        case EVP_CTRL_SET_PIPELINE_INPUT_LENS:
            pipe_ctx->numpipes = arg;
            pipe_ctx->lens = (size_t *)ptr;
            break;

        case EVP_CTRL_AEAD_SET_MAC_KEY:
            if (!aeadcapable)
                return -1;
            EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx->inner_cipher_data);
            ret = EVP_CIPHER_meth_get_ctrl(EVP_aes_128_cbc_hmac_sha1())
                                          (ctx, type, arg, ptr);
            EVP_CIPHER_CTX_set_cipher_data(ctx, pipe_ctx);
            return ret;

        case EVP_CTRL_AEAD_TLS1_AAD:
        {
            unsigned char *p = ptr;
            unsigned int len;

            if (!aeadcapable || arg != EVP_AEAD_TLS1_AAD_LEN)
                return -1;

            if (pipe_ctx->aadctr >= SSL_MAX_PIPELINES)
                return -1;

            memcpy(pipe_ctx->tlsaad[pipe_ctx->aadctr], ptr,
                   EVP_AEAD_TLS1_AAD_LEN);
            pipe_ctx->aadctr++;

            len = p[arg - 2] << 8 | p[arg - 1];

            if (pipe_ctx->enc) {
                if ((p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
                    len -= AES_BLOCK_SIZE;
                }

                return ((len + SHA_DIGEST_LENGTH + AES_BLOCK_SIZE)
                        & -AES_BLOCK_SIZE) - len;
            } else {
                return SHA_DIGEST_LENGTH;
            }
        }

        default:
            return 0;
    }

    return 1;
}
Exemple #15
0
static int afalg_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                             const unsigned char *iv, int enc)
{
    int ciphertype;
    int ret;
    afalg_ctx *actx;
    char ciphername[ALG_MAX_SALG_NAME];

    if (ctx == NULL || key == NULL) {
        ALG_WARN("%s: Null Parameter\n", __func__);
        return 0;
    }

    if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
        ALG_WARN("%s: Cipher object NULL\n", __func__);
        return 0;
    }

    actx = EVP_CIPHER_CTX_get_cipher_data(ctx);
    if (actx == NULL) {
        ALG_WARN("%s: Cipher data NULL\n", __func__);
        return 0;
    }

    ciphertype = EVP_CIPHER_CTX_nid(ctx);
    switch (ciphertype) {
    case NID_aes_128_cbc:
        strncpy(ciphername, "cbc(aes)", ALG_MAX_SALG_NAME);
        break;
    default:
        ALG_WARN("%s: Unsupported Cipher type %d\n", __func__, ciphertype);
        return 0;
    }
    ciphername[ALG_MAX_SALG_NAME-1]='\0';

    if (ALG_AES_IV_LEN != EVP_CIPHER_CTX_iv_length(ctx)) {
        ALG_WARN("%s: Unsupported IV length :%d\n", __func__,
                EVP_CIPHER_CTX_iv_length(ctx));
        return 0;
    }

    /* Setup AFALG socket for crypto processing */
    ret = afalg_create_sk(actx, "skcipher", ciphername);
    if (ret < 1)
        return 0;


    ret = afalg_set_key(actx, key, EVP_CIPHER_CTX_key_length(ctx));
    if (ret < 1)
        goto err;

    /* Setup AIO ctx to allow async AFALG crypto processing */
    if (afalg_init_aio(&actx->aio) == 0)
        goto err;

# ifdef ALG_ZERO_COPY
    pipe(actx->zc_pipe);
# endif

    actx->init_done = MAGIC_INIT_NUM;

    return 1;

err:
    close(actx->sfd);
    close(actx->bfd);
    return 0;
}
Exemple #16
0
static int cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                            const unsigned char *in, size_t inl)
{
    struct cipher_ctx *cipher_ctx =
        (struct cipher_ctx *)EVP_CIPHER_CTX_get_cipher_data(ctx);
    struct crypt_op cryp;
    unsigned char *iv = EVP_CIPHER_CTX_iv_noconst(ctx);
#if !defined(COP_FLAG_WRITE_IV)
    unsigned char saved_iv[EVP_MAX_IV_LENGTH];
    const unsigned char *ivptr;
    size_t nblocks, ivlen;
#endif

    memset(&cryp, 0, sizeof(cryp));
    cryp.ses = cipher_ctx->sess.ses;
    cryp.len = inl;
    cryp.src = (void *)in;
    cryp.dst = (void *)out;
    cryp.iv = (void *)iv;
    cryp.op = cipher_ctx->op;
#if !defined(COP_FLAG_WRITE_IV)
    cryp.flags = 0;

    ivlen = EVP_CIPHER_CTX_iv_length(ctx);
    if (ivlen > 0)
        switch (cipher_ctx->mode) {
        case EVP_CIPH_CBC_MODE:
            assert(inl >= ivlen);
            if (!EVP_CIPHER_CTX_encrypting(ctx)) {
                ivptr = in + inl - ivlen;
                memcpy(saved_iv, ivptr, ivlen);
            }
            break;

        case EVP_CIPH_CTR_MODE:
            break;

        default: /* should not happen */
            return 0;
        }
#else
    cryp.flags = COP_FLAG_WRITE_IV;
#endif

    if (ioctl(cfd, CIOCCRYPT, &cryp) < 0) {
        SYSerr(SYS_F_IOCTL, errno);
        return 0;
    }

#if !defined(COP_FLAG_WRITE_IV)
    if (ivlen > 0)
        switch (cipher_ctx->mode) {
        case EVP_CIPH_CBC_MODE:
            assert(inl >= ivlen);
            if (EVP_CIPHER_CTX_encrypting(ctx))
                ivptr = out + inl - ivlen;
            else
                ivptr = saved_iv;

            memcpy(iv, ivptr, ivlen);
            break;

        case EVP_CIPH_CTR_MODE:
            nblocks = (inl + cipher_ctx->blocksize - 1)
                      / cipher_ctx->blocksize;
            do {
                ivlen--;
                nblocks += iv[ivlen];
                iv[ivlen] = (uint8_t) nblocks;
                nblocks >>= 8;
            } while (ivlen);
            break;

        default: /* should not happen */
            return 0;
        }
#endif

    return 1;
}