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
29 * contrib/pgcrypto/pgp-pubenc.c
37 * padded msg: 02 || non-zero pad bytes || 00 || msg
40 pad_eme_pkcs1_v15(uint8
*data
, int data_len
, int res_len
, uint8
**res_p
)
44 int pad_len
= res_len
- 2 - data_len
;
49 buf
= palloc(res_len
);
52 if (!pg_strong_random(buf
+ 1, pad_len
))
58 /* pad must not contain zero bytes */
60 while (p
< buf
+ 1 + pad_len
)
64 if (!pg_strong_random(p
, 1))
66 px_memset(buf
, 0, res_len
);
76 memcpy(buf
+ pad_len
+ 2, data
, data_len
);
83 create_secmsg(PGP_Context
*ctx
, PGP_MPI
**msg_p
, int full_bytes
)
89 int klen
= ctx
->sess_key_len
;
94 for (i
= 0; i
< klen
; i
++)
95 cksum
+= ctx
->sess_key
[i
];
98 * create "secret message"
100 secmsg
= palloc(klen
+ 3);
101 secmsg
[0] = ctx
->cipher_algo
;
102 memcpy(secmsg
+ 1, ctx
->sess_key
, klen
);
103 secmsg
[klen
+ 1] = (cksum
>> 8) & 0xFF;
104 secmsg
[klen
+ 2] = cksum
& 0xFF;
107 * now create a large integer of it
109 res
= pad_eme_pkcs1_v15(secmsg
, klen
+ 3, full_bytes
, &padded
);
112 /* first byte will be 0x02 */
113 int full_bits
= full_bytes
* 8 - 6;
115 res
= pgp_mpi_create(padded
, full_bits
, &m
);
120 px_memset(padded
, 0, full_bytes
);
123 px_memset(secmsg
, 0, klen
+ 3);
133 encrypt_and_write_elgamal(PGP_Context
*ctx
, PGP_PubKey
*pk
, PushFilter
*pkt
)
140 /* create padded msg */
141 res
= create_secmsg(ctx
, &m
, pk
->pub
.elg
.p
->bytes
- 1);
146 res
= pgp_elgamal_encrypt(pk
, m
, &c1
, &c2
);
151 res
= pgp_mpi_write(pkt
, c1
);
154 res
= pgp_mpi_write(pkt
, c2
);
164 encrypt_and_write_rsa(PGP_Context
*ctx
, PGP_PubKey
*pk
, PushFilter
*pkt
)
170 /* create padded msg */
171 res
= create_secmsg(ctx
, &m
, pk
->pub
.rsa
.n
->bytes
- 1);
176 res
= pgp_rsa_encrypt(pk
, m
, &c
);
181 res
= pgp_mpi_write(pkt
, c
);
190 pgp_write_pubenc_sesskey(PGP_Context
*ctx
, PushFilter
*dst
)
193 PGP_PubKey
*pk
= ctx
->pub_key
;
195 PushFilter
*pkt
= NULL
;
200 px_debug("no pubkey?\n");
209 res
= pgp_create_pkt_writer(dst
, PGP_PKT_PUBENCRYPTED_SESSKEY
, &pkt
);
212 res
= pushf_write(pkt
, &ver
, 1);
215 res
= pushf_write(pkt
, pk
->key_id
, 8);
218 res
= pushf_write(pkt
, &algo
, 1);
224 case PGP_PUB_ELG_ENCRYPT
:
225 res
= encrypt_and_write_elgamal(ctx
, pk
, pkt
);
227 case PGP_PUB_RSA_ENCRYPT
:
228 case PGP_PUB_RSA_ENCRYPT_SIGN
:
229 res
= encrypt_and_write_rsa(ctx
, pk
, pkt
);
236 * done, signal packet end
238 res
= pushf_flush(pkt
);