File Coverage

inc/CryptX_AuthEnc_GCMSIV.xs.inc
Criterion Covered Total %
statement 49 49 100.0
branch 64 100 64.0
condition n/a
subroutine n/a
pod n/a
total 113 149 75.8


line stmt bran cond sub pod time code
1             MODULE = CryptX PACKAGE = Crypt::AuthEnc::GCMSIV
2              
3             PROTOTYPES: DISABLE
4              
5             SV *
6             gcm_siv_encrypt_authenticate(char *cipher_name, SV *key, SV *nonce, SV *aad, SV *plaintext)
7             CODE:
8             {
9 15           STRLEN k_len = 0, n_len = 0, a_len = 0, pt_len = 0;
10 15           unsigned char *k, *n, *a = NULL, *pt, *ct;
11             unsigned long ct_len, tag_len;
12             int rv, id;
13              
14 15           id = cryptx_internal_find_cipher(cipher_name);
15 15 50         if (id == -1) croak("FATAL: find_cipher failed for '%s'", cipher_name);
16              
17 15 50         if (!SvPOK_spec(key)) croak("FATAL: key must be string/buffer scalar");
    100          
    50          
    100          
    50          
18 14 50         if (!SvPOK_spec(nonce)) croak("FATAL: nonce must be string/buffer scalar");
    100          
    50          
    50          
    50          
19 14 50         if (!SvPOK_spec(plaintext)) croak("FATAL: plaintext must be string/buffer scalar");
    100          
    50          
    50          
    50          
20 14           k = (unsigned char *)SvPVbyte(key, k_len);
21 14           n = (unsigned char *)SvPVbyte(nonce, n_len);
22 14           pt = (unsigned char *)SvPVbyte(plaintext, pt_len);
23 14 100         if (SvOK(aad)) {
24 7 50         if (!SvPOK_spec(aad)) croak("FATAL: adata must be string/buffer scalar");
    100          
    50          
    50          
    50          
25 7           a = (unsigned char *)SvPVbyte(aad, a_len);
26             }
27              
28 14           ct_len = (unsigned long)pt_len + 16;
29 14           RETVAL = NEWSV(0, ct_len);
30 14           SvPOK_only(RETVAL);
31 14           SvCUR_set(RETVAL, ct_len);
32 14           ct = (unsigned char *)SvPVX(RETVAL);
33 14           tag_len = 16;
34              
35 14           rv = gcm_siv_memory(id,
36             k, (unsigned long)k_len,
37             n, (unsigned long)n_len,
38             a, (unsigned long)a_len,
39             pt, (unsigned long)pt_len,
40             ct, /* ciphertext output */
41             ct + pt_len, &tag_len, /* tag appended */
42             LTC_ENCRYPT);
43 14 100         if (rv != CRYPT_OK) {
44 2           SvREFCNT_dec(RETVAL);
45 2           croak("FATAL: gcm_siv_memory(encrypt) failed: %s", error_to_string(rv));
46             }
47             }
48             OUTPUT:
49             RETVAL
50              
51             void
52             gcm_siv_decrypt_verify(char *cipher_name, SV *key, SV *nonce, SV *aad, SV *ciphertext)
53             PPCODE:
54             {
55 10           STRLEN k_len = 0, n_len = 0, a_len = 0, ct_len = 0;
56 10           unsigned char *k, *n, *a = NULL, *ct, *pt;
57             unsigned long pt_len, tag_len;
58             int rv, id;
59             SV *output;
60             unsigned char tag[16];
61              
62 10           id = cryptx_internal_find_cipher(cipher_name);
63 10 50         if (id == -1) croak("FATAL: find_cipher failed for '%s'", cipher_name);
64              
65 10 50         if (!SvPOK_spec(key)) croak("FATAL: key must be string/buffer scalar");
    100          
    50          
    50          
    50          
66 10 50         if (!SvPOK_spec(nonce)) croak("FATAL: nonce must be string/buffer scalar");
    100          
    50          
    50          
    50          
67 10 50         if (!SvPOK_spec(ciphertext)) croak("FATAL: ciphertext must be string/buffer scalar");
    100          
    50          
    50          
    50          
68 10           k = (unsigned char *)SvPVbyte(key, k_len);
69 10           n = (unsigned char *)SvPVbyte(nonce, n_len);
70 10           ct = (unsigned char *)SvPVbyte(ciphertext, ct_len);
71 10 100         if (ct_len < 16) croak("FATAL: ciphertext too short");
72 9 100         if (SvOK(aad)) {
73 7 50         if (!SvPOK_spec(aad)) croak("FATAL: adata must be string/buffer scalar");
    100          
    50          
    50          
    50          
74 7           a = (unsigned char *)SvPVbyte(aad, a_len);
75             }
76              
77 9           pt_len = (unsigned long)ct_len - 16;
78 9 50         output = NEWSV(0, pt_len > 0 ? pt_len : 1);
79 9           SvPOK_only(output);
80 9           SvCUR_set(output, pt_len);
81 9           pt = (unsigned char *)SvPVX(output);
82 9           memcpy(tag, ct + pt_len, 16);
83 9           tag_len = 16;
84              
85 9           rv = gcm_siv_memory(id,
86             k, (unsigned long)k_len,
87             n, (unsigned long)n_len,
88             a, (unsigned long)a_len,
89             ct, pt_len, /* ciphertext input */
90             pt, /* plaintext output */
91             tag, &tag_len,
92             LTC_DECRYPT);
93 9 100         if (rv != CRYPT_OK) {
94 4           SvREFCNT_dec(output);
95 4 50         XPUSHs(sv_2mortal(newSVpvn(NULL, 0))); /* undef */
96             } else {
97 5 50         XPUSHs(sv_2mortal(output));
98             }
99             }