blob: 3a6c34dd6a96c00bbed56734913509bf45e02bd5 [file] [log] [blame]
Tom Joseph77531db2017-01-10 15:44:44 +05301#include <openssl/hmac.h>
2#include <openssl/sha.h>
3#include "integrity_algo.hpp"
4#include "message_parsers.hpp"
5
6namespace cipher
7{
8
9namespace integrity
10{
11
Vernon Mauery70fd29c2017-11-30 13:11:43 -080012Interface::Interface(const std::vector<uint8_t>& sik,
13 const Key& addKey, size_t authLength)
Tom Joseph77531db2017-01-10 15:44:44 +053014{
15 unsigned int mdLen = 0;
16
17 // Generated K1 for the integrity algorithm with the additional key keyed
18 // with SIK.
19 if (HMAC(EVP_sha1(), sik.data(), sik.size(), addKey.data(),
20 addKey.size(), K1.data(), &mdLen) == NULL)
21 {
22 throw std::runtime_error("Generating Key1 for integrity "
23 "algorithm failed");
24 }
25
26 authCodeLength = authLength;
27}
28
Vernon Mauery70fd29c2017-11-30 13:11:43 -080029std::vector<uint8_t> AlgoSHA1::generateHMAC(const uint8_t* input,
30 const size_t len) const
Tom Josephd212a6d2017-01-10 15:48:40 +053031{
Vernon Mauery70fd29c2017-11-30 13:11:43 -080032 std::vector<uint8_t> output(SHA_DIGEST_LENGTH);
Tom Josephd212a6d2017-01-10 15:48:40 +053033 unsigned int mdLen = 0;
34
35 if (HMAC(EVP_sha1(), K1.data(), K1.size(), input, len,
36 output.data(), &mdLen) == NULL)
37 {
38 throw std::runtime_error("Generating integrity data failed");
39 }
40
41 // HMAC generates Message Digest to the size of SHA_DIGEST_LENGTH, the
42 // AuthCode field length is based on the integrity algorithm. So we are
43 // interested only in the AuthCode field length of the generated Message
44 // digest.
45 output.resize(authCodeLength);
46
47 return output;
48}
49
Vernon Mauery70fd29c2017-11-30 13:11:43 -080050bool AlgoSHA1::verifyIntegrityData(
51 const std::vector<uint8_t>& packet,
52 const size_t length,
53 std::vector<uint8_t>::const_iterator integrityData) const
Tom Josephd212a6d2017-01-10 15:48:40 +053054{
55
56 auto output = generateHMAC(
57 packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE,
58 length);
59
60 // Verify if the generated integrity data for the packet and the received
61 // integrity data matches.
62 return (std::equal(output.begin(), output.end(), integrityData));
63}
64
Vernon Mauery70fd29c2017-11-30 13:11:43 -080065std::vector<uint8_t> AlgoSHA1::generateIntegrityData(
66 const std::vector<uint8_t>& packet) const
Tom Josephd212a6d2017-01-10 15:48:40 +053067{
68 return generateHMAC(
69 packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE,
70 packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE);
71}
72
Tom Joseph77531db2017-01-10 15:44:44 +053073}// namespace integrity
74
75}// namespace cipher