• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2017, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #include "cavp_test_util.h"
16 
17 #include <openssl/bn.h>
18 #include <openssl/digest.h>
19 #include <openssl/ec.h>
20 #include <openssl/nid.h>
21 
22 
GetCipher(const std::string & name)23 const EVP_CIPHER *GetCipher(const std::string &name) {
24   if (name == "des-cbc") {
25     return EVP_des_cbc();
26   } else if (name == "des-ecb") {
27     return EVP_des_ecb();
28   } else if (name == "des-ede") {
29     return EVP_des_ede();
30   } else if (name == "des-ede3") {
31     return EVP_des_ede3();
32   } else if (name == "des-ede-cbc") {
33     return EVP_des_ede_cbc();
34   } else if (name == "des-ede3-cbc") {
35     return EVP_des_ede3_cbc();
36   } else if (name == "rc4") {
37     return EVP_rc4();
38   } else if (name == "aes-128-ecb") {
39     return EVP_aes_128_ecb();
40   } else if (name == "aes-256-ecb") {
41     return EVP_aes_256_ecb();
42   } else if (name == "aes-128-cbc") {
43     return EVP_aes_128_cbc();
44   } else if (name == "aes-128-gcm") {
45     return EVP_aes_128_gcm();
46   } else if (name == "aes-128-ofb") {
47     return EVP_aes_128_ofb();
48   } else if (name == "aes-192-cbc") {
49     return EVP_aes_192_cbc();
50   } else if (name == "aes-192-ctr") {
51     return EVP_aes_192_ctr();
52   } else if (name == "aes-192-ecb") {
53     return EVP_aes_192_ecb();
54   } else if (name == "aes-256-cbc") {
55     return EVP_aes_256_cbc();
56   } else if (name == "aes-128-ctr") {
57     return EVP_aes_128_ctr();
58   } else if (name == "aes-256-ctr") {
59     return EVP_aes_256_ctr();
60   } else if (name == "aes-256-gcm") {
61     return EVP_aes_256_gcm();
62   } else if (name == "aes-256-ofb") {
63     return EVP_aes_256_ofb();
64   }
65   return nullptr;
66 }
67 
CipherOperation(const EVP_CIPHER * cipher,std::vector<uint8_t> * out,bool encrypt,const std::vector<uint8_t> & key,const std::vector<uint8_t> & iv,const std::vector<uint8_t> & in)68 bool CipherOperation(const EVP_CIPHER *cipher, std::vector<uint8_t> *out,
69                      bool encrypt, const std::vector<uint8_t> &key,
70                      const std::vector<uint8_t> &iv,
71                      const std::vector<uint8_t> &in) {
72   bssl::ScopedEVP_CIPHER_CTX ctx;
73   if (!EVP_CipherInit_ex(ctx.get(), cipher, nullptr, nullptr, nullptr,
74                          encrypt ? 1 : 0)) {
75     return false;
76   }
77   if (!iv.empty() && iv.size() != EVP_CIPHER_CTX_iv_length(ctx.get())) {
78     return false;
79   }
80 
81   int result_len1 = 0, result_len2;
82   *out = std::vector<uint8_t>(in.size());
83   if (!EVP_CIPHER_CTX_set_key_length(ctx.get(), key.size()) ||
84       !EVP_CipherInit_ex(ctx.get(), nullptr, nullptr, key.data(), iv.data(),
85                          -1) ||
86       !EVP_CIPHER_CTX_set_padding(ctx.get(), 0) ||
87       !EVP_CipherUpdate(ctx.get(), out->data(), &result_len1, in.data(),
88                         in.size()) ||
89       !EVP_CipherFinal_ex(ctx.get(), out->data() + result_len1, &result_len2)) {
90     return false;
91   }
92   out->resize(result_len1 + result_len2);
93 
94   return true;
95 }
96 
AEADEncrypt(const EVP_AEAD * aead,std::vector<uint8_t> * ct,std::vector<uint8_t> * tag,size_t tag_len,const std::vector<uint8_t> & key,const std::vector<uint8_t> & pt,const std::vector<uint8_t> & aad,const std::vector<uint8_t> & iv)97 bool AEADEncrypt(const EVP_AEAD *aead, std::vector<uint8_t> *ct,
98                  std::vector<uint8_t> *tag, size_t tag_len,
99                  const std::vector<uint8_t> &key,
100                  const std::vector<uint8_t> &pt,
101                  const std::vector<uint8_t> &aad,
102                  const std::vector<uint8_t> &iv) {
103   bssl::ScopedEVP_AEAD_CTX ctx;
104   if (!EVP_AEAD_CTX_init(ctx.get(), aead, key.data(), key.size(), tag_len,
105                          nullptr)) {
106     return false;
107   }
108 
109   std::vector<uint8_t> out;
110   out.resize(pt.size() + EVP_AEAD_max_overhead(aead));
111   size_t out_len;
112   if (!EVP_AEAD_CTX_seal(ctx.get(), out.data(), &out_len, out.size(), iv.data(),
113                          iv.size(), pt.data(), pt.size(), aad.data(),
114                          aad.size())) {
115     return false;
116   }
117   out.resize(out_len);
118 
119   ct->assign(out.begin(), out.end() - tag_len);
120   tag->assign(out.end() - tag_len, out.end());
121 
122   return true;
123 }
124 
AEADDecrypt(const EVP_AEAD * aead,std::vector<uint8_t> * pt,size_t pt_len,const std::vector<uint8_t> & key,const std::vector<uint8_t> & aad,const std::vector<uint8_t> & ct,const std::vector<uint8_t> & tag,const std::vector<uint8_t> & iv)125 bool AEADDecrypt(const EVP_AEAD *aead, std::vector<uint8_t> *pt, size_t pt_len,
126                  const std::vector<uint8_t> &key,
127                  const std::vector<uint8_t> &aad,
128                  const std::vector<uint8_t> &ct,
129                  const std::vector<uint8_t> &tag,
130                  const std::vector<uint8_t> &iv) {
131   bssl::ScopedEVP_AEAD_CTX ctx;
132   if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead, key.data(), key.size(),
133                                         tag.size(), evp_aead_open)) {
134     return false;
135   }
136   std::vector<uint8_t> in = ct;
137   in.reserve(ct.size() + tag.size());
138   in.insert(in.end(), tag.begin(), tag.end());
139 
140   pt->resize(pt_len);
141   size_t out_pt_len;
142   if (!EVP_AEAD_CTX_open(ctx.get(), pt->data(), &out_pt_len, pt->size(),
143                          iv.data(), iv.size(), in.data(), in.size(), aad.data(),
144                          aad.size()) ||
145       out_pt_len != pt_len) {
146     return false;
147   }
148   return true;
149 }
150 
HexToBIGNUM(bssl::UniquePtr<BIGNUM> * out,const char * in)151 static int HexToBIGNUM(bssl::UniquePtr<BIGNUM> *out, const char *in) {
152   BIGNUM *raw = NULL;
153   int ret = BN_hex2bn(&raw, in);
154   out->reset(raw);
155   return ret;
156 }
157 
GetBIGNUM(FileTest * t,const char * attribute)158 bssl::UniquePtr<BIGNUM> GetBIGNUM(FileTest *t, const char *attribute) {
159   std::string hex;
160   if (!t->GetAttribute(&hex, attribute)) {
161     return nullptr;
162   }
163 
164   bssl::UniquePtr<BIGNUM> ret;
165   if (HexToBIGNUM(&ret, hex.c_str()) != static_cast<int>(hex.size())) {
166     t->PrintLine("Could not decode '%s'.", hex.c_str());
167     return nullptr;
168   }
169   return ret;
170 }
171 
GetECGroupNIDFromInstruction(FileTest * t,const char ** out_str)172 int GetECGroupNIDFromInstruction(FileTest *t, const char **out_str) {
173   const char *dummy;
174   if (out_str == nullptr) {
175     out_str = &dummy;
176   }
177 
178   if (t->HasInstruction("P-224")) {
179     *out_str = "P-224";
180     return NID_secp224r1;
181   }
182   if (t->HasInstruction("P-256")) {
183     *out_str = "P-256";
184     return NID_X9_62_prime256v1;
185   }
186   if (t->HasInstruction("P-384")) {
187     *out_str = "P-384";
188     return NID_secp384r1;
189   }
190   if (t->HasInstruction("P-521")) {
191     *out_str = "P-521";
192     return NID_secp521r1;
193   }
194   t->PrintLine("No supported group specified.");
195   return NID_undef;
196 }
197 
GetDigestFromInstruction(FileTest * t)198 const EVP_MD *GetDigestFromInstruction(FileTest *t) {
199   if (t->HasInstruction("SHA-1")) {
200     return EVP_sha1();
201   }
202   if (t->HasInstruction("SHA-224")) {
203     return EVP_sha224();
204   }
205   if (t->HasInstruction("SHA-256")) {
206     return EVP_sha256();
207   }
208   if (t->HasInstruction("SHA-384")) {
209     return EVP_sha384();
210   }
211   if (t->HasInstruction("SHA-512")) {
212     return EVP_sha512();
213   }
214   t->PrintLine("No supported digest function specified.");
215   return nullptr;
216 }
217 
EchoComment(const std::string & comment)218 void EchoComment(const std::string& comment) {
219   fwrite(comment.c_str(), comment.size(), 1, stdout);
220 }
221