File Coverage

Nitrate.xs
Criterion Covered Total %
statement 44 48 91.6
branch 19 32 59.3
condition n/a
subroutine n/a
pod n/a
total 63 80 78.7


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2              
3             #include "EXTERN.h"
4             #include "perl.h"
5             #include "XSUB.h"
6              
7             /* libsodium */
8             #include "sodium.h"
9              
10             SV*
11 17           THX_sodium_encrypt(pTHX_ SV* msg, SV* nonce, SV* key)
12             #define sodium_encrypt(a,b,c) THX_sodium_encrypt(aTHX_ a,b,c)
13             {
14             SV* encrypted_sv;
15             STRLEN msg_len, nonce_len, key_len, enc_len;
16             unsigned char *msg_buf, *nonce_buf, *key_buf;
17 17 50         nonce_buf = (unsigned char *)SvPV(nonce, nonce_len);
18 17 100         if ( nonce_len != crypto_secretbox_NONCEBYTES ) {
19 1           croak("Invalid nonce");
20             }
21              
22 16 50         key_buf = (unsigned char *)SvPV(key, key_len);
23 16 100         if ( key_len != crypto_secretbox_KEYBYTES ) {
24 1           croak("Invalid key");
25             }
26              
27 15 50         msg_buf = (unsigned char *)SvPV(msg, msg_len);
28              
29 15           enc_len = crypto_secretbox_MACBYTES + msg_len;
30              
31 15           encrypted_sv = newSV(enc_len);
32 15 50         SvUPGRADE(encrypted_sv, SVt_PV);
33 15           SvPOK_on(encrypted_sv);
34 15           SvCUR_set(encrypted_sv, enc_len);
35              
36 15           crypto_secretbox_easy(
37 15           (unsigned char *)SvPVX(encrypted_sv),
38             msg_buf,
39             msg_len,
40             nonce_buf,
41             key_buf
42             );
43              
44 15           return encrypted_sv;
45             }
46              
47             SV*
48 14           THX_sodium_decrypt(pTHX_ SV* ciphertext, SV* nonce, SV* key)
49             #define sodium_decrypt(a,b,c) THX_sodium_decrypt(aTHX_ a,b,c)
50             {
51             SV* decrypted_sv;
52             STRLEN dec_len, nonce_len, key_len, msg_len;
53 14           int decrypt_result = 0;
54             unsigned char *nonce_buf, *key_buf, *msg_buf;
55              
56 14 50         nonce_buf = (unsigned char *)SvPV(nonce, nonce_len);
57 14 50         if ( nonce_len != crypto_secretbox_NONCEBYTES ) {
58 0           croak("Invalid nonce: %"SVf, nonce);
59             }
60              
61 14 50         key_buf = (unsigned char *)SvPV(key, key_len);
62 14 50         if ( key_len != crypto_secretbox_KEYBYTES ) {
63 0           croak("Invalid key");
64             }
65              
66 14 50         msg_buf = (unsigned char *)SvPV(ciphertext, msg_len);
67 14 100         if ( msg_len < crypto_secretbox_MACBYTES ) {
68 1           croak("Invalid ciphertext");
69             }
70 13           dec_len = msg_len - crypto_secretbox_MACBYTES;
71              
72 13           decrypted_sv = newSV(dec_len);
73 13 50         SvUPGRADE(decrypted_sv, SVt_PV);
74 13           SvPOK_on(decrypted_sv);
75              
76 13           decrypt_result = crypto_secretbox_open_easy(
77 13           (unsigned char *)SvPVX(decrypted_sv),
78             msg_buf,
79             msg_len,
80             nonce_buf,
81             key_buf
82             );
83              
84 13 50         if ( decrypt_result != 0 ) {
85 0           sv_free(decrypted_sv);
86 0           croak("Message forged");
87             }
88              
89 13           SvCUR_set(decrypted_sv, dec_len);
90 13           return decrypted_sv;
91             }
92              
93             MODULE = Crypt::Sodium::Nitrate PACKAGE = Crypt::Sodium::Nitrate
94              
95             PROTOTYPES: DISABLE
96              
97             void
98             encrypt(SV* msg, SV* nonce, SV* key)
99             INIT:
100             SV* encrypted_sv;
101             PPCODE:
102             {
103 17           encrypted_sv = sodium_encrypt(msg, nonce, key);
104 15 50         mXPUSHs( encrypted_sv );
105 15           XSRETURN(1);
106             }
107              
108             void
109             decrypt(SV* ciphertext, SV* nonce, SV* key)
110             INIT:
111             SV* decrypted_sv;
112             PPCODE:
113             {
114 14           decrypted_sv = sodium_decrypt(ciphertext, nonce, key);
115 13 50         mXPUSHs( decrypted_sv );
116 13           XSRETURN(1);
117             }
118              
119             BOOT:
120             {
121             /* let's create a couple of constants for perl to use */
122 4           HV *stash = gv_stashpvs("Crypt::Sodium::Nitrate", GV_ADD);
123              
124 4           newCONSTSUB(stash, "NONCEBYTES", newSViv(crypto_secretbox_NONCEBYTES));
125 4           newCONSTSUB(stash, "KEYBYTES", newSViv(crypto_secretbox_KEYBYTES));
126 4           newCONSTSUB(stash, "MACBYTES", newSViv(crypto_secretbox_MACBYTES));
127             }
128