154 lines
4.9 KiB
C++
154 lines
4.9 KiB
C++
/*
|
|
PIP - Platform Independent Primitives
|
|
Digest algorithms
|
|
Ivan Pelipenko peri4ko@yandex.ru
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "pidigest.h"
|
|
|
|
#include "pidigest_blake2_p.h"
|
|
#include "pidigest_md2_p.h"
|
|
#include "pidigest_md4_p.h"
|
|
#include "pidigest_md5_p.h"
|
|
#include "pidigest_sha1_p.h"
|
|
#include "pidigest_sha2_p.h"
|
|
|
|
|
|
int PIDigest::hashLength(Type type) {
|
|
switch (type) {
|
|
case Type::MD2: return 16;
|
|
case Type::MD4: return 16;
|
|
case Type::MD5: return 16;
|
|
case Type::SHA1: return 20;
|
|
case Type::SHA2_224: return 28;
|
|
case Type::SHA2_256: return 32;
|
|
case Type::SHA2_384: return 48;
|
|
case Type::SHA2_512: return 64;
|
|
case Type::SHA2_512_224: return 28;
|
|
case Type::SHA2_512_256: return 32;
|
|
case Type::BLAKE2s_128: return 16;
|
|
case Type::BLAKE2s_160: return 20;
|
|
case Type::BLAKE2s_224: return 28;
|
|
case Type::BLAKE2s_256: return 32;
|
|
case Type::BLAKE2b_128: return 16;
|
|
case Type::BLAKE2b_160: return 20;
|
|
case Type::BLAKE2b_224: return 28;
|
|
case Type::BLAKE2b_256: return 32;
|
|
case Type::BLAKE2b_384: return 48;
|
|
case Type::BLAKE2b_512: return 64;
|
|
default: break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int PIDigest::blockLength(Type type) {
|
|
switch (type) {
|
|
case Type::MD2: return 16;
|
|
case Type::MD4:
|
|
case Type::MD5: return 64;
|
|
case Type::SHA1: return 64;
|
|
case Type::SHA2_224:
|
|
case Type::SHA2_256: return 64;
|
|
case Type::SHA2_384:
|
|
case Type::SHA2_512:
|
|
case Type::SHA2_512_224:
|
|
case Type::SHA2_512_256: return 128;
|
|
case Type::BLAKE2s_128:
|
|
case Type::BLAKE2s_160:
|
|
case Type::BLAKE2s_224:
|
|
case Type::BLAKE2s_256: return 64;
|
|
case Type::BLAKE2b_128:
|
|
case Type::BLAKE2b_160:
|
|
case Type::BLAKE2b_224:
|
|
case Type::BLAKE2b_256:
|
|
case Type::BLAKE2b_384:
|
|
case Type::BLAKE2b_512: return 128;
|
|
default: break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
PIConstChars PIDigest::typeName(Type type) {
|
|
switch (type) {
|
|
case Type::MD2: return "MD2";
|
|
case Type::MD4: return "MD4";
|
|
case Type::MD5: return "MD5";
|
|
case Type::SHA1: return "SHA1";
|
|
case Type::SHA2_224: return "SHA2_224";
|
|
case Type::SHA2_256: return "SHA2_256";
|
|
case Type::SHA2_384: return "SHA2_384";
|
|
case Type::SHA2_512: return "SHA2_512";
|
|
case Type::SHA2_512_224: return "SHA2_512_224";
|
|
case Type::SHA2_512_256: return "SHA2_512_256";
|
|
case Type::BLAKE2s_128: return "BLAKE2s_128";
|
|
case Type::BLAKE2s_160: return "BLAKE2s_160";
|
|
case Type::BLAKE2s_224: return "BLAKE2s_224";
|
|
case Type::BLAKE2s_256: return "BLAKE2s_256";
|
|
case Type::BLAKE2b_128: return "BLAKE2b_128";
|
|
case Type::BLAKE2b_160: return "BLAKE2b_160";
|
|
case Type::BLAKE2b_224: return "BLAKE2b_224";
|
|
case Type::BLAKE2b_256: return "BLAKE2b_256";
|
|
case Type::BLAKE2b_384: return "BLAKE2b_384";
|
|
case Type::BLAKE2b_512: return "BLAKE2b_512";
|
|
default: break;
|
|
}
|
|
return "Unknown";
|
|
}
|
|
|
|
|
|
PIByteArray PIDigest::calculate(const PIByteArray & msg, Type type) {
|
|
switch (type) {
|
|
case Type::MD2: return MD2::md2(msg);
|
|
case Type::MD4: return MD4::md4(msg);
|
|
case Type::MD5: return MD5::md5(msg);
|
|
case Type::SHA1: return SHA1::sha1(msg);
|
|
case Type::SHA2_224: return SHA2::sha2xx(msg, SHA2::initial_224, 28);
|
|
case Type::SHA2_256: return SHA2::sha2xx(msg, SHA2::initial_256, 32);
|
|
case Type::SHA2_384: return SHA2::sha5xx(msg, SHA2::initial_384, 48);
|
|
case Type::SHA2_512: return SHA2::sha5xx(msg, SHA2::initial_512, 64);
|
|
case Type::SHA2_512_224: return SHA2::sha5xx(msg, SHA2::initial_512_224, 28);
|
|
case Type::SHA2_512_256: return SHA2::sha5xx(msg, SHA2::initial_512_256, 32);
|
|
case Type::BLAKE2s_128: return BLAKE2::blake2s(msg, 16);
|
|
case Type::BLAKE2s_160: return BLAKE2::blake2s(msg, 20);
|
|
case Type::BLAKE2s_224: return BLAKE2::blake2s(msg, 28);
|
|
case Type::BLAKE2s_256: return BLAKE2::blake2s(msg, 32);
|
|
case Type::BLAKE2b_128: return BLAKE2::blake2b(msg, 16);
|
|
case Type::BLAKE2b_160: return BLAKE2::blake2b(msg, 20);
|
|
case Type::BLAKE2b_224: return BLAKE2::blake2b(msg, 28);
|
|
case Type::BLAKE2b_256: return BLAKE2::blake2b(msg, 32);
|
|
case Type::BLAKE2b_384: return BLAKE2::blake2b(msg, 48);
|
|
case Type::BLAKE2b_512: return BLAKE2::blake2b(msg, 64);
|
|
default: break;
|
|
}
|
|
return {};
|
|
}
|
|
|
|
|
|
PIByteArray PIDigest::HMAC(const PIByteArray & msg, const PIByteArray & key, Type type) {
|
|
int b = PIDigest::blockLength(type);
|
|
auto ipad = PIByteArray(b, uchar(0x36));
|
|
auto opad = PIByteArray(b, uchar(0x5C));
|
|
PIByteArray k0;
|
|
if (key.size_s() > b)
|
|
k0 = PIDigest::calculate(key, type);
|
|
else
|
|
k0 = key;
|
|
k0.resize(b);
|
|
return PIDigest::calculate((k0 ^ opad).append(PIDigest::calculate((k0 ^ ipad).append(msg), type)), type);
|
|
}
|