File Coverage

inc/CryptX_Stream_ChaCha.xs.inc
Criterion Covered Total %
statement 47 59 79.6
branch 23 46 50.0
condition n/a
subroutine n/a
pod n/a
total 70 105 66.6


line stmt bran cond sub pod time code
1             MODULE = CryptX PACKAGE = Crypt::Stream::ChaCha
2              
3             PROTOTYPES: DISABLE
4              
5             Crypt::Stream::ChaCha
6             new(Class, SV * key, SV * nonce, UV counter = 0, int rounds = 20)
7             CODE:
8             {
9             int rv;
10 15           STRLEN iv_len=0, k_len=0;
11 15           unsigned char *iv=NULL, *k=NULL;
12              
13 15 50         if (!SvPOK_spec(key)) croak("FATAL: key must be string/buffer scalar");
    50          
    0          
    0          
    0          
14 15 50         if (!SvPOK_spec(nonce)) croak("FATAL: nonce must be string/buffer scalar");
    50          
    0          
    0          
    0          
15 15           k = (unsigned char *) SvPVbyte(key, k_len);
16 15           iv = (unsigned char *) SvPVbyte(nonce, iv_len);
17              
18 15           Newz(0, RETVAL, 1, chacha_state);
19 15 50         if (!RETVAL) croak("FATAL: Newz failed");
20              
21 15           rv = chacha_setup(RETVAL, k, (unsigned long)k_len, rounds);
22 15 50         if (rv != CRYPT_OK) {
23 0           Safefree(RETVAL);
24 0           croak("FATAL: chacha_setup failed: %s", error_to_string(rv));
25             }
26              
27 15 100         if (iv_len == 12) {
28 6 100         if (counter > (UV)0xFFFFFFFFUL) {
29 1           chacha_done(RETVAL);
30 1           Safefree(RETVAL);
31 1           croak("FATAL: chacha counter too large for 12-byte nonce");
32             }
33 5           rv = chacha_ivctr32(RETVAL, iv, (unsigned long)iv_len, (ulong32)counter);
34 5 50         if (rv != CRYPT_OK) {
35 0           chacha_done(RETVAL);
36 0           Safefree(RETVAL);
37 0           croak("FATAL: chacha_ivctr32 failed: %s", error_to_string(rv));
38             }
39             }
40 9 100         else if (iv_len == 8) {
41 8           rv = chacha_ivctr64(RETVAL, iv, (unsigned long)iv_len, (ulong64)counter);
42 8 50         if (rv != CRYPT_OK) {
43 0           chacha_done(RETVAL);
44 0           Safefree(RETVAL);
45 0           croak("FATAL: chacha_ivctr64 failed: %s", error_to_string(rv));
46             }
47             }
48             else {
49 1           chacha_done(RETVAL);
50 1           Safefree(RETVAL);
51 1           croak("FATAL: chacha IV length must be 8 or 12 bytes");
52             }
53             }
54             OUTPUT:
55             RETVAL
56              
57             void
58             DESTROY(Crypt::Stream::ChaCha self)
59             CODE:
60 15           chacha_done(self);
61 15           zeromem(self, sizeof(*self));
62 15           Safefree(self);
63              
64             Crypt::Stream::ChaCha
65             clone(Crypt::Stream::ChaCha self)
66             CODE:
67 2           Newz(0, RETVAL, 1, chacha_state);
68 2 50         if (!RETVAL) croak("FATAL: Newz failed");
69 2           Copy(self, RETVAL, 1, chacha_state);
70             OUTPUT:
71             RETVAL
72              
73             SV *
74             keystream(Crypt::Stream::ChaCha self, unsigned long out_len)
75             CODE:
76             {
77             int rv;
78             unsigned char *out_data;
79              
80 5 100         if (out_len == 0) {
81 1           RETVAL = newSVpvn("", 0);
82             }
83             else {
84 4 100         if (out_len == ULONG_MAX) croak("FATAL: output length too large");
85 2           RETVAL = NEWSV(0, out_len); /* avoid zero! */
86 2           SvPOK_only(RETVAL);
87 2           SvCUR_set(RETVAL, out_len);
88 2           out_data = (unsigned char *)SvPVX(RETVAL);
89 2           rv = chacha_keystream(self, out_data, out_len);
90 2 50         if (rv != CRYPT_OK) {
91 0           SvREFCNT_dec(RETVAL);
92 0           croak("FATAL: chacha_keystream failed: %s", error_to_string(rv));
93             }
94             }
95             }
96             OUTPUT:
97             RETVAL
98              
99             SV *
100             crypt(Crypt::Stream::ChaCha self, SV * data)
101             CODE:
102             {
103             int rv;
104             STRLEN in_data_len;
105             unsigned char *in_data, *out_data;
106              
107 11           in_data = (unsigned char *)SvPVbyte(data, in_data_len);
108 11 100         if (in_data_len == 0) {
109 1           RETVAL = newSVpvn("", 0);
110             }
111             else {
112 10           RETVAL = NEWSV(0, in_data_len); /* avoid zero! */
113 10           SvPOK_only(RETVAL);
114 10           SvCUR_set(RETVAL, in_data_len);
115 10           out_data = (unsigned char *)SvPVX(RETVAL);
116 10           rv = chacha_crypt(self, in_data, (unsigned long)in_data_len, out_data);
117 10 50         if (rv != CRYPT_OK) {
118 0           SvREFCNT_dec(RETVAL);
119 0           croak("FATAL: chacha_crypt failed: %s", error_to_string(rv));
120             }
121             }
122             }
123             OUTPUT:
124             RETVAL