blob: 62c2653edb57ba254dced3e6805de55ab0543f22 [file] [log] [blame]
Vernon Mauery9b307be2017-11-22 09:28:16 -08001#include <openssl/evp.h>
Tom Joseph77531db2017-01-10 15:44:44 +05302#include <openssl/hmac.h>
3#include <openssl/sha.h>
4#include "integrity_algo.hpp"
5#include "message_parsers.hpp"
6
7namespace cipher
8{
9
10namespace integrity
11{
12
Vernon Mauery9b307be2017-11-22 09:28:16 -080013AlgoSHA1::AlgoSHA1(const std::vector<uint8_t>& sik)
14 : Interface(SHA1_96_AUTHCODE_LENGTH)
Tom Joseph77531db2017-01-10 15:44:44 +053015{
Vernon Mauery9b307be2017-11-22 09:28:16 -080016 k1 = generateKn(sik, rmcp::const_1);
Tom Joseph77531db2017-01-10 15:44:44 +053017}
18
Vernon Mauery70fd29c2017-11-30 13:11:43 -080019std::vector<uint8_t> AlgoSHA1::generateHMAC(const uint8_t* input,
20 const size_t len) const
Tom Josephd212a6d2017-01-10 15:48:40 +053021{
Vernon Mauery70fd29c2017-11-30 13:11:43 -080022 std::vector<uint8_t> output(SHA_DIGEST_LENGTH);
Tom Josephd212a6d2017-01-10 15:48:40 +053023 unsigned int mdLen = 0;
24
Vernon Mauery9b307be2017-11-22 09:28:16 -080025 if (HMAC(EVP_sha1(), k1.data(), k1.size(), input, len,
Tom Josephd212a6d2017-01-10 15:48:40 +053026 output.data(), &mdLen) == NULL)
27 {
28 throw std::runtime_error("Generating integrity data failed");
29 }
30
31 // HMAC generates Message Digest to the size of SHA_DIGEST_LENGTH, the
32 // AuthCode field length is based on the integrity algorithm. So we are
33 // interested only in the AuthCode field length of the generated Message
34 // digest.
35 output.resize(authCodeLength);
36
37 return output;
38}
39
Vernon Mauery70fd29c2017-11-30 13:11:43 -080040bool AlgoSHA1::verifyIntegrityData(
41 const std::vector<uint8_t>& packet,
42 const size_t length,
43 std::vector<uint8_t>::const_iterator integrityData) const
Tom Josephd212a6d2017-01-10 15:48:40 +053044{
45
46 auto output = generateHMAC(
47 packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE,
48 length);
49
50 // Verify if the generated integrity data for the packet and the received
51 // integrity data matches.
52 return (std::equal(output.begin(), output.end(), integrityData));
53}
54
Vernon Mauery70fd29c2017-11-30 13:11:43 -080055std::vector<uint8_t> AlgoSHA1::generateIntegrityData(
56 const std::vector<uint8_t>& packet) const
Tom Josephd212a6d2017-01-10 15:48:40 +053057{
58 return generateHMAC(
59 packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE,
60 packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE);
61}
62
Vernon Mauery9b307be2017-11-22 09:28:16 -080063std::vector<uint8_t> AlgoSHA1::generateKn(const std::vector<uint8_t>& sik,
64 const rmcp::Const_n& const_n) const
65{
66 unsigned int mdLen = 0;
67 std::vector<uint8_t> Kn(sik.size());
68
69 // Generated Kn for the integrity algorithm with the additional key keyed
70 // with SIK.
71 if (HMAC(EVP_sha1(), sik.data(), sik.size(), const_n.data(),
72 const_n.size(), Kn.data(), &mdLen) == NULL)
73 {
74 throw std::runtime_error("Generating KeyN for integrity "
75 "algorithm failed");
76 }
77 return Kn;
78}
79
Tom Joseph77531db2017-01-10 15:44:44 +053080}// namespace integrity
81
82}// namespace cipher