Пример #1
0
void encrypt_buf(struct encryption_ctx *ctx, unsigned char *buf, size_t *len) {
    if (ctx->cipher == CIPHER_TABLE) {
        table_encrypt(buf, *len);
    } else {
        if (ctx->status == STATUS_EMPTY) {
            size_t iv_len = encryption_iv_len[_method];
            memset(ctx->iv, 0, iv_len);
            RAND_bytes(ctx->iv, iv_len);
            init_cipher(ctx, ctx->iv, iv_len, 1);
            size_t out_len = *len + ctx->iv_len;
            unsigned char *cipher_text = malloc(out_len);
            cipher_update(ctx, cipher_text, &out_len, buf, *len);
            memcpy(buf, ctx->iv, iv_len);
            memcpy(buf + iv_len, cipher_text, out_len);
            *len = iv_len + out_len;
            free(cipher_text);
        } else {
            size_t out_len = *len + ctx->iv_len;
            unsigned char *cipher_text = malloc(out_len);
            cipher_update(ctx, cipher_text, &out_len, buf, *len);
            memcpy(buf, cipher_text, out_len);
            *len = out_len;
            free(cipher_text);
        }
    }
}
Пример #2
0
static int cipher_context_update(cipher_ctx_t *ctx, uint8_t *output, size_t *olen,
                                 const uint8_t *input, size_t ilen)
{
#ifdef USE_CRYPTO_APPLECC
    cipher_cc_t *cc = &ctx->cc;
    if (cc->valid == kCCContextValid) {
        CCCryptorStatus ret;
        ret = CCCryptorUpdate(cc->cryptor, input, ilen, output,
                              ilen, olen);
        return (ret == kCCSuccess) ? 1 : 0;
    }
#endif
    cipher_evp_t *evp = &ctx->evp;
#if defined(USE_CRYPTO_OPENSSL)
    int err = 0, tlen = *olen;
    err = EVP_CipherUpdate(evp, (uint8_t *)output, &tlen,
                           (const uint8_t *)input, ilen);
    *olen = tlen;
    return err;
#elif defined(USE_CRYPTO_POLARSSL)
    return !cipher_update(evp, (const uint8_t *)input, ilen,
                          (uint8_t *)output, olen);
#elif defined(USE_CRYPTO_MBEDTLS)
    return !mbedtls_cipher_update(evp, (const uint8_t *)input, ilen,
                                  (uint8_t *)output, olen);
#endif
}
Пример #3
0
int cipher_context_update(cipher_ctx_t *evp, uint8_t *output, int *olen, \
                          const uint8_t *input, int ilen) {
#if defined(USE_CRYPTO_OPENSSL)
        return EVP_CipherUpdate(evp, (uint8_t *) output, (size_t *) olen, \
                                (const uint8_t *) input, (size_t) ilen);
#elif defined(USE_CRYPTO_POLARSSL)
        return !cipher_update(evp, (const uint8_t *) input, (size_t) ilen, \
                              (uint8_t *) output, (size_t *) olen);
#endif
}
Пример #4
0
int cipher_ctx_update (cipher_context_t *ctx, uint8_t *dst, int *dst_len,
    uint8_t *src, int src_len)
{
  int retval = 0;
  size_t s_dst_len = *dst_len;

  retval = cipher_update(ctx, src, (size_t)src_len, dst, &s_dst_len);

  *dst_len = s_dst_len;

  return 0 == retval;
}
Пример #5
0
int cipher_ctx_update (cipher_context_t *ctx, uint8_t *dst, int *dst_len,
    uint8_t *src, int src_len)
{
  size_t s_dst_len = *dst_len;

  if (!polar_ok(cipher_update(ctx, src, (size_t)src_len, dst, &s_dst_len)))
    return 0;

  *dst_len = s_dst_len;

  return 1;
}
Пример #6
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;
}
Пример #7
0
static int cipher_context_update(cipher_ctx_t *ctx, uint8_t *output, int *olen,
                                 const uint8_t *input, int ilen)
{
#ifdef USE_CRYPTO_APPLECC
    cipher_cc_t *cc = &ctx->cc;
    if (cc->valid == kCCContextValid)
    {
        CCCryptorStatus ret;
        ret = CCCryptorUpdate(cc->cryptor, input, ilen, output, ilen + BLOCK_SIZE, (size_t *) olen);
        return (ret == kCCSuccess) ? 1 : 0;
    }
#endif
    cipher_evp_t *evp = &ctx->evp;
#if defined(USE_CRYPTO_OPENSSL)
    return EVP_CipherUpdate(evp, (uint8_t *) output, olen,
                            (const uint8_t *) input, (size_t) ilen);
#elif defined(USE_CRYPTO_POLARSSL)
    return !cipher_update(evp, (const uint8_t *) input, (size_t) ilen,
                          (uint8_t *) output, (size_t *) olen);
#endif
}
Пример #8
0
/*
 * Packet-oriented wrapper for non-AEAD modes
 */
int cipher_crypt( 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 = cipher_set_iv( ctx, iv, iv_len ) ) != 0 )
        return( ret );

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

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

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

    *olen += finish_olen;

    return( 0 );
}
Пример #9
0
struct ibuf *
ikev2_msg_decrypt(struct iked *env, struct iked_sa *sa,
    struct ibuf *msg, struct ibuf *src)
{
	ssize_t			 ivlen, encrlen, integrlen, blocklen,
				    outlen, tmplen;
	uint8_t			 pad = 0, *ptr;
	struct ibuf		*integr, *encr, *tmp = NULL, *out = NULL;
	off_t			 ivoff, encroff, integroff;

	if (sa == NULL ||
	    sa->sa_encr == NULL ||
	    sa->sa_integr == NULL) {
		log_debug("%s: invalid SA", __func__);
		print_hex(ibuf_data(src), 0, ibuf_size(src));
		goto done;
	}

	if (!sa->sa_hdr.sh_initiator) {
		encr = sa->sa_key_iencr;
		integr = sa->sa_key_iauth;
	} else {
		encr = sa->sa_key_rencr;
		integr = sa->sa_key_rauth;
	}

	blocklen = cipher_length(sa->sa_encr);
	ivlen = cipher_ivlength(sa->sa_encr);
	ivoff = 0;
	integrlen = hash_length(sa->sa_integr);
	integroff = ibuf_size(src) - integrlen;
	encroff = ivlen;
	encrlen = ibuf_size(src) - integrlen - ivlen;

	if (encrlen < 0 || integroff < 0) {
		log_debug("%s: invalid integrity value", __func__);
		goto done;
	}

	log_debug("%s: IV length %zd", __func__, ivlen);
	print_hex(ibuf_data(src), 0, ivlen);
	log_debug("%s: encrypted payload length %zd", __func__, encrlen);
	print_hex(ibuf_data(src), encroff, encrlen);
	log_debug("%s: integrity checksum length %zd", __func__, integrlen);
	print_hex(ibuf_data(src), integroff, integrlen);

	/*
	 * Validate packet checksum
	 */
	if ((tmp = ibuf_new(NULL, ibuf_length(integr))) == NULL)
		goto done;

	hash_setkey(sa->sa_integr, integr->buf, ibuf_length(integr));
	hash_init(sa->sa_integr);
	hash_update(sa->sa_integr, ibuf_data(msg),
	    ibuf_size(msg) - integrlen);
	hash_final(sa->sa_integr, tmp->buf, &tmplen);

	if (memcmp(tmp->buf, ibuf_data(src) + integroff, integrlen) != 0) {
		log_debug("%s: integrity check failed", __func__);
		goto done;
	}

	log_debug("%s: integrity check succeeded", __func__);
	print_hex(tmp->buf, 0, tmplen);

	ibuf_release(tmp);
	tmp = NULL;

	/*
	 * Decrypt the payload and strip any padding
	 */
	if ((encrlen % blocklen) != 0) {
		log_debug("%s: unaligned encrypted payload", __func__);
		goto done;
	}

	cipher_setkey(sa->sa_encr, encr->buf, ibuf_length(encr));
	cipher_setiv(sa->sa_encr, ibuf_data(src) + ivoff, ivlen);
	cipher_init_decrypt(sa->sa_encr);

	if ((out = ibuf_new(NULL, cipher_outlength(sa->sa_encr,
	    encrlen))) == NULL)
		goto done;

	if ((outlen = ibuf_length(out)) != 0) {
		cipher_update(sa->sa_encr, ibuf_data(src) + encroff, encrlen,
		    ibuf_data(out), &outlen);

		ptr = ibuf_seek(out, outlen - 1, 1);
		pad = *ptr;
	}

	log_debug("%s: decrypted payload length %zd/%zd padding %d",
	    __func__, outlen, encrlen, pad);
	print_hex(ibuf_data(out), 0, ibuf_size(out));

	if (ibuf_setsize(out, outlen) != 0)
		goto done;

	ibuf_release(src);
	return (out);
 done:
	ibuf_release(tmp);
	ibuf_release(out);
	ibuf_release(src);
	return (NULL);
}
Пример #10
0
struct ibuf *
ikev2_msg_encrypt(struct iked *env, struct iked_sa *sa, struct ibuf *src)
{
	size_t			 len, encrlen, integrlen, blocklen, outlen;
	uint8_t			*buf, pad = 0, *ptr;
	struct ibuf		*encr, *dst = NULL, *out = NULL;

	buf = ibuf_data(src);
	len = ibuf_size(src);

	log_debug("%s: decrypted length %zu", __func__, len);
	print_hex(buf, 0, len);

	if (sa == NULL ||
	    sa->sa_encr == NULL ||
	    sa->sa_integr == NULL) {
		log_debug("%s: invalid SA", __func__);
		goto done;
	}

	if (sa->sa_hdr.sh_initiator)
		encr = sa->sa_key_iencr;
	else
		encr = sa->sa_key_rencr;

	blocklen = cipher_length(sa->sa_encr);
	integrlen = hash_length(sa->sa_integr);
	encrlen = roundup(len + sizeof(pad), blocklen);
	pad = encrlen - (len + sizeof(pad));

	/*
	 * Pad the payload and encrypt it
	 */
	if (pad) {
		if ((ptr = ibuf_advance(src, pad)) == NULL)
			goto done;
		arc4random_buf(ptr, pad);
	}
	if (ibuf_add(src, &pad, sizeof(pad)) != 0)
		goto done;

	log_debug("%s: padded length %zu", __func__, ibuf_size(src));
	print_hex(ibuf_data(src), 0, ibuf_size(src));

	cipher_setkey(sa->sa_encr, encr->buf, ibuf_length(encr));
	cipher_setiv(sa->sa_encr, NULL, 0);
	cipher_init_encrypt(sa->sa_encr);

	if ((dst = ibuf_dup(sa->sa_encr->encr_iv)) == NULL)
		goto done;

	if ((out = ibuf_new(NULL,
	    cipher_outlength(sa->sa_encr, encrlen))) == NULL)
		goto done;

	outlen = ibuf_size(out);
	cipher_update(sa->sa_encr,
	    ibuf_data(src), encrlen, ibuf_data(out), &outlen);

	if (outlen && ibuf_add(dst, ibuf_data(out), outlen) != 0)
		goto done;

	if ((ptr = ibuf_advance(dst, integrlen)) == NULL)
		goto done;
	explicit_bzero(ptr, integrlen);

	log_debug("%s: length %zu, padding %d, output length %zu",
	    __func__, len + sizeof(pad), pad, ibuf_size(dst));
	print_hex(ibuf_data(dst), 0, ibuf_size(dst));

	ibuf_release(src);
	ibuf_release(out);
	return (dst);
 done:
	ibuf_release(src);
	ibuf_release(out);
	ibuf_release(dst);
	return (NULL);
}
Пример #11
0
int pkcs5_pbes2( asn1_buf *pbe_params, int mode,
                 const unsigned char *pwd,  size_t pwdlen,
                 const unsigned char *data, size_t datalen,
                 unsigned char *output )
{
    int ret, iterations = 0, keylen = 0;
    unsigned char *p, *end, *end2;
    asn1_buf kdf_alg_oid, enc_scheme_oid, salt;
    md_type_t md_type = POLARSSL_MD_SHA1;
    unsigned char key[32], iv[32];
    size_t len = 0, olen = 0;
    const md_info_t *md_info;
    const cipher_info_t *cipher_info;
    md_context_t md_ctx;
    cipher_context_t cipher_ctx;

    p = pbe_params->p;
    end = p + pbe_params->len;

    /*
     *  PBES2-params ::= SEQUENCE {
     *    keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}},
     *    encryptionScheme AlgorithmIdentifier {{PBES2-Encs}}
     *  }
     */
    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
    }

    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
    }

    end2 = p + len;

    if( ( ret = asn1_get_tag( &p, end2, &kdf_alg_oid.len, ASN1_OID ) ) != 0 )
        return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );

    kdf_alg_oid.p = p;
    p += kdf_alg_oid.len;

    // Only PBKDF2 supported at the moment
    //
    if( !OID_CMP( OID_PKCS5_PBKDF2, &kdf_alg_oid ) )
        return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE );

    if( ( ret = pkcs5_parse_pbkdf2_params( &p, end2,
                                           &salt, &iterations, &keylen,
                                           &md_type ) ) != 0 )
    {
        return( ret );
    }

    md_info = md_info_from_type( md_type );
    if( md_info == NULL )
        return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE );

    if( ( ret = asn1_get_tag( &p, end, &len,
            ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
    {
        return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );
    }

    end2 = p + len;

    if( ( ret = asn1_get_tag( &p, end2, &enc_scheme_oid.len, ASN1_OID ) ) != 0 )
        return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );

    enc_scheme_oid.p = p;
    p += enc_scheme_oid.len;

#if defined(POLARSSL_DES_C)
    // Only DES-CBC and DES-EDE3-CBC supported at the moment
    //
    if( OID_CMP( OID_DES_EDE3_CBC, &enc_scheme_oid ) )
    {
        cipher_info = cipher_info_from_type( POLARSSL_CIPHER_DES_EDE3_CBC );
    }
    else if( OID_CMP( OID_DES_CBC, &enc_scheme_oid ) )
    {
        cipher_info = cipher_info_from_type( POLARSSL_CIPHER_DES_CBC );
    }
    else
#endif /* POLARSSL_DES_C */
        return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE );

    if( cipher_info == NULL )
        return( POLARSSL_ERR_PKCS5_FEATURE_UNAVAILABLE );

    keylen = cipher_info->key_length / 8;

    if( ( ret = asn1_get_tag( &p, end2, &len, ASN1_OCTET_STRING ) ) != 0 )
        return( POLARSSL_ERR_PKCS5_INVALID_FORMAT + ret );

    if( len != cipher_info->iv_size )
        return( POLARSSL_ERR_PKCS5_INVALID_FORMAT );

    memcpy( iv, p, len );

    if( ( ret = md_init_ctx( &md_ctx, md_info ) ) != 0 )
        return( ret );

    if( ( ret = cipher_init_ctx( &cipher_ctx, cipher_info ) ) != 0 )
        return( ret );

    if ( ( ret = pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len,
                                    iterations, keylen, key ) ) != 0 )
    {
        return( ret );
    }

    if( ( ret = cipher_setkey( &cipher_ctx, key, keylen, mode ) ) != 0 )
        return( ret );

    if( ( ret = cipher_reset( &cipher_ctx, iv ) ) != 0 )
        return( ret );

    if( ( ret = cipher_update( &cipher_ctx, data, datalen,
                                output, &olen ) ) != 0 )
    {
        return( ret );
    }

    if( ( ret = cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 )
        return( POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH );

    return( 0 );
}