static VALUE 
ossl_cipher_update(VALUE self, VALUE data)
{
    EVP_CIPHER_CTX *ctx;
    char *in;
    int in_len, out_len;
    VALUE str;

    StringValue(data);
    in = RSTRING(data)->ptr;
    if ((in_len = RSTRING(data)->len) == 0)
        rb_raise(rb_eArgError, "data must not be empty");
    GetCipher(self, ctx);
    str = rb_str_new(0, in_len+EVP_CIPHER_CTX_block_size(ctx));
    if (!EVP_CipherUpdate(ctx, RSTRING(str)->ptr, &out_len, in, in_len))
	ossl_raise(eCipherError, NULL);
    assert(out_len < RSTRING(str)->len);
    RSTRING(str)->len = out_len;
    RSTRING(str)->ptr[out_len] = 0;

    return str;
}
Example #2
0
/*
 *  call-seq:
 *     cipher.auth_tag([ tag_len ] -> string
 *
 *  Gets the authentication tag generated by Authenticated Encryption Cipher
 *  modes (GCM for example). This tag may be stored along with the ciphertext,
 *  then set on the decryption cipher to authenticate the contents of the
 *  ciphertext against changes. If the optional integer parameter +tag_len+ is
 *  given, the returned tag will be +tag_len+ bytes long. If the parameter is
 *  omitted, the maximum length of 16 bytes will be returned. For maximum
 *  security, the default of 16 bytes should be chosen.
 *
 *  The tag may only be retrieved after calling Cipher#final.
 */
static VALUE
ossl_cipher_get_auth_tag(int argc, VALUE *argv, VALUE self)
{
    VALUE vtag_len;
    EVP_CIPHER_CTX *ctx;
    int nid, tag_len;

    if (rb_scan_args(argc, argv, "01", &vtag_len) == 0) {
	tag_len = 16;
    } else {
	tag_len = NUM2INT(vtag_len);
    }

    GetCipher(self, ctx);
    nid = EVP_CIPHER_CTX_nid(ctx);

    if (ossl_is_gcm(nid)) {
	return ossl_get_gcm_auth_tag(ctx, tag_len);
    } else {
	ossl_raise(eCipherError, "authentication tag not supported by this cipher");
	return Qnil; /* dummy */
    }
}
Example #3
0
/*
 *  call-seq:
 *     cipher.auth_tag = string -> string
 *
 *  Sets the authentication tag to verify the contents of the
 *  ciphertext. The tag must be set after calling Cipher#decrypt,
 *  Cipher#key= and Cipher#iv=, but before assigning the associated
 *  authenticated data using Cipher#auth_data= and of course, before
 *  decrypting any of the ciphertext. After all decryption is
 *  performed, the tag is verified automatically in the call to
 *  Cipher#final.
 */
static VALUE
ossl_cipher_set_auth_tag(VALUE self, VALUE vtag)
{
    EVP_CIPHER_CTX *ctx;
    int nid;
    unsigned char *tag;
    int tag_len;

    StringValue(vtag);
    tag = (unsigned char *) RSTRING_PTR(vtag);
    tag_len = RSTRING_LENINT(vtag);

    GetCipher(self, ctx);
    nid = EVP_CIPHER_CTX_nid(ctx);

    if (ossl_is_gcm(nid)) {
	ossl_set_gcm_auth_tag(ctx, tag, tag_len);
    } else {
	ossl_raise(eCipherError, "authentication tag not supported by this cipher");
    }

    return vtag;
}
Example #4
0
static VALUE
ossl_cipher_set_tag(VALUE self, VALUE data)
{
    EVP_CIPHER_CTX *ctx;
    char           *in     = NULL;
    int             in_len = 0;

    StringValue(data);

    in     = (unsigned char *) RSTRING_PTR(data);
    in_len = RSTRING_LEN(data);

    GetCipher(self, ctx);

#ifndef EVP_CTRL_GCM_SET_TAG
    ossl_raise(eCipherError, "your version of OpenSSL doesn't support GCM");
#else
    if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, in_len, in))
        ossl_raise(eCipherError, NULL);
#endif

    return data;
}