5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2007 - 2008 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
20 #include "silccrypto.h"
22 /************************* Static utility functions *************************/
24 /* Parse PGP packet */
27 silc_pgp_packet_parse(const unsigned char *data, SilcUInt32 data_len,
28 SilcPGPPacket *ret_packet)
33 SilcBool partial = FALSE;
36 SILC_LOG_DEBUG(("Parsing OpenPGP packet"));
38 if (!data || data_len < 2)
40 silc_buffer_set(&buf, (unsigned char *)data, data_len);
42 packet = silc_calloc(1, sizeof(*packet));
46 while (silc_buffer_len(&buf) > 0) {
48 silc_buffer_pull(&buf, 1);
51 SILC_LOG_DEBUG(("Invalid tag"));
60 packet->tag = tag & 0x3f;
61 SILC_LOG_DEBUG(("Packet type %d (%s)", packet->tag,
62 silc_pgp_packet_name(packet->tag)));
67 if (len >= 192 && len <= 223) {
69 if (silc_buffer_len(&buf) < 2)
71 len = ((len - 192) << 8) + buf.data[1] + 192;
72 silc_buffer_pull(&buf, 2);
73 } else if (len == 255) {
75 if (silc_buffer_len(&buf) < 5)
77 silc_buffer_pull(&buf, 1);
78 SILC_GET32_MSB(len, buf.data);
79 silc_buffer_pull(&buf, 4);
80 } else if (len >= 224 && len < 255) {
82 if (silc_buffer_len(&buf) < 1)
84 len = 1 << (len & 0x1f);
85 silc_buffer_pull(&buf, 1);
94 packet->tag = (tag >> 2) & 0x0f;
95 SILC_LOG_DEBUG(("Packet type %d (%s)", packet->tag,
96 silc_pgp_packet_name(packet->tag)));
99 if ((tag & 0x03) == 3) {
100 /* Indeterminate length, use whole buffer */
101 len = silc_buffer_len(&buf);
103 for (llen = 1 << (tag & 0x03), len = 0 ; llen; llen--) {
106 if (!silc_buffer_pull(&buf, 1))
112 if (silc_buffer_len(&buf) < len) {
113 SILC_LOG_DEBUG(("Too short packet (%d < %d)",
114 silc_buffer_len(&buf), len));
119 if (silc_buffer_format(&packet->data,
121 SILC_STR_DATA(silc_buffer_data(&buf), len),
125 silc_buffer_pull(&buf, len);
131 silc_buffer_start(&packet->data);
133 SILC_LOG_HEXDUMP(("Packet, len %d", silc_buffer_len(&packet->data)),
134 silc_buffer_data(&packet->data),
135 silc_buffer_len(&packet->data));
137 *ret_packet = packet;
139 return silc_buffer_headlen(&buf);
142 silc_buffer_purge(&packet->data);
147 /****************************** PGP Algorithms ******************************/
149 /* Allocates cipher */
151 SilcCipher silc_pgp_cipher_alloc(SilcPGPCipher cipher)
155 SILC_LOG_DEBUG(("Allocate cipher %d", cipher));
158 case SILC_PGP_CIPHER_IDEA:
159 if (!silc_cipher_alloc("idea-128-cfb", &c)) {
160 SILC_LOG_ERROR(("Unsupported algorithm idea-128-cfb"));
165 case SILC_PGP_CIPHER_3DES:
166 if (!silc_cipher_alloc("3des-168-cfb", &c)) {
167 SILC_LOG_ERROR(("Unsupported algorithm 3des-168-cfb"));
172 case SILC_PGP_CIPHER_CAST5:
173 if (!silc_cipher_alloc("cast5-128-cfb", &c)) {
174 SILC_LOG_ERROR(("Unsupported algorithm cast5-168-cfb"));
179 case SILC_PGP_CIPHER_BLOWFISH:
180 if (!silc_cipher_alloc("blowfish-128-cfb", &c)) {
181 SILC_LOG_ERROR(("Unsupported algorithm blowfish-128-cfb"));
186 case SILC_PGP_CIPHER_AES128:
187 if (!silc_cipher_alloc("aes-128-cfb", &c)) {
188 SILC_LOG_ERROR(("Unsupported algorithm aes-128-cfb"));
193 case SILC_PGP_CIPHER_AES192:
194 if (!silc_cipher_alloc("aes-192-cfb", &c)) {
195 SILC_LOG_ERROR(("Unsupported algorithm aes-192-cfb"));
200 case SILC_PGP_CIPHER_AES256:
201 if (!silc_cipher_alloc("aes-256-cfb", &c)) {
202 SILC_LOG_ERROR(("Unsupported algorithm aes-256-cfb"));
207 case SILC_PGP_CIPHER_TWOFISH:
208 if (!silc_cipher_alloc("twofish-256-cfb", &c)) {
209 SILC_LOG_ERROR(("Unsupported algorithm twofish-256-cfb"));
222 /* Allocates hash function */
224 SilcHash silc_pgp_hash_alloc(SilcPGPHash hash)
228 SILC_LOG_DEBUG(("Allocate hash %d", hash));
231 case SILC_PGP_HASH_MD5:
232 if (!silc_hash_alloc("md5", &h)) {
233 SILC_LOG_ERROR(("Unsupported algorithm md5"));
238 case SILC_PGP_HASH_SHA1:
239 if (!silc_hash_alloc("sha1", &h)) {
240 SILC_LOG_ERROR(("Unsupported algorithm sha1"));
245 case SILC_PGP_HASH_RIPEMD160:
246 if (!silc_hash_alloc("ripemd160", &h)) {
247 SILC_LOG_ERROR(("Unsupported algorithm ripemd160"));
252 case SILC_PGP_HASH_SHA256:
253 if (!silc_hash_alloc("sha256", &h)) {
254 SILC_LOG_ERROR(("Unsupported algorithm sha256"));
259 case SILC_PGP_HASH_SHA384:
260 if (!silc_hash_alloc("sha384", &h)) {
261 SILC_LOG_ERROR(("Unsupported algorithm sha384"));
266 case SILC_PGP_HASH_SHA512:
267 if (!silc_hash_alloc("sha512", &h)) {
268 SILC_LOG_ERROR(("Unsupported algorithm sha512"));
273 case SILC_PGP_HASH_SHA224:
274 if (!silc_hash_alloc("sha244", &h)) {
275 SILC_LOG_ERROR(("Unsupported algorithm sha224"));
288 /************************* OpenPGP Packet routines **************************/
291 /* Return packet tag as string */
293 const char *silc_pgp_packet_name(SilcPGPPacketTag tag)
295 if (tag == SILC_PGP_PACKET_PKENC_SK)
297 if (tag == SILC_PGP_PACKET_SIGNATURE)
299 if (tag == SILC_PGP_PACKET_SENC_SK)
301 if (tag == SILC_PGP_PACKET_OP_SIGNATURE)
302 return "OP_SIGNATUER";
303 if (tag == SILC_PGP_PACKET_SECKEY)
305 if (tag == SILC_PGP_PACKET_PUBKEY)
307 if (tag == SILC_PGP_PACKET_SECKEY_SUB)
309 if (tag == SILC_PGP_PACKET_COMP_DATA)
311 if (tag == SILC_PGP_PACKET_SENC_DATA)
313 if (tag == SILC_PGP_PACKET_MARKER)
315 if (tag == SILC_PGP_PACKET_LITERAL_DATA)
316 return "LITERAL_DATA";
317 if (tag == SILC_PGP_PACKET_TRUST)
319 if (tag == SILC_PGP_PACKET_USER_ID)
321 if (tag == SILC_PGP_PACKET_PUBKEY_SUB)
323 if (tag == SILC_PGP_PACKET_USER_ATTR)
325 if (tag == SILC_PGP_PACKET_SENC_I_DATA)
326 return "SENC_I_DATA";
327 if (tag == SILC_PGP_PACKET_MDC)
331 #endif /* SILC_DEBUG */
335 SilcPGPPacket silc_pgp_packet_copy(SilcPGPPacket packet)
337 SilcPGPPacket newpacket;
340 newpacket = silc_calloc(1, sizeof(*newpacket));
344 data = silc_memdup(packet->data.head, silc_buffer_truelen(&packet->data));
346 silc_free(newpacket);
350 silc_buffer_set(&newpacket->data, data, silc_buffer_truelen(&packet->data));
351 newpacket->tag = packet->tag;
356 /* Decode all PGP packets into a list */
358 int silc_pgp_packet_decode(const unsigned char *data,
363 SilcBufferStruct buf;
364 SilcPGPPacket packet;
367 SILC_LOG_DEBUG(("Parsing OpenPGP packets"));
372 if (!data || data_len < 2)
375 silc_buffer_set(&buf, (unsigned char *)data, data_len);
376 silc_list_init(*ret_list, struct SilcPGPPacketStruct, next);
378 /* Parse one by one */
379 while (silc_buffer_len(&buf) > 0) {
380 ret = silc_pgp_packet_parse(silc_buffer_data(&buf),
381 silc_buffer_len(&buf), &packet);
388 silc_buffer_pull(&buf, ret);
389 silc_list_add(*ret_list, packet);
392 SILC_LOG_DEBUG(("Parsed %d packets", silc_list_count(*ret_list)));
394 silc_list_start(*ret_list);
396 return silc_list_count(*ret_list);
399 /* Get PGP packet tag (packet type) */
401 SilcPGPPacketTag silc_pgp_packet_get_tag(SilcPGPPacket packet)
406 /* Get PGP packet data */
408 unsigned char *silc_pgp_packet_get_data(SilcPGPPacket packet,
409 SilcUInt32 *data_len)
411 unsigned char *ptr = silc_buffer_data(&packet->data);
413 *data_len = silc_buffer_len(&packet->data);
417 /* Free PGP packet from */
419 void silc_pgp_packet_free(SilcPGPPacket packet)
421 silc_buffer_purge(&packet->data);
425 /* Free PGP packets from list */
427 void silc_pgp_packet_free_list(SilcList *list)
429 SilcPGPPacket packet;
431 silc_list_start(*list);
432 while ((packet = silc_list_get(*list))) {
433 silc_buffer_purge(&packet->data);
438 /****************************** String to Key *******************************/
440 /* PGP String-to-key. Converts passphrases to encryption and decryption
441 keys. This can be used to create both encryption and decryption key. */
443 unsigned char *silc_pgp_s2k(SilcPGPS2KType type,
445 const char *passphrase,
446 SilcUInt32 passphrase_len,
449 SilcUInt32 iter_octet_count,
453 unsigned char *key = NULL, digest[SILC_HASH_MAXLEN], preload[8], esalt[8];
460 SILC_LOG_DEBUG(("Compute S2K for %s", salt ? "decryption" : "encryption"));
462 h = silc_pgp_hash_alloc(hash);
465 hash_len = silc_hash_len(h);
467 key = silc_malloc(key_len);
471 memset(preload, 0, sizeof(preload));
474 /* If salt is NULL, we'll create one for encryption */
476 silc_rng_get_rn_data(rng, 8, esalt, sizeof(esalt));
481 case SILC_PGP_S2K_SIMPLE:
482 /* Hash passphrase */
483 for (i = 0; i < key_len; i += hash_len) {
484 if (i && i < sizeof(preload)) {
486 silc_hash_update(h, preload, i);
489 silc_hash_update(h, passphrase, passphrase_len);
490 silc_hash_final(h, digest);
491 memcpy(key + i, digest,
492 (key_len - i) > hash_len ? hash_len : key_len - i);
496 case SILC_PGP_S2K_SALTED:
497 /* Hash passphrase with salt */
498 for (i = 0; i < key_len; i += hash_len) {
499 if (i && i < sizeof(preload)) {
501 silc_hash_update(h, preload, i);
504 silc_hash_update(h, salt, 8);
505 silc_hash_update(h, passphrase, passphrase_len);
506 silc_hash_final(h, digest);
507 memcpy(key + i, digest,
508 (key_len - i) > hash_len ? hash_len : key_len - i);
512 case SILC_PGP_S2K_ITERATED_SALTED:
513 /* Hash passphrase with salt iteratively. This is very poorly defined
515 if (iter_octet_count < 8 + passphrase_len)
516 iter_octet_count = 8 + passphrase_len;
518 for (i = 0; i < key_len; i += hash_len) {
519 if (i && i < sizeof(preload)) {
521 silc_hash_update(h, preload, i);
524 for (k = 0; k < iter_octet_count; k += (8 + passphrase_len)) {
525 if (iter_octet_count - k < 8) {
526 silc_hash_update(h, salt, iter_octet_count - k);
528 silc_hash_update(h, salt, 8);
529 if (iter_octet_count - k - 8 < passphrase_len)
530 silc_hash_update(h, passphrase, iter_octet_count - k - 8);
532 silc_hash_update(h, passphrase, passphrase_len);
536 silc_hash_final(h, digest);
537 memcpy(key + i, digest,
538 (key_len - i) > hash_len ? hash_len : key_len - i);
547 memset(digest, 0, sizeof(digest));
548 memset(esalt, 0, sizeof(esalt));
559 /****************************** ASCII armoring ******************************/
561 /* Adds ASCII armor */
563 unsigned char *silc_pgp_armor(unsigned char *data,
570 /* Removes ASCII armoring */
572 unsigned char *silc_pgp_dearmor(unsigned char *data,
581 if (memcmp(data, "-----BEGIN PGP ", 15))
584 /* Get beginning of base64 encoded data */
585 for (i = 0; i < data_len; i++) {
586 if (i + 3 < data_len && data[i] == '\n' && data[i + 1] == '\n') {
590 if (i + 3 < data_len &&
591 data[i] == '\n' && data[i + 1] == ' ' && data[i + 2] == '\n') {
597 /* Get end of base64 encoded data, ignore OpenPGP radix64 CRC */
598 for (k = i; k < data_len; k++) {
599 if (k + 1 < data_len && data[k] == '=') {
600 data_len -= (data_len - ++k);
605 return silc_base64_decode(NULL, data + i, data_len, ret_len);