blob: d718f24933b0cfb1922aed056af3c083ae5ab754 [file] [log] [blame]
Alexandre Lision51140e12013-12-02 10:54:09 -05001/*
2 Copyright (C) 2006, 2009 by Werner Dittmann
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18 * In addition, as a special exception, the copyright holders give
19 * permission to link the code of portions of this program with the
20 * OpenSSL library under certain conditions as described in each
21 * individual source file, and distribute linked combinations
22 * including the two.
23 * You must obey the GNU General Public License in all respects
24 * for all of the code used other than OpenSSL. If you modify
25 * file(s) with this exception, you may extend this exception to your
26 * version of the file(s), but you are not obligated to do so. If you
27 * do not wish to do so, delete this exception statement from your
28 * version. If you delete this exception statement from all source
29 * files in the program, then also delete it here.
30 */
31
32/** Copyright (C) 2006, 2009
33 *
34 * @author Werner Dittmann <Werner.Dittmann@t-online.de>
35 */
36
37#include <string.h>
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050038#include <sys/types.h>
39#include <sys/stat.h>
40#include <fcntl.h>
Alexandre Lision51140e12013-12-02 10:54:09 -050041
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050042#include <bn.h>
43#include <bnprint.h>
44#include <ec/ec.h>
45#include <ec/ecdh.h>
46#include <zrtp/crypto/zrtpDH.h>
47#include <zrtp/libzrtpcpp/ZrtpTextData.h>
48#include <cryptcommon/aes.h>
49#include <cryptcommon/ZrtpRandom.h>
Alexandre Lision51140e12013-12-02 10:54:09 -050050
Alexandre Lision51140e12013-12-02 10:54:09 -050051
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050052static BigNum bnP2048 = {0};
53static BigNum bnP3072 = {0};
Alexandre Lision51140e12013-12-02 10:54:09 -050054
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050055static BigNum bnP2048MinusOne = {0};
56static BigNum bnP3072MinusOne = {0};
Alexandre Lision51140e12013-12-02 10:54:09 -050057
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050058static BigNum two = {0};
Alexandre Lision51140e12013-12-02 10:54:09 -050059
60static uint8_t dhinit = 0;
61
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050062typedef struct _dhCtx {
63 BigNum privKey;
64 BigNum pubKey;
65 EcCurve curve;
66 EcPoint pubPoint;
67} dhCtx;
68
Alexandre Lision51140e12013-12-02 10:54:09 -050069void randomZRTP(uint8_t *buf, int32_t length)
70{
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050071 ZrtpRandom::getRandomData(buf, length);
Alexandre Lision51140e12013-12-02 10:54:09 -050072}
73
74static const uint8_t P2048[] =
75{
76 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
77 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
78 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
79 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
80 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
81 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
82 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
83 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
84 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
85 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
86 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
87 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
88 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
89 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
90 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
91 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
92 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
93 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
94 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
95 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
96 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF,
97 0xFF, 0xFF, 0xFF, 0xFF
98};
99
100static const uint8_t P3072[] =
101{
102 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
103 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
104 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
105 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
106 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
107 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
108 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
109 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
110 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
111 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
112 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
113 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
114 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
115 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
116 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
117 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
118 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
119 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
120 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
121 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
122 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
123 0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
124 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
125 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
126 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
127 0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
128 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
129 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
130 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
131 0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
132 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
133 0xA9, 0x3A, 0xD2, 0xCA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
134};
135
136/* **************
137static const uint8_t P4096[] =
138{
1390xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
1400x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
1410x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
1420x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
1430xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
1440xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
1450xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
1460xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
1470xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
1480x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
1490xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
1500x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
1510x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
1520x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
1530x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
1540xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
1550xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
1560xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
1570xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
1580xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
1590x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
1600x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
1610xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
1620x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
1630xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
1640x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
1650xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
1660x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
1670xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
1680xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
1690x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
1700xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
1710x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
1720x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
1730x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
1740x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
1750x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
1760xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
1770x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
1780x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
1790x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
1800x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
1810xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
182};
183*************** */
184
185ZrtpDH::ZrtpDH(const char* type) {
186
187 uint8_t random[64];
188
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500189 ctx = static_cast<void*>(new dhCtx);
190 dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
191
Alexandre Lision51140e12013-12-02 10:54:09 -0500192 // Well - the algo type is only 4 char thus cast to int32 and compare
193 if (*(int32_t*)type == *(int32_t*)dh2k) {
194 pkType = DH2K;
195 }
196 else if (*(int32_t*)type == *(int32_t*)dh3k) {
197 pkType = DH3K;
198 }
199 else if (*(int32_t*)type == *(int32_t*)ec25) {
200 pkType = EC25;
201 }
202 else if (*(int32_t*)type == *(int32_t*)ec38) {
203 pkType = EC38;
204 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500205 else if (*(int32_t*)type == *(int32_t*)e255) {
206 pkType = E255;
207 }
208 else if (*(int32_t*)type == *(int32_t*)e414) {
209 pkType = E414;
210 }
Alexandre Lision51140e12013-12-02 10:54:09 -0500211 else {
212 return;
213 }
214
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500215 randomZRTP(random, sizeof(random));
Alexandre Lision51140e12013-12-02 10:54:09 -0500216
217 if (!dhinit) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500218 bnBegin(&two);
219 bnSetQ(&two, 2);
Alexandre Lision51140e12013-12-02 10:54:09 -0500220
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500221 bnBegin(&bnP2048);
222 bnInsertBigBytes(&bnP2048, P2048, 0, sizeof(P2048));
223 bnBegin(&bnP3072);
224 bnInsertBigBytes(&bnP3072, P3072, 0, sizeof(P3072));
Alexandre Lision51140e12013-12-02 10:54:09 -0500225
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500226 bnBegin(&bnP2048MinusOne);
227 bnCopy(&bnP2048MinusOne, &bnP2048);
228 bnSubQ(&bnP2048MinusOne, 1);
Alexandre Lision51140e12013-12-02 10:54:09 -0500229
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500230 bnBegin(&bnP3072MinusOne);
231 bnCopy(&bnP3072MinusOne, &bnP3072);
232 bnSubQ(&bnP3072MinusOne, 1);
233
Alexandre Lision51140e12013-12-02 10:54:09 -0500234 dhinit = 1;
235 }
236
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500237 bnBegin(&tmpCtx->privKey);
238 INIT_EC_POINT(&tmpCtx->pubPoint);
239
Alexandre Lision51140e12013-12-02 10:54:09 -0500240 switch (pkType) {
241 case DH2K:
242 case DH3K:
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500243 bnInsertBigBytes(&tmpCtx->privKey, random, 0, 256/8);
Alexandre Lision51140e12013-12-02 10:54:09 -0500244 break;
245
246 case EC25:
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500247 ecGetCurveNistECp(NIST256P, &tmpCtx->curve);
248 ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
Alexandre Lision51140e12013-12-02 10:54:09 -0500249 break;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500250
Alexandre Lision51140e12013-12-02 10:54:09 -0500251 case EC38:
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500252 ecGetCurveNistECp(NIST384P, &tmpCtx->curve);
253 ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
254 break;
255
256 case E255:
257 ecGetCurvesCurve(Curve25519, &tmpCtx->curve);
258 ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
259 break;
260
261 case E414:
262 ecGetCurvesCurve(Curve3617, &tmpCtx->curve);
263 ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
Alexandre Lision51140e12013-12-02 10:54:09 -0500264 break;
265 }
266}
267
268ZrtpDH::~ZrtpDH() {
269 if (ctx == NULL)
270 return;
271
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500272 dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
273 FREE_EC_POINT(&tmpCtx->pubPoint);
274 bnEnd(&tmpCtx->privKey);
275
Alexandre Lision51140e12013-12-02 10:54:09 -0500276 switch (pkType) {
277 case DH2K:
278 case DH3K:
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500279 bnEnd(&tmpCtx->pubKey);
Alexandre Lision51140e12013-12-02 10:54:09 -0500280 break;
281
282 case EC25:
283 case EC38:
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500284 ecFreeCurveNistECp(&tmpCtx->curve);
285 break;
286
287 case E255:
288 case E414:
289 ecFreeCurvesCurve(&tmpCtx->curve);
Alexandre Lision51140e12013-12-02 10:54:09 -0500290 break;
291 }
292}
293
294int32_t ZrtpDH::computeSecretKey(uint8_t *pubKeyBytes, uint8_t *secret) {
295
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500296 dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
297
298 int32_t length = getDhSize();
299
300 BigNum sec;
Alexandre Lision51140e12013-12-02 10:54:09 -0500301 if (pkType == DH2K || pkType == DH3K) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500302 BigNum pubKeyOther;
303 bnBegin(&pubKeyOther);
304 bnBegin(&sec);
Alexandre Lision51140e12013-12-02 10:54:09 -0500305
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500306 bnInsertBigBytes(&pubKeyOther, pubKeyBytes, 0, length);
307
308 if (pkType == DH2K) {
309 bnExpMod(&sec, &pubKeyOther, &tmpCtx->privKey, &bnP2048);
Alexandre Lision51140e12013-12-02 10:54:09 -0500310 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500311 else if (pkType == DH3K) {
312 bnExpMod(&sec, &pubKeyOther, &tmpCtx->privKey, &bnP3072);
313 }
314 else {
315 return 0;
316 }
317 bnEnd(&pubKeyOther);
318 bnExtractBigBytes(&sec, secret, 0, length);
319 bnEnd(&sec);
Alexandre Lision51140e12013-12-02 10:54:09 -0500320
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500321 return length;
322 }
323
324 if (pkType == EC25 || pkType == EC38 || pkType == E414) {
325 int32_t len = getPubKeySize() / 2;
326 EcPoint pub;
327
328 bnBegin(&sec);
329 INIT_EC_POINT(&pub);
330 bnSetQ(pub.z, 1); // initialze Z to one, these are affine coords
331
332 bnInsertBigBytes(pub.x, pubKeyBytes, 0, len);
333 bnInsertBigBytes(pub.y, pubKeyBytes+len, 0, len);
334
335 /* Generate agreement for responder: sec = pub * privKey */
336 ecdhComputeAgreement(&tmpCtx->curve, &sec, &pub, &tmpCtx->privKey);
337 bnExtractBigBytes(&sec, secret, 0, length);
338 bnEnd(&sec);
339 FREE_EC_POINT(&pub);
340
341 return length;
342 }
343 if (pkType == E255) {
344 int32_t len = getPubKeySize();
345 EcPoint pub;
346
347 bnBegin(&sec);
348 INIT_EC_POINT(&pub);
349
350 bnInsertLittleBytes(pub.x, pubKeyBytes, 0, len);
351
352 /* Generate agreement for responder: sec = pub * privKey */
353 ecdhComputeAgreement(&tmpCtx->curve, &sec, &pub, &tmpCtx->privKey);
354 bnExtractLittleBytes(&sec, secret, 0, length);
355 bnEnd(&sec);
356 FREE_EC_POINT(&pub);
357
358 return length;
Alexandre Lision51140e12013-12-02 10:54:09 -0500359 }
360 return -1;
361}
362
363int32_t ZrtpDH::generatePublicKey()
364{
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500365 dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
Alexandre Lision51140e12013-12-02 10:54:09 -0500366
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500367 bnBegin(&tmpCtx->pubKey);
368 switch (pkType) {
369 case DH2K:
370 bnExpMod(&tmpCtx->pubKey, &two, &tmpCtx->privKey, &bnP2048);
371 break;
372
373 case DH3K:
374 bnExpMod(&tmpCtx->pubKey, &two, &tmpCtx->privKey, &bnP3072);
375 break;
376
377 case EC25:
378 case EC38:
379 case E255:
380 case E414:
381 while (!ecdhGeneratePublic(&tmpCtx->curve, &tmpCtx->pubPoint, &tmpCtx->privKey))
382 ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
383 }
Alexandre Lision51140e12013-12-02 10:54:09 -0500384 return 0;
385}
386
387int32_t ZrtpDH::getDhSize() const
388{
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500389 switch (pkType) {
390 case DH2K:
391 return 2048/8;
392 break;
393 case DH3K:
394 return 3072/8;
395 break;
Alexandre Lision51140e12013-12-02 10:54:09 -0500396
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500397 case EC25:
Alexandre Lision51140e12013-12-02 10:54:09 -0500398 return 32;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500399 break;
400 case EC38:
Alexandre Lision51140e12013-12-02 10:54:09 -0500401 return 48;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500402 break;
Alexandre Lision51140e12013-12-02 10:54:09 -0500403
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500404 case E255:
405 return 32;
406 break;
407 case E414:
408 return 52;
409 break;
410 }
Alexandre Lision51140e12013-12-02 10:54:09 -0500411 return 0;
412}
413
414int32_t ZrtpDH::getPubKeySize() const
415{
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500416 dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
Alexandre Lision51140e12013-12-02 10:54:09 -0500417 if (pkType == DH2K || pkType == DH3K)
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500418 return bnBytes(&tmpCtx->pubKey);
Alexandre Lision51140e12013-12-02 10:54:09 -0500419
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500420 if (pkType == EC25 || pkType == EC38 || pkType == E414)
421 return bnBytes(tmpCtx->curve.p) * 2; // *2 -> x and y coordinate
422
423 if (pkType == E255)
424 return bnBytes(tmpCtx->curve.p);
Alexandre Lision51140e12013-12-02 10:54:09 -0500425 return 0;
426
427}
428
429int32_t ZrtpDH::getPubKeyBytes(uint8_t *buf) const
430{
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500431 dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
Alexandre Lision51140e12013-12-02 10:54:09 -0500432
433 if (pkType == DH2K || pkType == DH3K) {
434 // get len of pub_key, prepend with zeros to DH size
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500435 int size = getPubKeySize();
436 int32_t prepend = getDhSize() - size;
Alexandre Lision51140e12013-12-02 10:54:09 -0500437 if (prepend > 0) {
438 memset(buf, 0, prepend);
439 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500440 bnExtractBigBytes(&tmpCtx->pubKey, buf + prepend, 0, size);
441 return size;
Alexandre Lision51140e12013-12-02 10:54:09 -0500442 }
Alexandre Lision51140e12013-12-02 10:54:09 -0500443
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500444 if (pkType == EC25 || pkType == EC38 || pkType == E414) {
445 int32_t len = getPubKeySize() / 2;
446
447 bnExtractBigBytes(tmpCtx->pubPoint.x, buf, 0, len);
448 bnExtractBigBytes(tmpCtx->pubPoint.y, buf+len, 0, len);
449 return len * 2;
450 }
451 if (pkType == E255) {
452 int32_t len = getPubKeySize();
453 bnExtractLittleBytes(tmpCtx->pubPoint.x, buf, 0, len);
454 return len;
Alexandre Lision51140e12013-12-02 10:54:09 -0500455 }
456 return 0;
457}
458
459int32_t ZrtpDH::checkPubKey(uint8_t *pubKeyBytes) const
460{
Alexandre Lision51140e12013-12-02 10:54:09 -0500461
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500462 /* ECC validation (partial), NIST SP800-56A, section 5.6.2.6 */
463 if (pkType == EC25 || pkType == EC38 || pkType == E414) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500464
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500465 dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
466 EcPoint pub;
Alexandre Lision51140e12013-12-02 10:54:09 -0500467
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500468 INIT_EC_POINT(&pub);
469 int32_t len = getPubKeySize() / 2;
470
471 bnInsertBigBytes(pub.x, pubKeyBytes, 0, len);
472 bnInsertBigBytes(pub.y, pubKeyBytes+len, 0, len);
473
474 return ecCheckPubKey(&tmpCtx->curve, &pub);
Alexandre Lision51140e12013-12-02 10:54:09 -0500475 }
476
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500477 if (pkType == E255) {
478 return 1;
479 }
480
481 BigNum pubKeyOther;
482 bnBegin(&pubKeyOther);
483 bnInsertBigBytes(&pubKeyOther, pubKeyBytes, 0, getDhSize());
Alexandre Lision51140e12013-12-02 10:54:09 -0500484
485 if (pkType == DH2K) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500486 if (bnCmp(&bnP2048MinusOne, &pubKeyOther) == 0) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500487 return 0;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500488 }
Alexandre Lision51140e12013-12-02 10:54:09 -0500489 }
490 else if (pkType == DH3K) {
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500491 if (bnCmp(&bnP3072MinusOne, &pubKeyOther) == 0) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500492 return 0;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500493
494 }
Alexandre Lision51140e12013-12-02 10:54:09 -0500495 }
496 else {
Alexandre Lision51140e12013-12-02 10:54:09 -0500497 return 0;
498 }
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500499 if (bnCmpQ(&pubKeyOther, 1) == 0) {
Alexandre Lision51140e12013-12-02 10:54:09 -0500500 return 0;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500501 }
Alexandre Lision51140e12013-12-02 10:54:09 -0500502
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500503 bnEnd(&pubKeyOther);
Alexandre Lision51140e12013-12-02 10:54:09 -0500504 return 1;
505}
506
507const char* ZrtpDH::getDHtype()
508{
509 switch (pkType) {
510 case DH2K:
511 return dh2k;
Alexandre Lision51140e12013-12-02 10:54:09 -0500512 case DH3K:
513 return dh3k;
Alexandre Lision51140e12013-12-02 10:54:09 -0500514 case EC25:
515 return ec25;
Alexandre Lision51140e12013-12-02 10:54:09 -0500516 case EC38:
517 return ec38;
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -0500518 case E255:
519 return e255;
520 case E414:
521 return e414;
Alexandre Lision51140e12013-12-02 10:54:09 -0500522 }
523 return NULL;
524}
525
526/** EMACS **
527 * Local variables:
528 * mode: c++
529 * c-default-style: ellemtel
530 * c-basic-offset: 4
531 * End:
532 */