]>
Commit | Line | Data |
---|---|---|
103d40f7 MG |
1 | /* HomeMatic protocol-functions |
2 | * | |
3 | * Copyright (c) 2014-15 Michael Gernoth <michael@gernoth.net> | |
4 | * | |
5 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
6 | * of this software and associated documentation files (the "Software"), to | |
7 | * deal in the Software without restriction, including without limitation the | |
8 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | |
9 | * sell copies of the Software, and to permit persons to whom the Software is | |
10 | * furnished to do so, subject to the following conditions: | |
11 | * | |
12 | * The above copyright notice and this permission notice shall be included in | |
13 | * all copies or substantial portions of the Software. | |
14 | * | |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
21 | * IN THE SOFTWARE. | |
22 | */ | |
23 | ||
24 | #include <stdio.h> | |
25 | #include <stdlib.h> | |
26 | #include <unistd.h> | |
27 | #include <stdint.h> | |
28 | #include <string.h> | |
29 | #include <strings.h> | |
30 | #include <errno.h> | |
31 | #include <sys/types.h> | |
32 | #include <sys/time.h> | |
33 | ||
34 | #include "aes.h" | |
35 | #include "hexdump.h" | |
36 | #include "hm.h" | |
37 | ||
38 | static int debug = 0; | |
39 | ||
40 | uint8_t* hm_sign(uint8_t *key, uint8_t *challenge, uint8_t *m_frame, uint8_t *exp_auth, uint8_t *resp) | |
41 | { | |
42 | uint8_t signkey[16]; | |
43 | WORD ks[60]; | |
44 | struct timeval tv; | |
45 | int i; | |
46 | ||
47 | printf("AES-request with challenge: %02x%02x%02x%02x%02x%02x\n", | |
48 | challenge[0], challenge[1], challenge[2], | |
49 | challenge[3], challenge[4], challenge[5]); | |
50 | ||
51 | /* | |
52 | * Build signing key by XORing the first 6 bytes of | |
53 | * the key with the challenge. | |
54 | */ | |
55 | memcpy(signkey, key, sizeof(signkey)); | |
56 | for (i = 0; i < 6; i++) { | |
57 | signkey[i] ^= challenge[i]; | |
58 | } | |
59 | aes_key_setup(signkey, ks, 128); | |
60 | ||
61 | /* | |
62 | * Generate payload for first encryption. | |
63 | */ | |
64 | gettimeofday(&tv, NULL); | |
65 | resp[0] = tv.tv_sec >> 24 & 0xff; | |
66 | resp[1] = tv.tv_sec >> 16 & 0xff; | |
67 | resp[2] = tv.tv_sec >> 8 & 0xff; | |
68 | resp[3] = tv.tv_sec & 0xff; | |
69 | resp[4] = tv.tv_usec >> 8 & 0xff; | |
70 | resp[5] = tv.tv_usec & 0xff; | |
71 | memcpy(&(resp[6]), &(m_frame[MSGID]), 10); | |
72 | ||
73 | if (debug) | |
74 | hexdump(resp, 16, "P > "); | |
75 | ||
76 | aes_encrypt(resp, resp, ks, 128); | |
77 | ||
78 | if (debug) | |
79 | hexdump(resp, 16, "Pe > "); | |
80 | ||
81 | /* | |
82 | * Device has to answer with the first 4 bytes of the | |
83 | * encrypted payload to authenticate, so pass them to | |
84 | * the caller. | |
85 | */ | |
86 | ||
87 | if (exp_auth) { | |
88 | memcpy(exp_auth, resp, 4); | |
89 | } | |
90 | ||
91 | /* | |
92 | * XOR parameters of the m_frame to the payload. | |
93 | */ | |
94 | for (i = 0; i < PAYLOADLEN(m_frame) - 1; i++) { | |
95 | if (i == 16) { | |
96 | break; | |
97 | } | |
98 | ||
99 | resp[i] ^= m_frame[PAYLOAD + 1+ i]; | |
100 | } | |
101 | ||
102 | if (debug) | |
103 | hexdump(resp, 16, "Pe^ > "); | |
104 | ||
105 | /* | |
106 | * Encrypt payload again | |
107 | */ | |
108 | aes_encrypt(resp, resp, ks, 128); | |
109 | ||
110 | if (debug) | |
111 | hexdump(resp, 16, "Pe^e> "); | |
112 | ||
113 | return resp; | |
114 | } |