File Coverage

blib/lib/Crypt/KeyWrap.pm
Criterion Covered Total %
statement 214 219 97.7
branch 103 146 70.5
condition 21 29 72.4
subroutine 26 26 100.0
pod 12 12 100.0
total 376 432 87.0


line stmt bran cond sub pod time code
1             package Crypt::KeyWrap;
2              
3 13     13   426648 use strict;
  13         88  
  13         406  
4 13     13   168 use warnings;
  13         29  
  13         574  
5              
6             our $VERSION = '0.034';
7              
8 13     13   85 use Exporter 'import';
  13         27  
  13         1434  
9             our %EXPORT_TAGS = ( all => [qw(aes_key_wrap aes_key_unwrap gcm_key_wrap gcm_key_unwrap pbes2_key_wrap pbes2_key_unwrap ecdh_key_wrap ecdh_key_unwrap ecdhaes_key_wrap ecdhaes_key_unwrap rsa_key_wrap rsa_key_unwrap)] );
10             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
11             our @EXPORT = qw();
12              
13 13     13   93 use Carp;
  13         27  
  13         986  
14 13     13   3396 use Crypt::Mode::ECB;
  13         113374  
  13         613  
15 13     13   6219 use Crypt::AuthEnc::GCM qw(gcm_encrypt_authenticate gcm_decrypt_verify);
  13         4780  
  13         883  
16 13     13   3181 use Crypt::PRNG qw(random_bytes);
  13         6469  
  13         699  
17 13     13   5894 use Crypt::KeyDerivation qw(pbkdf2);
  13         4250  
  13         793  
18 13     13   3358 use Crypt::Digest qw(digest_data);
  13         5555  
  13         641  
19 13     13   133 use Config;
  13         27  
  13         43087  
20              
21             # JWS: https://tools.ietf.org/html/rfc7515
22             # JWE: https://tools.ietf.org/html/rfc7516
23             # JWK: https://tools.ietf.org/html/rfc7517
24             # JWA: https://tools.ietf.org/html/rfc7518 - !!! this is important !!!
25              
26             sub _LSB {
27 12541     12541   18889 my ($bytes, $data) = @_;
28 12541         16298 my $len = length $data;
29 12541 50       36734 return $len > $bytes ? substr($data, $len-$bytes, $bytes) : $data;
30             }
31              
32             sub _MSB {
33 12541     12541   20541 my ($bytes, $data) = @_;
34 12541         16006 my $len = length $data;
35 12541 50       29939 return $len > $bytes ? substr($data, 0, $bytes) : $data;
36             }
37              
38             sub _N2RAW {
39 12528     12528   19420 my ($bytes, $n) = @_;
40 12528 100       21576 if ($bytes == 8) {
41 10656 50       46143 return pack("N", 0) . pack("N", $n) if $Config{uvsize} == 4; #workaround
42 10656         45212 return pack("N", $n >> 32) . pack("N", $n & 0xFFFFFFFF);
43             }
44 1872 50       6486 return pack("N", $n & 0xFFFFFFFF) if $bytes == 4;
45             }
46              
47             sub aes_key_wrap {
48 138     138 1 47183 my ($kek, $pt_data, $cipher, $padding, $inverse) = @_;
49 138 100       506 $cipher = 'AES' unless defined $cipher;
50 138 50       445 $padding = $cipher eq 'AES' ? 1 : 0 unless defined $padding;
    100          
51              
52 138         274 my ($A, $B, $P, $R);
53              
54 138 50       348 croak "aes_key_wrap: no KEK" unless defined $kek;
55 138 50       331 croak "aes_key_wrap: no PT data" unless defined $pt_data;
56 138         260 my $klen = length $kek;
57 138 50 100     703 croak "aes_key_wrap: invalid KEK length" unless $klen == 16 || $klen == 24 || $klen == 32;
      66        
58 138 50 66     503 croak "aes_key_wrap: cipher must be AES or DES_EDE" unless $cipher eq 'AES' || $cipher eq 'DES_EDE';
59 138 50 66     539 croak "aes_key_wrap: padding not allowed with DES_EDE" if $padding && $cipher eq 'DES_EDE';
60              
61 138         1280 my $ECB = Crypt::Mode::ECB->new($cipher, 0);
62 138 100       387 my $blck = $cipher eq 'DES_EDE' ? 4 : 8; # semiblock size in bytes, for AES 8, for 3DES 4
63              
64 138         622 my $IV = pack("H*", "A6" x $blck);
65 138         276 my $len = length $pt_data;
66 138 100       485 if ($len % $blck > 0) {
67 33 50       92 croak "aes_key_wrap: pt_data length not multiply of $blck" if !$padding;
68 33         84 $pt_data .= chr(0) x ($blck - ($len % $blck));
69 33         83 $IV = pack("H*", "A65959A6") . pack("N", $len);
70             }
71              
72 138         394 my $n = length($pt_data) / $blck;
73 138         1347 $P->[$_] = substr($pt_data, $_*$blck, $blck) for (0..$n-1);
74              
75 138 100       430 if ($n == 1) {
76 13 100       75 return $inverse ? $ECB->decrypt($IV . $P->[0], $kek)
77             : $ECB->encrypt($IV . $P->[0], $kek);
78             }
79              
80 125         217 $A = $IV;
81 125         839 $R->[$_] = $P->[$_] for (0..$n-1);
82              
83 125         311 for my $j (0..5) {
84 750         1549 for my $i (0..$n-1) {
85 6012 100       16901 $B = $inverse ? $ECB->decrypt($A . $R->[$i], $kek)
86             : $ECB->encrypt($A . $R->[$i], $kek);
87 6012         89240 $A = _MSB($blck, $B) ^ _N2RAW($blck, ($n*$j)+$i+1);
88 6012         11897 $R->[$i] = _LSB($blck, $B);
89             }
90             }
91              
92 125         247 my $rv = $A;
93 125         686 $rv .= $R->[$_] for (0..$n-1);
94 125         1060 return $rv;
95             }
96              
97             sub aes_key_unwrap {
98 163     163 1 47520 my ($kek, $ct_data, $cipher, $padding, $inverse) = @_;
99 163 100       527 $cipher = 'AES' unless defined $cipher;
100 163 50       563 $padding = $cipher eq 'AES' ? 1 : 0 unless defined $padding;
    100          
101              
102 163         364 my ($A, $B, $C, $P, $R);
103              
104 163 50       456 croak "aes_key_unwrap: no KEK" unless defined $kek;
105 163 50       406 croak "aes_key_unwrap: no CT data" unless defined $ct_data;
106 163         300 my $klen = length $kek;
107 163 50 100     853 croak "aes_key_unwrap: invalid KEK length" unless $klen == 16 || $klen == 24 || $klen == 32;
      66        
108 163 50 66     522 croak "aes_key_unwrap: cipher must be AES or DES_EDE" unless $cipher eq 'AES' || $cipher eq 'DES_EDE';
109 163 50 66     782 croak "aes_key_unwrap: padding not allowed with DES_EDE" if $padding && $cipher eq 'DES_EDE';
110              
111 163         1552 my $ECB = Crypt::Mode::ECB->new($cipher, 0);
112 163 100       503 my $blck = $cipher eq 'DES_EDE' ? 4 : 8; # semiblock size in bytes, for AES 8, for 3DES 4
113              
114 163         528 my $n = length($ct_data) / $blck - 1;
115 163         1575 $C->[$_] = substr($ct_data, $_*$blck, $blck) for (0..$n); # n+1 semiblocks
116              
117 163 100       468 if ($n==1) {
118 13 100       70 $B = $inverse ? $ECB->encrypt($C->[0] . $C->[1], $kek)
119             : $ECB->decrypt($C->[0] . $C->[1], $kek);
120 13         285 $A = _MSB($blck, $B);
121 13         33 $R->[0] = _LSB($blck, $B);
122             }
123             else {
124 150         331 $A = $C->[0];
125 150         967 $R->[$_] = $C->[$_+1] for (0..$n-1);
126 150         530 for(my $j=5; $j>=0; $j--) {
127 900         1975 for(my $i=$n-1; $i>=0; $i--) {
128 6516 100       14870 $B = $inverse ? $ECB->encrypt(($A ^ _N2RAW($blck, $n*$j+$i+1)) . $R->[$i], $kek)
129             : $ECB->decrypt(($A ^ _N2RAW($blck, $n*$j+$i+1)) . $R->[$i], $kek);
130 6516         97604 $A = _MSB($blck, $B);
131 6516         10435 $R->[$i] = _LSB($blck, $B);
132             }
133             }
134             }
135              
136 163         337 my $rv = '';
137 163         849 $rv .= $R->[$_] for (0..$n-1);
138              
139 163         613 my $A_hex = unpack("H*", $A);
140 163 100 33     874 if ($A_hex eq 'a6'x$blck) {
    50          
141 130         1002 return $rv;
142             }
143             elsif ($A_hex =~ /^a65959a6/ && $blck == 8) {
144 33 50       80 warn "key_unwrap: unexpected padding" unless $padding;
145 33         127 my $n = unpack("N", substr($A, 4, 4));
146 33         72 my $z = length($rv) - $n;
147 33         97 my $tail = unpack("H*", substr($rv, -$z));
148 33 50       87 croak "aes_key_unwrap: invalid data" unless $tail eq "00"x$z;
149 33         257 return substr($rv, 0, $n);
150             }
151 0         0 croak "aes_key_unwrap: unexpected data [$cipher/$A_hex]";
152             }
153              
154             # AES GCM KW - https://tools.ietf.org/html/rfc7518#section-4.7
155              
156             sub gcm_key_wrap {
157 19     19 1 851 my ($kek, $pt_data, $aad, $cipher, $iv) = @_;
158 19 100       46 $cipher = 'AES' unless defined $cipher;
159 19 100       53 $iv = random_bytes(12) unless defined $iv; # 96 bits REQUIRED by RFC7518
160 19         4322 my ($ct_data, $tag) = gcm_encrypt_authenticate($cipher, $kek, $iv, $aad, $pt_data);
161 19         102 return ($ct_data, $tag, $iv);
162             }
163              
164             sub gcm_key_unwrap {
165 23     23 1 155 my ($kek, $ct_data, $tag, $iv, $aad, $cipher) = @_;
166 23   100     108 $cipher ||= 'AES';
167 23         4676 my $pt_data = gcm_decrypt_verify($cipher, $kek, $iv, $aad, $ct_data, $tag);
168 23         126 return $pt_data;
169             }
170              
171             # PBES2/PBKDF2 KW - https://tools.ietf.org/html/rfc7518#section-4.8
172              
173             sub pbes2_key_wrap {
174 25     25 1 921 my ($kek, $pt_data, $alg, $salt, $iter) = @_;
175 25         72 my ($hash_name, $len);
176 25 50       179 if ($alg =~ /^PBES2-HS(256|384|512)\+A(128|192|256)KW$/) {
177 25         75 $hash_name = "SHA$1";
178 25         71 $len = $2/8;
179 25         494040 my $aes_key = pbkdf2($kek, $alg."\x00".$salt, $iter, $hash_name, $len);
180 25         232 my $ct_data = aes_key_wrap($aes_key, $pt_data);
181 25         134 return $ct_data;
182             }
183 0         0 croak "pbes2_key_wrap: invalid alg '$alg'";
184 0         0 return undef;
185             }
186              
187             sub pbes2_key_unwrap {
188 40     40 1 345 my ($kek, $ct_data, $alg, $salt, $iter) = @_;
189 40         91 my ($hash_name, $len);
190 40 50       215 if ($alg =~ /^PBES2-HS(256|384|512)\+A(128|192|256)KW$/) {
191 40         120 $hash_name = "SHA$1";
192 40         134 $len = $2/8;
193 40         818412 my $aes_key = pbkdf2($kek, $alg."\x00".$salt, $iter, $hash_name, $len);
194 40         399 my $pt_data = aes_key_unwrap($aes_key, $ct_data);
195 40         340 return $pt_data;
196             }
197 0         0 croak "pbes2_key_unwrap: invalid alg '$alg'";
198 0         0 return undef;
199             }
200              
201             # RSA KW
202             # https://tools.ietf.org/html/rfc7518#section-4.2
203             # https://tools.ietf.org/html/rfc7518#section-4.3
204              
205             sub rsa_key_wrap {
206 21     21 1 2018 my ($kek_public, $pt_data, $alg) = @_;
207 21 50       53 croak "rsa_key_wrap: no Crypt::PK::RSA" unless ref $kek_public eq 'Crypt::PK::RSA';
208 21         36 my ($padding, $hash_name);
209 21 100       60 if ($alg eq 'RSA-OAEP') { ($padding, $hash_name) = ('oaep', 'SHA1') }
  7 100       17  
    50          
210 7         16 elsif ($alg eq 'RSA-OAEP-256') { ($padding, $hash_name) = ('oaep', 'SHA256') }
211 7         12 elsif ($alg eq 'RSA1_5') { $padding = 'v1.5' }
212 21 50       45 croak "rsa_key_wrap: invalid algorithm '$alg'" unless $padding;
213 21         4790 my $ct_data = $kek_public->encrypt($pt_data, $padding, $hash_name);
214 21         83 return $ct_data;
215             }
216              
217             sub rsa_key_unwrap {
218 39     39 1 863 my ($kek_private, $ct_data, $alg) = @_;
219 39 50       134 croak "rsa_key_unwrap: no Crypt::PK::RSA" unless ref $kek_private eq 'Crypt::PK::RSA';
220 39 50       150 croak "rsa_key_unwrap: no private key" unless $kek_private->is_private;
221 39         59 my ($padding, $hash_name);
222 39 100       121 if ($alg eq 'RSA-OAEP') { ($padding, $hash_name) = ('oaep', 'SHA1') }
  14 100       31  
    50          
223 10         22 elsif ($alg eq 'RSA-OAEP-256') { ($padding, $hash_name) = ('oaep', 'SHA256') }
224 15         27 elsif ($alg eq 'RSA1_5') { $padding = 'v1.5' }
225 39 50       80 croak "rsa_key_unwrap: invalid algorithm '$alg'" unless $padding;
226 39         209815 my $pt_data = $kek_private->decrypt($ct_data, $padding, $hash_name);
227 39         454 return $pt_data;
228             }
229              
230             # ConcatKDF - http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf
231             # ECDH KW - https://tools.ietf.org/html/rfc7518#section-4.6
232              
233             sub _concat_kdf {
234 68     68   251 my ($hash_name, $key_size, $shared_secret, $algorithm, $apu, $apv) = @_;
235 68 50       238 $apu = '' unless defined $apu;
236 68 50       163 $apv = '' unless defined $apv;
237 68         360 my $hsize = Crypt::Digest->hashsize($hash_name);
238 68         175 my $count = int($key_size / $hsize);
239 68 100       203 $count++ if ($key_size % $hsize) > 0;
240 68         121 my $data = '';
241 68         198 for my $i (1..$count) {
242 72         864 $data .= digest_data('SHA256', pack("N", 1) .
243             $shared_secret .
244             pack("N", length($algorithm)) . $algorithm .
245             pack("N", length($apu)) . $apu .
246             pack("N", length($apv)) . $apv .
247             pack("N", 8 *$key_size));
248             }
249 68         305 return substr($data, 0, $key_size);
250             }
251              
252             sub ecdh_key_wrap {
253 7     7 1 3820 my ($kek_public, $enc, $apu, $apv) = @_;
254 7 50       23 croak "ecdh_key_wrap: no Crypt::PK::ECC" unless ref $kek_public eq 'Crypt::PK::ECC';
255 7         15 my $encryption_key_size = 256;
256 7 100       24 if ($enc =~ /^A(128|192|256)CBC-HS/) {
257 3         20 $encryption_key_size = $1*2;
258             }
259 7 100       63 if ($enc =~ /^A(128|192|256)GCM/) {
260 4         29 $encryption_key_size = $1;
261             }
262 7         30 my $ephemeral = Crypt::PK::ECC->new()->generate_key($kek_public->curve2hash);
263 7         41841 my $shared_secret = $ephemeral->shared_secret($kek_public);
264 7         54 my $ct_data = _concat_kdf('SHA256', $encryption_key_size/8, $shared_secret, $enc, $apu, $apv);
265 7         39 return ($ct_data, $ephemeral->export_key_jwk('public'));
266             }
267              
268             sub ecdh_key_unwrap {
269 15     15 1 8603 my ($kek_private, $enc, $epk, $apu, $apv) = @_;
270 15 50       70 croak "ecdh_key_unwrap: no Crypt::PK::ECC" unless ref $kek_private eq 'Crypt::PK::ECC';
271 15 50       73 croak "ecdh_key_unwrap: no private key" unless $kek_private->is_private;
272 15         26 my $encryption_key_size = 256;
273 15 100       59 if ($enc =~ /^A(128|192|256)CBC-HS/) {
274 5         21 $encryption_key_size = $1*2;
275             }
276 15 100       85 if ($enc =~ /^A(128|192|256)GCM/) {
277 10         32 $encryption_key_size = $1;
278             }
279 15 100       91 my $ephemeral = ref($epk) eq 'Crypt::PK::ECC' ? $epk : Crypt::PK::ECC->new(ref $epk ? $epk : \$epk);
    50          
280 15         89403 my $shared_secret = $kek_private->shared_secret($ephemeral);
281 15         112 my $pt_data = _concat_kdf('SHA256', $encryption_key_size/8, $shared_secret, $enc, $apu, $apv);
282 15         177 return $pt_data;
283             }
284              
285             sub ecdhaes_key_wrap {
286 20     20 1 3823 my ($kek_public, $pt_data, $alg, $apu, $apv) = @_;
287 20 50       97 croak "ecdhaes_key_wrap: no Crypt::PK::(ECC|X25519)" unless ref($kek_public) =~ /^Crypt::PK::(ECC|X25519)$/;
288 20         43 my $encryption_key_size = 256;
289 20 50       64 if ($alg =~ /^ECDH-ES\+A(128|192|256)KW$/) {
290 20         48 $encryption_key_size = $1;
291             }
292 20         30 my $ephemeral;
293 20 100       53 if (ref($kek_public) eq 'Crypt::PK::ECC') {
294 19         76 $ephemeral = Crypt::PK::ECC->new->generate_key($kek_public->curve2hash);
295             }
296             else {
297 1         4 $ephemeral = Crypt::PK::X25519->new->generate_key();
298             }
299 20         222488 my $shared_secret = $ephemeral->shared_secret($kek_public);
300 20         155 my $kek = _concat_kdf('SHA256', $encryption_key_size/8, $shared_secret, $alg, $apu, $apv);
301 20         71 return (aes_key_wrap($kek, $pt_data), $ephemeral->export_key_jwk('public'));
302             }
303              
304             sub ecdhaes_key_unwrap {
305 26     26 1 7801 my ($kek_private, $ct_data, $alg, $epk, $apu, $apv) = @_;
306 26 50       168 croak "ecdhaes_key_unwrap: no Crypt::PK::(ECC|X25519)" unless ref($kek_private) =~ /^Crypt::PK::(ECC|X25519)$/;
307 26 50       122 croak "ecdhaes_key_unwrap: no private key" unless $kek_private->is_private;
308 26         46 my $encryption_key_size = 256;
309 26 50       109 if ($alg =~ /^ECDH-ES\+A(128|192|256)KW$/) {
310 26         73 $encryption_key_size = $1;
311             }
312 26         35 my $ephemeral;
313 26 100       73 if (ref($kek_private) eq 'Crypt::PK::ECC') {
314 25 100       144 $ephemeral = ref($epk) eq 'Crypt::PK::ECC' ? $epk : Crypt::PK::ECC->new(ref $epk ? $epk : \$epk);
    50          
315             }
316             else {
317 1 50       9 $ephemeral = ref($epk) eq 'Crypt::PK::X25519' ? $epk : Crypt::PK::X25519->new(ref $epk ? $epk : \$epk);
    50          
318             }
319 26         256592 my $shared_secret = $kek_private->shared_secret($ephemeral);
320 26         216 my $kek = _concat_kdf('SHA256', $encryption_key_size/8, $shared_secret, $alg, $apu, $apv);
321 26         92 my $pt_data = aes_key_unwrap($kek, $ct_data);
322 26         276 return $pt_data;
323             }
324              
325             1;
326              
327             =pod
328              
329             =head1 NAME
330              
331             Crypt::KeyWrap - Key management/wrapping algorithms defined in RFC7518 (JWA)
332              
333             =head1 SYNOPSIS
334              
335             # A192KW wrapping
336             use Crypt::KeyWrap qw(aes_key_wrap);
337             my $kek = pack("H*", "5840df6e29b02af1ab493b705bf16ea1ae8338f4dcc176a8"); # key encryption key
338             my $cek = pack("H*", "c37b7e6492584340bed12207808941155068f738"); # content encryption key
339             my $enc_cek = aes_key_wrap($kek, $pt_data); # encrypted content encryption key
340              
341             # A192KW unwrapping
342             use Crypt::KeyWrap qw(aes_key_unwrap);
343             my $kek = pack("H*", "5840df6e29b02af1ab493b705bf16ea1ae8338f4dcc176a8");
344             my $enc_cek = pack("H*", "138bdeaa9b8fa7fc61f97742e72248ee5ae6ae5360d1ae6a5f54f373fa543b6a");
345             my $cek = aes_key_unwrap($kek, $pt_data);
346              
347             =head1 DESCRIPTION
348              
349             Implements key management algorithms defined in L
350              
351             BEWARE: experimental, interface of this module might change!
352              
353             Supported algorithms (all defined in RFC7518):
354              
355             A128KW see: aes_key_wrap() + aes_key_unwrap()
356             A192KW see: aes_key_wrap() + aes_key_unwrap()
357             A256KW see: aes_key_wrap() + aes_key_unwrap()
358             A128GCMKW see: gcm_key_wrap() + gcm_key_unwrap()
359             A192GCMKW see: gcm_key_wrap() + gcm_key_unwrap()
360             A256GCMKW see: gcm_key_wrap() + gcm_key_unwrap()
361             PBES2-HS256+A128KW see: pbes2_key_wrap() + pbes2_key_unwrap()
362             PBES2-HS384+A192KW see: pbes2_key_wrap() + pbes2_key_unwrap()
363             PBES2-HS512+A256KW see: pbes2_key_wrap() + pbes2_key_unwrap()
364             RSA-OAEP see: rsa_key_wrap() + rsa_key_unwrap()
365             RSA-OAEP-256 see: rsa_key_wrap() + rsa_key_unwrap()
366             RSA1_5 see: rsa_key_wrap() + rsa_key_unwrap()
367             ECDH-ES+A128KW see: ecdhaes_key_wrap() + ecdhaes_key_unwrap()
368             ECDH-ES+A192KW see: ecdhaes_key_wrap() + ecdhaes_key_unwrap()
369             ECDH-ES+A256KW see: ecdhaes_key_wrap() + ecdhaes_key_unwrap()
370             ECDH-ES see: ecdh_key_wrap() + ecdh_key_unwrap()
371              
372             =head1 EXPORT
373              
374             Nothing is exported by default.
375              
376             You can export selected functions:
377              
378             use Crypt::KeyWrap qw(aes_key_wrap gcm_key_wrap pbes2_key_wrap);
379              
380             Or all of them at once:
381              
382             use Crypt::KeyWrap ':all';
383              
384             =head1 FUNCTIONS
385              
386             =head2 aes_key_wrap
387              
388             AES key wrap algorithm as defined in L
389             (implements algorithms C, C, C).
390              
391             Implementation follows L and L.
392              
393             The implementation is also compatible with L
394             (it supports AES based KW, KWP + TDEA/DES_EDE based TKW).
395              
396             AES Key Wrap algorithm.
397              
398             $enc_cek = aes_key_wrap($kek, $cek);
399             # or
400             $enc_cek = aes_key_wrap($kek, $cek, $cipher, $padding, $inverse);
401              
402             # params:
403             # $kek .. key encryption key (16bytes for AES128, 24 for AES192, 32 for AES256)
404             # $cek .. content encryption key
405             # optional params:
406             # $cipher .. 'AES' (default) or 'DES_EDE'
407             # $padding .. 1 (default) or 0 handle $cek padding (relevant for AES only)
408             # $inverse .. 0 (default) or 1 use cipher in inverse mode as defined by SP.800-38F
409              
410             Values C<$enc_cek>, C<$cek> and C<$kek> are binary octets. If you disable padding you have to make sure that
411             C<$cek> length is multiply of 8 (for AES) or multiply of 4 (for DES_EDE);
412              
413             =head2 aes_key_unwrap
414              
415             AES key unwrap algorithm as defined in L
416             (implements algorithms C, C, C).
417              
418             AES Key Unwrap algorithm.
419              
420             $cek = aes_key_unwrap($kek, $enc_cek);
421             # or
422             $cek = aes_key_unwrap($kek, $enc_cek, $cipher, $padding, $inverse);
423              
424             # params:
425             # $kek .. key encryption key (16bytes for AES128, 24 for AES192, 32 for AES256)
426             # $enc_cek .. encrypted content encryption key
427             # optional params:
428             # $cipher .. 'AES' (default) or 'DES_EDE'
429             # $padding .. 1 (default) or 0 - use $cek padding (relevant for AES only)
430             # $inverse .. 0 (default) or 1 - use cipher in inverse mode as defined by SP.800-38F
431              
432             Values C<$enc_cek>, C<$cek> and C<$kek> are binary octets.
433              
434             =head2 gcm_key_wrap
435              
436             AES GCM key wrap algorithm as defined in L
437             (implements algorithms C, C, C).
438              
439             ($enc_cek, $tag, $iv) = gcm_key_wrap($kek, $cek);
440             #or
441             ($enc_cek, $tag, $iv) = gcm_key_wrap($kek, $cek, $aad);
442             #or
443             ($enc_cek, $tag, $iv) = gcm_key_wrap($kek, $cek, $aad, $cipher, $iv);
444              
445             # params:
446             # $kek .. key encryption key (16bytes for AES128, 24 for AES192, 32 for AES256)
447             # $cek .. content encryption key
448             # optional params:
449             # $aad .. additional authenticated data, DEFAULT is '' (empty string)
450             # $cipher .. cipher to be used by GCM, DEFAULT is 'AES'
451             # $iv .. initialization vector (if not defined a random IV is generated)
452              
453             Values C<$enc_cek>, C<$cek>, C<$aad>, C<$iv>, C<$tag> and C<$kek> are binary octets.
454              
455             =head2 gcm_key_unwrap
456              
457             AES GCM key unwrap algorithm as defined in L
458             (implements algorithms C, C, C).
459              
460             $cek = gcm_key_unwrap($kek, $enc_cek, $tag, $iv);
461             # or
462             $cek = gcm_key_unwrap($kek, $enc_cek, $tag, $iv, $aad);
463             # or
464             $cek = gcm_key_unwrap($kek, $enc_cek, $tag, $iv, $aad, $cipher);
465              
466             # params:
467             # $kek .. key encryption key (16bytes for AES128, 24 for AES192, 32 for AES256)
468             # $enc_cek .. encrypted content encryption key
469             # $tag .. GCM's tag
470             # $iv .. initialization vector
471             # optional params:
472             # $aad .. additional authenticated data, DEFAULT is '' (empty string)
473             # $cipher .. cipher to be used by GCM, DEFAULT is 'AES'
474              
475             Values C<$enc_cek>, C<$cek>, C<$aad>, C<$iv>, C<$tag> and C<$kek> are binary octets.
476              
477             =head2 pbes2_key_wrap
478              
479             PBES2 key wrap algorithm as defined in L
480             (implements algorithms C, C, C).
481              
482             $enc_cek = pbes2_key_wrap($kek, $cek, $alg, $salt, $iter);
483              
484             # params:
485             # $kek .. key encryption key (arbitrary length)
486             # $cek .. content encryption key
487             # $alg .. algorithm name e.g. 'PBES2-HS256+A128KW' (see rfc7518)
488             # $salt .. pbkdf2 salt
489             # $iter .. pbkdf2 iteration count
490              
491             Values C<$enc_cek>, C<$cek>, C<$salt> and C<$kek> are binary octets.
492              
493             =head2 pbes2_key_unwrap
494              
495             PBES2 key unwrap algorithm as defined in L
496             (implements algorithms C, C, C).
497              
498             $cek = pbes2_key_unwrap($kek, $enc_cek, $alg, $salt, $iter);
499              
500             # params:
501             # $kek .. key encryption key (arbitrary length)
502             # $enc_cek .. encrypted content encryption key
503             # $alg .. algorithm name e.g. 'PBES2-HS256+A128KW' (see rfc7518)
504             # $salt .. pbkdf2 salt
505             # $iter .. pbkdf2 iteration count
506              
507             Values C<$enc_cek>, C<$cek>, C<$salt> and C<$kek> are binary octets.
508              
509             =head2 rsa_key_wrap
510              
511             PBES2 key wrap algorithm as defined in L and
512             L (implements algorithms C, C, C).
513              
514             $enc_cek = rsa_key_wrap($kek, $cek, $alg);
515              
516             # params:
517             # $kek .. RSA public key - Crypt::PK::RSA instance
518             # $cek .. content encryption key
519             # $alg .. algorithm name e.g. 'RSA-OAEP' (see rfc7518)
520              
521             Values C<$enc_cek> and C<$cek> are binary octets.
522              
523             =head2 rsa_key_unwrap
524              
525             PBES2 key wrap algorithm as defined in L and
526             L (implements algorithms C, C, C).
527              
528             $cek = rsa_key_unwrap($kek, $enc_cek, $alg);
529              
530             # params:
531             # $kek .. RSA private key - Crypt::PK::RSA instance
532             # $enc_cek .. encrypted content encryption key
533             # $alg .. algorithm name e.g. 'RSA-OAEP' (see rfc7518)
534              
535             Values C<$enc_cek> and C<$cek> are binary octets.
536              
537             =head2 ecdhaes_key_wrap
538              
539             ECDH+AESKW key agreement/wrap algorithm as defined in L
540             (implements algorithms C, C, C).
541              
542             ($enc_cek, $epk) = ecdhaes_key_wrap($kek, $cek, $alg, $apu, $apv);
543              
544             # params:
545             # $kek .. ECC public key - Crypt::PK::ECC|X25519 instance
546             # $cek .. content encryption key
547             # $alg .. algorithm name e.g. 'ECDH-ES+A256KW' (see rfc7518)
548             # optional params:
549             # $apu .. Agreement PartyUInfo Header Parameter
550             # $apv .. Agreement PartyVInfo Header Parameter
551              
552             Values C<$enc_cek> and C<$cek> are binary octets.
553              
554             =head2 ecdhaes_key_unwrap
555              
556             ECDH+AESKW key agreement/unwrap algorithm as defined in L
557             (implements algorithms C, C, C).
558              
559             $cek = ecdhaes_key_unwrap($kek, $enc_cek, $alg, $epk, $apu, $apv);
560              
561             # params:
562             # $kek .. ECC private key - Crypt::PK::ECC|X25519 instance
563             # $enc_cek .. encrypted content encryption key
564             # $alg .. algorithm name e.g. 'ECDH-ES+A256KW' (see rfc7518)
565             # $epk .. ephemeral ECC public key (JWK/JSON or Crypt::PK::ECC|X25519)
566             # optional params:
567             # $apu .. Agreement PartyUInfo Header Parameter
568             # $apv .. Agreement PartyVInfo Header Parameter
569              
570             Values C<$enc_cek> and C<$cek> are binary octets.
571              
572             =head2 ecdh_key_wrap
573              
574             ECDH (Ephememeral Static) key agreement/wrap algorithm as defined in L
575             (implements algorithm C).
576              
577             ($cek, $epk) = ecdh_key_wrap($kek, $enc, $apu, $apv);
578              
579             # params:
580             # $kek .. ECC public key - Crypt::PK::ECC|X25519 instance
581             # $enc .. encryption algorithm name e.g. 'A256GCM' (see rfc7518)
582             # optional params:
583             # $apu .. Agreement PartyUInfo Header Parameter
584             # $apv .. Agreement PartyVInfo Header Parameter
585              
586             Value C<$cek> - binary octets, C<$epk> JWK/JSON string with ephemeral ECC public key.
587              
588             =head2 ecdh_key_unwrap
589              
590             ECDH (Ephememeral Static) key agreement/unwrap algorithm as defined in L
591             (implements algorithm C).
592              
593             $cek = ecdh_key_unwrap($kek, $enc, $epk, $apu, $apv);
594              
595             # params:
596             # $kek .. ECC private key - Crypt::PK::ECC|X25519 instance
597             # $enc .. encryption algorithm name e.g. 'A256GCM' (see rfc7518)
598             # $epk .. ephemeral ECC public key (JWK/JSON or Crypt::PK::ECC|X25519)
599             # optional params:
600             # $apu .. Agreement PartyUInfo Header Parameter
601             # $apv .. Agreement PartyVInfo Header Parameter
602              
603             Value C<$cek> - binary octets.
604              
605             =head1 SEE ALSO
606              
607             L, L, L, L
608              
609             =head1 LICENSE
610              
611             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
612              
613             =head1 COPYRIGHT
614              
615             Copyright (c) 2015-2021 DCIT, a.s. L / Karel Miko