Class: PQCrypto::Seal::Native::Decryptor

Inherits:
Object
  • Object
show all
Defined in:
ext/pq_crypto_seal/pq_crypto_seal.c

Instance Method Summary collapse

Constructor Details

#initialize(key, nonce, ad) ⇒ Object



275
276
277
278
279
280
281
282
283
284
285
286
# File 'ext/pq_crypto_seal/pq_crypto_seal.c', line 275

static VALUE state_initialize(VALUE self, VALUE key, VALUE nonce, VALUE ad) {
    seal_state *st;
    TypedData_Get_Struct(self, seal_state, &state_type, st);
    require_length(key, KEY_BYTES, "key");
    require_length(nonce, NONCE_BYTES, "nonce");
    StringValue(ad);
    aegis256_state_init(&st->state, (uint8_t *)RSTRING_PTR(ad), (size_t)RSTRING_LEN(ad),
                        (uint8_t *)RSTRING_PTR(nonce), (uint8_t *)RSTRING_PTR(key));
    st->finalized = 0;
    st->mode = rb_obj_is_kind_of(self, cEncryptor) ? 1 : 2;
    return self;
}

Instance Method Details

#final(tag) ⇒ Object



344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
# File 'ext/pq_crypto_seal/pq_crypto_seal.c', line 344

static VALUE decrypt_final(VALUE self, VALUE tag) {
    seal_state *st;
    TypedData_Get_Struct(self, seal_state, &state_type, st);
    if (st->mode != 2)
        rb_raise(rb_eRuntimeError, "AEGIS decrypt state is not initialized");
    if (st->finalized)
        rb_raise(rb_eRuntimeError, "AEGIS state is finalized");
    require_length(tag, TAG_BYTES, "tag");
    int result = aegis256_state_decrypt_final(&st->state, (uint8_t *)RSTRING_PTR(tag), TAG_BYTES);
    st->finalized = 1;
    OPENSSL_cleanse(&st->state, sizeof(st->state));
    if (result != 0)
        rb_raise(eAuth, "AEGIS-256 authentication failed");
    return Qtrue;
}

#update(input) ⇒ Object



306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
# File 'ext/pq_crypto_seal/pq_crypto_seal.c', line 306

static VALUE state_update(VALUE self, VALUE input) {
    seal_state *st;
    TypedData_Get_Struct(self, seal_state, &state_type, st);
    if (st->mode != 1 && st->mode != 2)
        rb_raise(rb_eRuntimeError, "AEGIS state is not initialized");
    if (st->finalized)
        rb_raise(rb_eRuntimeError, "AEGIS state is finalized");
    StringValue(input);
    VALUE out = rb_str_new(NULL, RSTRING_LEN(input));
    update_args args = {st, (uint8_t *)RSTRING_PTR(input), (uint8_t *)RSTRING_PTR(out),
                        (size_t)RSTRING_LEN(input), -1};
    void *(*fn)(void *) = st->mode == 1 ? update_encrypt_nogvl : update_decrypt_nogvl;
    if (args.len >= NOGVL_THRESHOLD)
        rb_thread_call_without_gvl(fn, &args, RUBY_UBF_IO, NULL);
    else
        fn(&args);
    RB_GC_GUARD(input);
    if (args.result != 0)
        rb_raise(rb_eRuntimeError, "AEGIS-256 update failed");
    return out;
}