aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/byzantine-lab/mcl/include/cybozu/crypto.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/byzantine-lab/mcl/include/cybozu/crypto.hpp')
-rw-r--r--vendor/github.com/byzantine-lab/mcl/include/cybozu/crypto.hpp321
1 files changed, 321 insertions, 0 deletions
diff --git a/vendor/github.com/byzantine-lab/mcl/include/cybozu/crypto.hpp b/vendor/github.com/byzantine-lab/mcl/include/cybozu/crypto.hpp
new file mode 100644
index 000000000..d427179d9
--- /dev/null
+++ b/vendor/github.com/byzantine-lab/mcl/include/cybozu/crypto.hpp
@@ -0,0 +1,321 @@
+#pragma once
+/**
+ @file
+ @brief wrap openssl
+ @author MITSUNARI Shigeo(@herumi)
+*/
+
+#include <cybozu/exception.hpp>
+#ifdef __APPLE__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+#if 0 //#ifdef __APPLE__
+ #define COMMON_DIGEST_FOR_OPENSSL
+ #include <CommonCrypto/CommonDigest.h>
+ #include <CommonCrypto/CommonHMAC.h>
+ #define SHA1 CC_SHA1
+ #define SHA224 CC_SHA224
+ #define SHA256 CC_SHA256
+ #define SHA384 CC_SHA384
+ #define SHA512 CC_SHA512
+#else
+#include <openssl/hmac.h>
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+#endif
+#ifdef _MSC_VER
+ #include <cybozu/link_libeay32.hpp>
+#endif
+
+namespace cybozu {
+
+namespace crypto {
+
+class Hash {
+public:
+ enum Name {
+ N_SHA1,
+ N_SHA224,
+ N_SHA256,
+ N_SHA384,
+ N_SHA512
+ };
+private:
+ Name name_;
+ size_t hashSize_;
+ union {
+ SHA_CTX sha1;
+ SHA256_CTX sha256;
+ SHA512_CTX sha512;
+ } ctx_;
+public:
+ static inline size_t getSize(Name name)
+ {
+ switch (name) {
+ case N_SHA1: return SHA_DIGEST_LENGTH;
+ case N_SHA224: return SHA224_DIGEST_LENGTH;
+ case N_SHA256: return SHA256_DIGEST_LENGTH;
+ case N_SHA384: return SHA384_DIGEST_LENGTH;
+ case N_SHA512: return SHA512_DIGEST_LENGTH;
+ default:
+ throw cybozu::Exception("crypto:Hash:getSize") << name;
+ }
+ }
+ static inline const char *getName(Name name)
+ {
+ switch (name) {
+ case N_SHA1: return "sha1";
+ case N_SHA224: return "sha224";
+ case N_SHA256: return "sha256";
+ case N_SHA384: return "sha384";
+ case N_SHA512: return "sha512";
+ default:
+ throw cybozu::Exception("crypto:Hash:getName") << name;
+ }
+ }
+ static inline Name getName(const std::string& nameStr)
+ {
+ static const struct {
+ const char *nameStr;
+ Name name;
+ } tbl[] = {
+ { "sha1", N_SHA1 },
+ { "sha224", N_SHA224 },
+ { "sha256", N_SHA256 },
+ { "sha384", N_SHA384 },
+ { "sha512", N_SHA512 },
+ };
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
+ if (nameStr == tbl[i].nameStr) return tbl[i].name;
+ }
+ throw cybozu::Exception("crypto:Hash:getName") << nameStr;
+ }
+ explicit Hash(Name name = N_SHA1)
+ : name_(name)
+ , hashSize_(getSize(name))
+ {
+ reset();
+ }
+ void update(const void *buf, size_t bufSize)
+ {
+ switch (name_) {
+ case N_SHA1: SHA1_Update(&ctx_.sha1, buf, bufSize); break;
+ case N_SHA224: SHA224_Update(&ctx_.sha256, buf, bufSize); break;
+ case N_SHA256: SHA256_Update(&ctx_.sha256, buf, bufSize); break;
+ case N_SHA384: SHA384_Update(&ctx_.sha512, buf, bufSize); break;
+ case N_SHA512: SHA512_Update(&ctx_.sha512, buf, bufSize); break;
+ }
+ }
+ void update(const std::string& buf)
+ {
+ update(buf.c_str(), buf.size());
+ }
+ void reset()
+ {
+ switch (name_) {
+ case N_SHA1: SHA1_Init(&ctx_.sha1); break;
+ case N_SHA224: SHA224_Init(&ctx_.sha256); break;
+ case N_SHA256: SHA256_Init(&ctx_.sha256); break;
+ case N_SHA384: SHA384_Init(&ctx_.sha512); break;
+ case N_SHA512: SHA512_Init(&ctx_.sha512); break;
+ default:
+ throw cybozu::Exception("crypto:Hash:rset") << name_;
+ }
+ }
+ /*
+ md must have hashSize byte
+ @note clear inner buffer after calling digest
+ */
+ void digest(void *out, const void *buf, size_t bufSize)
+ {
+ update(buf, bufSize);
+ unsigned char *md = reinterpret_cast<unsigned char*>(out);
+ switch (name_) {
+ case N_SHA1: SHA1_Final(md, &ctx_.sha1); break;
+ case N_SHA224: SHA224_Final(md, &ctx_.sha256); break;
+ case N_SHA256: SHA256_Final(md, &ctx_.sha256); break;
+ case N_SHA384: SHA384_Final(md, &ctx_.sha512); break;
+ case N_SHA512: SHA512_Final(md, &ctx_.sha512); break;
+ default:
+ throw cybozu::Exception("crypto:Hash:digest") << name_;
+ }
+ reset();
+ }
+ std::string digest(const void *buf, size_t bufSize)
+ {
+ std::string ret;
+ ret.resize(hashSize_);
+ digest(&ret[0], buf, bufSize);
+ return ret;
+ }
+ std::string digest(const std::string& buf = "")
+ {
+ return digest(buf.c_str(), buf.size());
+ }
+ /*
+ out must have necessary size
+ @note return written size
+ */
+ static inline size_t digest(void *out, Name name, const void *buf, size_t bufSize)
+ {
+ unsigned char *md = (unsigned char*)out;
+ const unsigned char *src = cybozu::cast<const unsigned char *>(buf);
+ switch (name) {
+ case N_SHA1: SHA1(src, bufSize, md); return 160 / 8;
+ case N_SHA224: SHA224(src, bufSize, md); return 224 / 8;
+ case N_SHA256: SHA256(src, bufSize, md); return 256 / 8;
+ case N_SHA384: SHA384(src, bufSize, md); return 384 / 8;
+ case N_SHA512: SHA512(src, bufSize, md); return 512 / 8;
+ default:
+ return 0;
+ }
+ }
+ static inline std::string digest(Name name, const void *buf, size_t bufSize)
+ {
+ char md[128];
+ size_t size = digest(md, name, buf, bufSize);
+ if (size == 0) throw cybozu::Exception("crypt:Hash:digest") << name;
+ return std::string(md, size);
+ }
+ static inline std::string digest(Name name, const std::string& buf)
+ {
+ return digest(name, buf.c_str(), buf.size());
+ }
+};
+
+class Hmac {
+ const EVP_MD *evp_;
+public:
+ explicit Hmac(Hash::Name name = Hash::N_SHA1)
+ {
+ switch (name) {
+ case Hash::N_SHA1: evp_ = EVP_sha1(); break;
+ case Hash::N_SHA224: evp_ = EVP_sha224(); break;
+ case Hash::N_SHA256: evp_ = EVP_sha256(); break;
+ case Hash::N_SHA384: evp_ = EVP_sha384(); break;
+ case Hash::N_SHA512: evp_ = EVP_sha512(); break;
+ default:
+ throw cybozu::Exception("crypto:Hmac:") << name;
+ }
+ }
+ std::string eval(const std::string& key, const std::string& data)
+ {
+ std::string out(EVP_MD_size(evp_) + 1, 0);
+ unsigned int outLen = 0;
+ if (HMAC(evp_, key.c_str(), static_cast<int>(key.size()),
+ cybozu::cast<const uint8_t *>(data.c_str()), data.size(), cybozu::cast<uint8_t *>(&out[0]), &outLen)) {
+ out.resize(outLen);
+ return out;
+ }
+ throw cybozu::Exception("crypto::Hamc::eval");
+ }
+};
+
+class Cipher {
+ const EVP_CIPHER *cipher_;
+ EVP_CIPHER_CTX *ctx_;
+public:
+ enum Name {
+ N_AES128_CBC,
+ N_AES192_CBC,
+ N_AES256_CBC,
+ N_AES128_ECB, // be carefull to use
+ N_AES192_ECB, // be carefull to use
+ N_AES256_ECB, // be carefull to use
+ };
+ static inline size_t getSize(Name name)
+ {
+ switch (name) {
+ case N_AES128_CBC: return 128;
+ case N_AES192_CBC: return 192;
+ case N_AES256_CBC: return 256;
+ case N_AES128_ECB: return 128;
+ case N_AES192_ECB: return 192;
+ case N_AES256_ECB: return 256;
+ default:
+ throw cybozu::Exception("crypto:Cipher:getSize") << name;
+ }
+ }
+ enum Mode {
+ Decoding,
+ Encoding
+ };
+ explicit Cipher(Name name = N_AES128_CBC)
+ : cipher_(0)
+ , ctx_(0)
+ {
+ ctx_ = EVP_CIPHER_CTX_new();
+ if (ctx_ == 0) throw cybozu::Exception("crypto:Cipher:EVP_CIPHER_CTX_new");
+ switch (name) {
+ case N_AES128_CBC: cipher_ = EVP_aes_128_cbc(); break;
+ case N_AES192_CBC: cipher_ = EVP_aes_192_cbc(); break;
+ case N_AES256_CBC: cipher_ = EVP_aes_256_cbc(); break;
+ case N_AES128_ECB: cipher_ = EVP_aes_128_ecb(); break;
+ case N_AES192_ECB: cipher_ = EVP_aes_192_ecb(); break;
+ case N_AES256_ECB: cipher_ = EVP_aes_256_ecb(); break;
+ default:
+ throw cybozu::Exception("crypto:Cipher:Cipher:name") << (int)name;
+ }
+ }
+ ~Cipher()
+ {
+ if (ctx_) EVP_CIPHER_CTX_free(ctx_);
+ }
+ /*
+ @note don't use padding = true
+ */
+ void setup(Mode mode, const std::string& key, const std::string& iv, bool padding = false)
+ {
+ const int keyLen = static_cast<int>(key.size());
+ const int expectedKeyLen = EVP_CIPHER_key_length(cipher_);
+ if (keyLen != expectedKeyLen) {
+ throw cybozu::Exception("crypto:Cipher:setup:keyLen") << keyLen << expectedKeyLen;
+ }
+
+ int ret = EVP_CipherInit_ex(ctx_, cipher_, NULL, cybozu::cast<const uint8_t*>(key.c_str()), cybozu::cast<const uint8_t*>(iv.c_str()), mode == Encoding ? 1 : 0);
+ if (ret != 1) {
+ throw cybozu::Exception("crypto:Cipher:setup:EVP_CipherInit_ex") << ret;
+ }
+ ret = EVP_CIPHER_CTX_set_padding(ctx_, padding ? 1 : 0);
+ if (ret != 1) {
+ throw cybozu::Exception("crypto:Cipher:setup:EVP_CIPHER_CTX_set_padding") << ret;
+ }
+/*
+ const int ivLen = static_cast<int>(iv.size());
+ const int expectedIvLen = EVP_CIPHER_CTX_iv_length(&ctx_);
+ if (ivLen != expectedIvLen) {
+ throw cybozu::Exception("crypto:Cipher:setup:ivLen") << ivLen << expectedIvLen;
+ }
+*/
+ }
+ /*
+ the size of outBuf must be larger than inBufSize + blockSize
+ @retval positive or 0 : writeSize(+blockSize)
+ @retval -1 : error
+ */
+ int update(char *outBuf, const char *inBuf, int inBufSize)
+ {
+ int outLen = 0;
+ int ret = EVP_CipherUpdate(ctx_, cybozu::cast<uint8_t*>(outBuf), &outLen, cybozu::cast<const uint8_t*>(inBuf), inBufSize);
+ if (ret != 1) return -1;
+ return outLen;
+ }
+ /*
+ return -1 if padding
+ @note don't use
+ */
+ int finalize(char *outBuf)
+ {
+ int outLen = 0;
+ int ret = EVP_CipherFinal_ex(ctx_, cybozu::cast<uint8_t*>(outBuf), &outLen);
+ if (ret != 1) return -1;
+ return outLen;
+ }
+};
+
+} } // cybozu::crypto
+
+#ifdef __APPLE__
+ #pragma GCC diagnostic pop
+#endif