1 /**
2  * @file sodium.h
3  * @brief Crypto layer using libsodium.
4  *
5  * (c) 2013-2014 by Mega Limited, Auckland, New Zealand
6  *
7  * This file is part of the MEGA SDK - Client Access Engine.
8  *
9  * Applications using the MEGA API must present a valid application key
10  * and comply with the the rules set forth in the Terms of Service.
11  *
12  * The MEGA SDK is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15  *
16  * @copyright Simplified (2-clause) BSD License.
17  *
18  * You should have received a copy of the license along with this
19  * program.
20  */
21 
22 #ifndef SODIUM_H
23 #define SODIUM_H 1
24 
25 #include <sodium.h>
26 
27 namespace mega {
28 
29 class PrnGen;
30 
31 /**
32  * @brief Asymmetric cryptographic signature using EdDSA with Edwards 25519.
33  */
34 class MEGA_API EdDSA
35 {
36 public:
37     static const int SEED_KEY_LENGTH = crypto_sign_SEEDBYTES;
38     static const int PUBLIC_KEY_LENGTH = crypto_sign_PUBLICKEYBYTES;
39 
40     // TLV key to access to the corresponding value in the TLV records
41     static const std::string TLV_KEY;
42     bool initializationOK;
43 
44     EdDSA(PrnGen &rng, unsigned char* keySeed = NULL);
45     ~EdDSA();
46 
47     unsigned char keySeed[SEED_KEY_LENGTH];
48     unsigned char pubKey[PUBLIC_KEY_LENGTH];
49 
50     /**
51      * @brief Computes the signature of a message.
52      *
53      * @param msg The message to sign.
54      * @param msglen Length of the message.
55      * @param sig Buffer to take the signature.
56      * @return Number of bytes for signed message (msg length + signature),
57      *     0 on failure.
58      */
59     int sign(const unsigned char* msg, const unsigned long long msglen,
60              unsigned char* sig);
61 
62     /**
63      * @brief Verifies the signature of a message.
64      *
65      * @param msg Text of the message.
66      * @param msglen Length of message.
67      * @param sig Signature of the message
68      * @param pubKey Public key to check the signature.
69      * @return 1 on a valid signature, 0 on a failed verification.
70      */
71     static int verify(const unsigned char* msg, unsigned long long msglen,
72                       const unsigned char* sig, const unsigned char* pubKey);
73 
74     void signKey(const unsigned char* key, const unsigned long long keyLength, std::string *sigBuf, uint64_t ts = 0);
75     static bool verifyKey(const unsigned char* pubk, const unsigned long long pubkLen,
76                    const std::string *sig, const unsigned char* singingPubKey);
77 
78 private:
79     static const int PRIVATE_KEY_LENGTH = crypto_sign_SECRETKEYBYTES;
80     unsigned char privKey[PRIVATE_KEY_LENGTH]; // don't use it externally, use keySeed instead
81 };
82 
83 
84 /**
85  * @brief Asymmetric cryptographic for chat messages encryptiong using
86  * ECDH approach with x25519 key pair.
87  */
88 class MEGA_API ECDH
89 {
90 public:
91     static const int PRIVATE_KEY_LENGTH = crypto_box_SECRETKEYBYTES;
92     static const int PUBLIC_KEY_LENGTH = crypto_box_PUBLICKEYBYTES;
93 
94     // TLV key to access to the corresponding value in the TLV records
95     static const std::string TLV_KEY;
96     bool initializationOK;
97 
98     unsigned char privKey[PRIVATE_KEY_LENGTH];
99     unsigned char pubKey[PUBLIC_KEY_LENGTH];
100 
101     ECDH(unsigned char * privKey = NULL);
102     ~ECDH();
103 
104     /**
105      * @brief encrypt Encrypt a message using the public key of recipient, the
106      * private key of the sender and a nonce (number used once)
107      *
108      * @param encmsg Encrypted text after encryption. This function ensures that the
109      * first crypto_box_ZEROBYTES bytes of the encrypted text msg are all 0.
110      * @param msg Message to be encrypted. Caller must ensure that the first
111      * crypto_box_ZEROBYTES bytes of the message msg are all 0.
112      * @param msglen Lenght of the message to be encrypted.
113      * @param nonce Number used once. The same nonce must never be used to encrypt another
114      * packet from the sender's private key to this receiver's public key or viceversa.
115      * @param pubKey Public key of the receiver.
116      * @param privKey Private key of the sender.
117      *
118      * @return 1 on success, 0 on failure.
119      */
120     int encrypt(unsigned char* encmsg, const unsigned char* msg,
121                const unsigned long long msglen, const unsigned char* nonce,
122                const unsigned char* pubKey, const unsigned char* privKey);
123 
124     /**
125      * @brief decrypt Decrypt a message using the public key of recipient, the
126      * private key of the sender and a nonce (number used once)
127      *
128      * @param msg Message in plain text after decryption. This function ensures that
129      * the first crypto_box_ZEROBYTES bytes of the message msg are all 0.
130      * @param encmsg Encrypted text to be decrypted. Caller must ensure that the first
131      * crypto_box_ZEROBYTES bytes of the chipered text encmsg are all 0.
132      * @param encmsglen Length of the encrypted text.
133      * @param nonce Number used once. The same nonce must never be used to encrypt another
134      * packet from the sender's private key to this receiver's public key or viceversa.
135      * @param pubKey Public key of the sender.
136      * @param privKey Private key of the receiver.
137      *
138      * @return 1 on success, 0 on failure.
139      */
140     int decrypt(unsigned char* msg, const unsigned char* encmsg,
141                  const unsigned long long encmsglen, const unsigned char* nonce,
142                  const unsigned char* pubKey, const unsigned char* privKey);
143 };
144 
145 } // namespace
146 
147 #endif
148