File Coverage

inc/CryptX_AuthEnc_SIV.xs.inc
Criterion Covered Total %
statement 68 70 97.1
branch 79 126 62.7
condition n/a
subroutine n/a
pod n/a
total 147 196 75.0


line stmt bran cond sub pod time code
1             MODULE = CryptX PACKAGE = Crypt::AuthEnc::SIV
2              
3             PROTOTYPES: DISABLE
4              
5             SV *
6             siv_encrypt_authenticate(char *cipher_name, SV *key, SV *plaintext, SV *aad = &PL_sv_undef)
7             CODE:
8             {
9 9           STRLEN k_len = 0, pt_len = 0;
10             unsigned char *k, *pt, *ct;
11             unsigned long ct_len;
12             int rv, id;
13             const unsigned char *ad_ptrs[126];
14             unsigned long ad_lens[126];
15 9           unsigned long n_ad = 0;
16             STRLEN tmp;
17              
18 9           id = cryptx_internal_find_cipher(cipher_name);
19 9 50         if (id == -1) croak("FATAL: find_cipher failed for '%s'", cipher_name);
20              
21 9 50         if (!SvPOK_spec(key)) croak("FATAL: key must be string/buffer scalar");
    100          
    50          
    100          
    50          
22 8           k = (unsigned char *)SvPVbyte(key, k_len);
23 8 50         if (!SvPOK_spec(plaintext)) croak("FATAL: plaintext must be string/buffer scalar");
    100          
    50          
    50          
    50          
24 8           pt = (unsigned char *)SvPVbyte(plaintext, pt_len);
25              
26 8 50         if (SvOK(aad)) {
27 10 100         if (SvROK(aad) && SvTYPE(SvRV(aad)) == SVt_PVAV) {
    100          
28 4           AV *av = (AV *)SvRV(aad);
29 4           SSize_t i, alen = av_len(av);
30 134 100         for (i = 0; i <= alen; i++) {
31 132           SV **svp = av_fetch(av, i, 0);
32 132 50         if (svp && SvOK(*svp)) {
    50          
33 132 100         if (n_ad >= 126) croak("FATAL: too many associated data components (max 126)");
34 131 50         if (!SvPOK_spec(*svp)) croak("FATAL: associated data component must be string/buffer scalar");
    100          
    50          
    100          
    50          
35 130           ad_ptrs[n_ad] = (const unsigned char *)SvPVbyte(*svp, tmp);
36 130           ad_lens[n_ad] = (unsigned long)tmp;
37 130           n_ad++;
38             }
39             }
40             } else {
41 4 50         if (!SvPOK_spec(aad)) croak("FATAL: associated data must be string/buffer scalar or arrayref");
    100          
    50          
    50          
    50          
42 4           ad_ptrs[0] = (const unsigned char *)SvPVbyte(aad, tmp);
43 4           ad_lens[0] = (unsigned long)tmp;
44 4           n_ad = 1;
45             }
46             }
47 6           ct_len = (unsigned long)pt_len + 16;
48 6 50         RETVAL = NEWSV(0, ct_len > 0 ? ct_len : 1);
49 6           SvPOK_only(RETVAL);
50 6           SvCUR_set(RETVAL, ct_len);
51 6           ct = (unsigned char *)SvPVX(RETVAL);
52              
53 6           rv = siv_encrypt_memory(id, k, (unsigned long)k_len,
54             n_ad,
55             ad_ptrs, ad_lens,
56             pt, (unsigned long)pt_len,
57             ct, &ct_len);
58 6 50         if (rv != CRYPT_OK) {
59 0           SvREFCNT_dec(RETVAL);
60 0           croak("FATAL: siv_encrypt_memory failed: %s", error_to_string(rv));
61             }
62 6           SvCUR_set(RETVAL, ct_len);
63             }
64             OUTPUT:
65             RETVAL
66              
67             void
68             siv_decrypt_verify(char *cipher_name, SV *key, SV *ciphertext, SV *aad = &PL_sv_undef)
69             PPCODE:
70             {
71 6           STRLEN k_len = 0, ct_len = 0;
72             unsigned char *k, *ct, *pt;
73             unsigned long pt_len;
74             int rv, id;
75             SV *output;
76             const unsigned char *ad_ptrs[126];
77             unsigned long ad_lens[126];
78 6           unsigned long n_ad = 0;
79             STRLEN tmp;
80              
81 6           id = cryptx_internal_find_cipher(cipher_name);
82 6 50         if (id == -1) croak("FATAL: find_cipher failed for '%s'", cipher_name);
83              
84 6 50         if (!SvPOK_spec(key)) croak("FATAL: key must be string/buffer scalar");
    100          
    50          
    50          
    50          
85 6           k = (unsigned char *)SvPVbyte(key, k_len);
86 6 50         if (!SvPOK_spec(ciphertext)) croak("FATAL: ciphertext must be string/buffer scalar");
    100          
    50          
    100          
    50          
87 5           ct = (unsigned char *)SvPVbyte(ciphertext, ct_len);
88 5 50         if (ct_len < 16) croak("FATAL: ciphertext too short");
89              
90 5 50         if (SvOK(aad)) {
91 6 100         if (SvROK(aad) && SvTYPE(SvRV(aad)) == SVt_PVAV) {
    100          
92 2           AV *av = (AV *)SvRV(aad);
93 2           SSize_t i, alen = av_len(av);
94 131 100         for (i = 0; i <= alen; i++) {
95 130           SV **svp = av_fetch(av, i, 0);
96 130 50         if (svp && SvOK(*svp)) {
    50          
97 130 100         if (n_ad >= 126) croak("FATAL: too many associated data components (max 126)");
98 129 50         if (!SvPOK_spec(*svp)) croak("FATAL: associated data component must be string/buffer scalar");
    50          
    0          
    0          
    0          
99 129           ad_ptrs[n_ad] = (const unsigned char *)SvPVbyte(*svp, tmp);
100 129           ad_lens[n_ad] = (unsigned long)tmp;
101 129           n_ad++;
102             }
103             }
104             } else {
105 3 50         if (!SvPOK_spec(aad)) croak("FATAL: associated data must be string/buffer scalar or arrayref");
    100          
    50          
    50          
    50          
106 3           ad_ptrs[0] = (const unsigned char *)SvPVbyte(aad, tmp);
107 3           ad_lens[0] = (unsigned long)tmp;
108 3           n_ad = 1;
109             }
110             }
111 4           pt_len = (unsigned long)ct_len - 16;
112 4 50         output = NEWSV(0, pt_len > 0 ? pt_len : 1);
113 4           SvPOK_only(output);
114 4           SvCUR_set(output, pt_len);
115 4           pt = (unsigned char *)SvPVX(output);
116              
117 4           rv = siv_decrypt_memory(id, k, (unsigned long)k_len,
118             n_ad,
119             ad_ptrs, ad_lens,
120             ct, (unsigned long)ct_len,
121             pt, &pt_len);
122 4 100         if (rv != CRYPT_OK) {
123 1           SvREFCNT_dec(output);
124 1 50         XPUSHs(sv_2mortal(newSVpvn(NULL, 0))); /* undef */
125             } else {
126 3           SvCUR_set(output, pt_len);
127 3 50         XPUSHs(sv_2mortal(output));
128             }
129             }