3 * Encrypt session key with public key.
5 * Copyright (c) 2005 Marko Kreen
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * padded msg: 02 || non-zero pad bytes || 00 || msg
41 pad_eme_pkcs1_v15(uint8
*data
, int data_len
, int res_len
, uint8
**res_p
)
46 int pad_len
= res_len
- 2 - data_len
;
51 buf
= px_alloc(res_len
);
53 res
= px_get_random_bytes(buf
+ 1, pad_len
);
60 /* pad must not contain zero bytes */
62 while (p
< buf
+ 1 + pad_len
)
66 res
= px_get_random_bytes(p
, 1);
76 memset(buf
, 0, res_len
);
82 memcpy(buf
+ pad_len
+ 2, data
, data_len
);
89 create_secmsg(PGP_Context
* ctx
, PGP_MPI
** msg_p
, int full_bytes
)
95 int klen
= ctx
->sess_key_len
;
100 for (i
= 0; i
< klen
; i
++)
101 cksum
+= ctx
->sess_key
[i
];
104 * create "secret message"
106 secmsg
= px_alloc(klen
+ 3);
107 secmsg
[0] = ctx
->cipher_algo
;
108 memcpy(secmsg
+ 1, ctx
->sess_key
, klen
);
109 secmsg
[klen
+ 1] = (cksum
>> 8) & 0xFF;
110 secmsg
[klen
+ 2] = cksum
& 0xFF;
113 * now create a large integer of it
115 res
= pad_eme_pkcs1_v15(secmsg
, klen
+ 3, full_bytes
, &padded
);
118 /* first byte will be 0x02 */
119 int full_bits
= full_bytes
* 8 - 6;
121 res
= pgp_mpi_create(padded
, full_bits
, &m
);
126 memset(padded
, 0, full_bytes
);
129 memset(secmsg
, 0, klen
+ 3);
139 encrypt_and_write_elgamal(PGP_Context
* ctx
, PGP_PubKey
* pk
, PushFilter
* pkt
)
146 /* create padded msg */
147 res
= create_secmsg(ctx
, &m
, pk
->pub
.elg
.p
->bytes
- 1);
152 res
= pgp_elgamal_encrypt(pk
, m
, &c1
, &c2
);
157 res
= pgp_mpi_write(pkt
, c1
);
160 res
= pgp_mpi_write(pkt
, c2
);
170 encrypt_and_write_rsa(PGP_Context
* ctx
, PGP_PubKey
* pk
, PushFilter
* pkt
)
176 /* create padded msg */
177 res
= create_secmsg(ctx
, &m
, pk
->pub
.rsa
.n
->bytes
- 1);
182 res
= pgp_rsa_encrypt(pk
, m
, &c
);
187 res
= pgp_mpi_write(pkt
, c
);
196 pgp_write_pubenc_sesskey(PGP_Context
* ctx
, PushFilter
* dst
)
199 PGP_PubKey
*pk
= ctx
->pub_key
;
201 PushFilter
*pkt
= NULL
;
202 uint8 algo
= pk
->algo
;
206 px_debug("no pubkey?\n");
213 res
= pgp_create_pkt_writer(dst
, PGP_PKT_PUBENCRYPTED_SESSKEY
, &pkt
);
216 res
= pushf_write(pkt
, &ver
, 1);
219 res
= pushf_write(pkt
, pk
->key_id
, 8);
222 res
= pushf_write(pkt
, &algo
, 1);
228 case PGP_PUB_ELG_ENCRYPT
:
229 res
= encrypt_and_write_elgamal(ctx
, pk
, pkt
);
231 case PGP_PUB_RSA_ENCRYPT
:
232 case PGP_PUB_RSA_ENCRYPT_SIGN
:
233 res
= encrypt_and_write_rsa(ctx
, pk
, pkt
);
240 * done, signal packet end
242 res
= pushf_flush(pkt
);