├── CONTRIBUTING ├── LICENSE ├── README ├── cfg ├── decrypt.cfg ├── encrypt_transport_crypt_off_128.cfg ├── encrypt_transport_crypt_off_128_empty.cfg ├── encrypt_transport_crypt_off_128_vc.cfg ├── encrypt_transport_crypt_off_256.cfg ├── encrypt_transport_no_crypt_off_128.cfg ├── encrypt_transport_no_crypt_off_128_vc.cfg ├── encrypt_transport_no_crypt_off_256.cfg ├── encrypt_tunnel_crypt_off_128.cfg ├── encrypt_tunnel_crypt_off_256.cfg ├── encrypt_tunnel_crypt_off_256_empty.cfg ├── encrypt_tunnel_crypt_off_256_vc.cfg ├── encrypt_tunnel_no_crypt_off_128.cfg ├── encrypt_tunnel_no_crypt_off_256.cfg └── encrypt_tunnel_no_crypt_off_256_vc.cfg ├── doc └── PSP_Arch_Spec.pdf ├── pcap ├── create_cleartext.sh ├── v4_cleartext.pcap ├── v4_cleartext_empty.pcap ├── v4_cleartext_empty_pcap.txt ├── v4_cleartext_pcap.txt ├── v6_cleartext.pcap ├── v6_cleartext_empty.pcap ├── v6_cleartext_empty_pcap.txt └── v6_cleartext_pcap.txt ├── rfc └── README ├── src ├── Makefile ├── create_pcap.c ├── psp.h ├── psp_decrypt.c └── psp_encrypt.c ├── test ├── all_tests.sh ├── v4_transport_crypt_off_128.sh ├── v4_transport_crypt_off_128_empty.sh ├── v4_transport_crypt_off_128_err.sh ├── v4_transport_crypt_off_128_vc.sh ├── v4_transport_crypt_off_256.sh ├── v4_transport_no_crypt_off_128.sh ├── v4_transport_no_crypt_off_128_vc.sh ├── v4_transport_no_crypt_off_256.sh ├── v4_tunnel_crypt_off_128.sh ├── v4_tunnel_crypt_off_256.sh ├── v4_tunnel_no_crypt_off_128.sh ├── v4_tunnel_no_crypt_off_256.sh ├── v6_transport_crypt_off_128.sh ├── v6_transport_crypt_off_256.sh ├── v6_transport_no_crypt_off_128.sh ├── v6_transport_no_crypt_off_256.sh ├── v6_tunnel_crypt_off_128.sh ├── v6_tunnel_crypt_off_256.sh ├── v6_tunnel_crypt_off_256_empty.sh ├── v6_tunnel_crypt_off_256_err.sh ├── v6_tunnel_crypt_off_256_vc.sh ├── v6_tunnel_no_crypt_off_128.sh ├── v6_tunnel_no_crypt_off_256.sh └── v6_tunnel_no_crypt_off_256_vc.sh └── wireshark └── psp.lua /CONTRIBUTING: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement (CLA). You (or your employer) retain the copyright to your 10 | contribution; this simply gives us permission to use and redistribute your 11 | contributions as part of the project. Head over to 12 | to see your current agreements on file or 13 | to sign a new one. 14 | 15 | You generally only need to submit a CLA once, so if you've already submitted one 16 | (even if it was for a different project), you probably don't need to do it 17 | again. 18 | 19 | ## Code Reviews 20 | 21 | All submissions, including submissions by project members, require review. We 22 | use GitHub pull requests for this purpose. Consult 23 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 24 | information on using pull requests. 25 | 26 | ## Community Guidelines 27 | 28 | This project follows 29 | [Google's Open Source Community Guidelines](https://opensource.google/conduct/). 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | psp-open-source project 3 | ======================= 4 | This is the README file for the psp-open-source project. The PSP Security 5 | Protocol (PSP) is a security protocol created by Google for encryption 6 | in transit. PSP uses several of the concepts from IPsec ESP to provide 7 | an encryption encapsulation layer on-top of IP that is streamlined and 8 | custom-built to address the requirements of large-scale data centers. PSP 9 | is described in the "PSP Architecture Specification", which can be found 10 | in the /doc subdirectory. 11 | 12 | The project also contains a reference software implementation written in 13 | the 'C' language and a suite of packet-level test cases. 14 | 15 | The project contains the following subdirectories: 16 | 17 | /src - source code for the reference software implementation 18 | 19 | /pcap - pcap files used for testing 20 | 21 | /cfg - configuration files used for testing 22 | 23 | /test - bash scripts that implement the suite of test cases 24 | 25 | /doc - documentation including the "PSP Architecture Specification" 26 | in .pdf format 27 | 28 | /wireshark - wireshark plugin for PSP 29 | 30 | A more detailed description of the subdirectories is provided below. 31 | 32 | /src 33 | ==== 34 | Contains 3 programs and a Makefile. All the executables are built by the 35 | 'make' command. The 3 programs are: 36 | 37 | create_pcap 38 | ----------- 39 | Creates a cleartext pcap file that can be used for testing. 40 | 41 | The created packets are of the form Eth-IP-UDP-Payload with 42 | a fixed size of 1434 octets (unless the -e option is specified). 43 | 44 | All of the created packets are for the same flow (i.e., they all have 45 | the same MAC addresses, IP addresses, and UDP port numbers). 46 | 47 | Command Line Args: 48 | [-n N] [-f file_name] [-i ver] [-e] 49 | 50 | N is the number of packets to create, defaults to 1 51 | 52 | file_name is the name of the pcap output file, 53 | defaults to "cleartext.pcap" 54 | 55 | ver is 4 or 6, 4 indicates create ipv4 packets, 56 | 6 indicates create ipv6 packets, default is 4 57 | 58 | the -e option indicates that empty packets are to be 59 | created, where empty means the size of the l4 payload is 0 60 | 61 | psp_encrypt 62 | ----------- 63 | Program to perform PSP encryption. 64 | 65 | Reads plaintext packets from a pcap input file. 66 | 67 | Performs the following for each packet: 68 | - Adds appropriate PSP encapsulation 69 | - Computes ICV 70 | - Encrypts data 71 | 72 | Then writes each PSP-encrypted packet to a pcap output 73 | 74 | Command Line Args: 75 | 76 | [-c psp_cfg_file_name] [-i in_file] [-o out_file] [-v] [-e] 77 | 78 | -v enables verbose mode 79 | 80 | -e forces a single bit error in each output packet, 81 | which will cause authentication to fail 82 | 83 | Defaults: 84 | psp_cfg_file: "psp_encrypt.cfg" 85 | in_file: "cleartext.pcap" 86 | out_file: "psp_encrypt.pcap" 87 | 88 | The format of the PSP encryption configuration file is: 89 | 90 | series of 32 hex bytes (e.g., 34 44 8a ...): Master Key 0 91 | series of 32 hex bytes (e.g., 56 39 52 ...): Master Key 1 92 | 32b hex value (e.g., 9A345678), msb selects master key: SPI 93 | encap string (either "transport" or "tunnel"): PSP Encap Mode 94 | crypro algorithm string 95 | (either "aes-gcm-128" or "aes-gcm-256"): Crypto Algorithm 96 | non-negative integer with units of 4 bytes (e.g., 1): Transport Mode 97 | Crypt Offset 98 | non-negative integer with units of 4 bytes (e.g., 6): IPv4 Tunnel Mode 99 | Crypt Offset 100 | non-negative integer with units of 4 bytes (e.g., 11): IPv6 Tunnel Mode 101 | Crypt Offset 102 | virtual cookie string (either "vc" or "no-vc") Include VC in 103 | PSP Header 104 | 105 | The program uses OpenSSL crypto libraries. 106 | 107 | psp_decrypt 108 | ----------- 109 | Program to perform PSP decryption. 110 | 111 | Reads PSP-encrypted packets from a pcap input file. 112 | 113 | Performs the following for each packet: 114 | - Removes the PSP encapsulation (supports transport and tunnel encaps) 115 | - Checks that ICV is correct 116 | - Decrypts data 117 | 118 | Then writes each cleartext packet to a pcap output 119 | 120 | Command Line Args: 121 | 122 | [-c psp_cfg_file_name] [-i input_file_name] [-o output_file_name] [-v] 123 | 124 | -v enables verbose mode 125 | 126 | Defaults: 127 | psp_cfg_file: "psp_decrypt.cfg" 128 | input_file_name: "psp_encrypt.pcap" 129 | output_file_name: "psp_decrypt.pcap" 130 | 131 | The format of the PSP encryption configuration file is: 132 | 133 | series of 32 hex bytes (e.g., 34 44 8a ...): Master Key 0 134 | series of 32 hex bytes (e.g., 56 39 52 ...): Master Key 1 135 | 136 | The program uses OpenSSL crypto libraries. 137 | 138 | /pcap 139 | ===== 140 | Contains the following files with cleartext packets created by the 141 | create_pcap program: 142 | 143 | v4_cleartext.pcap 144 | v6_cleartext.pcap 145 | v4_cleartext_empty.pcap 146 | v6_cleartext_empty.pcap 147 | 148 | The cleartext packets are used as input for the test cases. The 149 | files with the '_empty' suffix contain packets with an L4 payload 150 | size of 0 bytes. 151 | 152 | There is also '.txt' version of each cleartext pcap file. These files 153 | have names of the form 'v4_cleartext_pcap.txt'. The '.txt' files are 154 | created using 'tcpdump' as follows: 155 | 156 | tcpdump -qns 0 -xx -r v4_cleartext.pcap > v4_cleartext_pcap.txt 157 | 158 | The purpose of the '.txt' files is to enable a 'diff' of the files 159 | input to the test cases and the files output by the test cases. In 160 | general, the test cases operate as follows: 161 | 162 | - a cleartext packet is encrypted by psp_encrypt 163 | - the output from psp_encrypt is used as input to 164 | psp_decrypt 165 | - the output from psp_decrypt is compared against the 166 | original cleartext packet 167 | 168 | Other pcap files will be created in the /pcap subdirectory when the 169 | test cases execute. 170 | 171 | /cfg 172 | ==== 173 | Contains configuration files used as input to psp_encrypt and psp_decrypt. 174 | There are multiple configuration files with different values for the various 175 | test cases. 176 | 177 | /test 178 | ===== 179 | Contains a suite of test cases, which are described below. 180 | 181 | all_tests 182 | execute all the test cases 183 | 184 | v4_transport_crypt_off_128 185 | IPv4 input packet, transport mode encapsulation, 186 | encryption starts after L4 ports, AES-GCM-128, 187 | 188 | v4_transport_no_crypt_off_128 189 | same as v4_transport_crypt_off_128 except encryption starts 190 | afer PSP header 191 | 192 | v4_transport_crypt_off_128_vc 193 | same as v4_transport_crypt_off_128 except PSP header includes 194 | a Virtualization Cookie (VC) field 195 | 196 | v4_transport_no_crypt_off_128_vc 197 | same as v4_transport_no_crypt_off_128 except PSP header includes 198 | a VC field, in this test case the VC field is encrypted 199 | 200 | v4_transport_crypt_off_128_empty 201 | similar to v4_transport_crypt_off_128 except size of L4 payload 202 | is 0 bytes and crypt off is configured such that no encryption 203 | is performed only authentication 204 | 205 | v4_transport_crypt_off_256 206 | same as v4_transport_crypt_off_128 except uses AES-GCM-256 207 | 208 | v4_transport_no_crypt_off_256 209 | same as v4_transport_no_crypt_off_128 except uses AES-GCM-256 210 | 211 | v4_transport_crypt_off_128_err 212 | a single bit error is forced in the packet after encryption and 213 | ICV computation, the expected result is an authentication failure 214 | 215 | v4_tunnel_crypt_off_128 216 | v4_tunnel_no_crypt_off_128 217 | v4_tunnel_crypt_off_256 218 | v4_tunnel_no_crypt_off_256 219 | same as transport mode tests with similar names except that 220 | tunnel mode encapsulation is used 221 | 222 | v6_transport_crypt_off_128 223 | v6_transport_no_crypt_off_128 224 | v6_transport_crypt_off_256 225 | v6_transport_no_crypt_off_256 226 | v6_tunnel_crypt_off_128 227 | v6_tunnel_no_crypt_off_128 228 | v6_tunnel_crypt_off_256 229 | v6_tunnel_no_crypt_off_256 230 | v6_tunnel_crypt_off_256_vc 231 | v6_tunnel_no_crypt_off_256_vc 232 | v6_tunnel_crypt_off_256_empty 233 | v6_tunnel_crypt_off_256_err 234 | same as IPv4 tests with similar names except that IPv6 input 235 | packet is used 236 | -------------------------------------------------------------------------------- /cfg/decrypt.cfg: -------------------------------------------------------------------------------- 1 | 34 44 8a 06 42 92 60 1b 11 a0 97 8f 56 a2 d3 4c f3 fc 35 ed e1 a6 bc 04 f8 db 3e 52 43 a2 b0 ca 2 | 56 39 52 56 5d 3a 78 ae 77 3e c1 b7 79 f2 f2 d9 9f 4a 7f 53 a6 fb b9 b0 7d 5b 71 f3 93 64 d7 39 3 | -------------------------------------------------------------------------------- /cfg/encrypt_transport_crypt_off_128.cfg: -------------------------------------------------------------------------------- 1 | 34 44 8a 06 42 92 60 1b 11 a0 97 8f 56 a2 d3 4c f3 fc 35 ed e1 a6 bc 04 f8 db 3e 52 43 a2 b0 ca 2 | 56 39 52 56 5d 3a 78 ae 77 3e c1 b7 79 f2 f2 d9 9f 4a 7f 53 a6 fb b9 b0 7d 5b 71 f3 93 64 d7 39 3 | 9A345678 4 | transport 5 | aes-gcm-128 6 | 1 7 | 6 8 | 11 9 | no-vc 10 | -------------------------------------------------------------------------------- /cfg/encrypt_transport_crypt_off_128_empty.cfg: -------------------------------------------------------------------------------- 1 | 34 44 8a 06 42 92 60 1b 11 a0 97 8f 56 a2 d3 4c f3 fc 35 ed e1 a6 bc 04 f8 db 3e 52 43 a2 b0 ca 2 | 56 39 52 56 5d 3a 78 ae 77 3e c1 b7 79 f2 f2 d9 9f 4a 7f 53 a6 fb b9 b0 7d 5b 71 f3 93 64 d7 39 3 | 9A345678 4 | transport 5 | aes-gcm-128 6 | 2 7 | 7 8 | 12 9 | no-vc 10 | -------------------------------------------------------------------------------- /cfg/encrypt_transport_crypt_off_128_vc.cfg: -------------------------------------------------------------------------------- 1 | 34 44 8a 06 42 92 60 1b 11 a0 97 8f 56 a2 d3 4c f3 fc 35 ed e1 a6 bc 04 f8 db 3e 52 43 a2 b0 ca 2 | 56 39 52 56 5d 3a 78 ae 77 3e c1 b7 79 f2 f2 d9 9f 4a 7f 53 a6 fb b9 b0 7d 5b 71 f3 93 64 d7 39 3 | 9A345678 4 | transport 5 | aes-gcm-128 6 | 3 7 | 8 8 | 13 9 | vc 10 | -------------------------------------------------------------------------------- /cfg/encrypt_transport_crypt_off_256.cfg: -------------------------------------------------------------------------------- 1 | 34 44 8a 06 42 92 60 1b 11 a0 97 8f 56 a2 d3 4c f3 fc 35 ed e1 a6 bc 04 f8 db 3e 52 43 a2 b0 ca 2 | 56 39 52 56 5d 3a 78 ae 77 3e c1 b7 79 f2 f2 d9 9f 4a 7f 53 a6 fb b9 b0 7d 5b 71 f3 93 64 d7 39 3 | 9A345678 4 | transport 5 | aes-gcm-256 6 | 1 7 | 6 8 | 11 9 | no-vc 10 | -------------------------------------------------------------------------------- /cfg/encrypt_transport_no_crypt_off_128.cfg: -------------------------------------------------------------------------------- 1 | 34 44 8a 06 42 92 60 1b 11 a0 97 8f 56 a2 d3 4c f3 fc 35 ed e1 a6 bc 04 f8 db 3e 52 43 a2 b0 ca 2 | 56 39 52 56 5d 3a 78 ae 77 3e c1 b7 79 f2 f2 d9 9f 4a 7f 53 a6 fb b9 b0 7d 5b 71 f3 93 64 d7 39 3 | 1A345678 4 | transport 5 | aes-gcm-128 6 | 0 7 | 0 8 | 0 9 | no-vc 10 | -------------------------------------------------------------------------------- /cfg/encrypt_transport_no_crypt_off_128_vc.cfg: -------------------------------------------------------------------------------- 1 | 34 44 8a 06 42 92 60 1b 11 a0 97 8f 56 a2 d3 4c f3 fc 35 ed e1 a6 bc 04 f8 db 3e 52 43 a2 b0 ca 2 | 56 39 52 56 5d 3a 78 ae 77 3e c1 b7 79 f2 f2 d9 9f 4a 7f 53 a6 fb b9 b0 7d 5b 71 f3 93 64 d7 39 3 | 9A345678 4 | transport 5 | aes-gcm-128 6 | 0 7 | 0 8 | 0 9 | vc 10 | -------------------------------------------------------------------------------- /cfg/encrypt_transport_no_crypt_off_256.cfg: -------------------------------------------------------------------------------- 1 | 34 44 8a 06 42 92 60 1b 11 a0 97 8f 56 a2 d3 4c f3 fc 35 ed e1 a6 bc 04 f8 db 3e 52 43 a2 b0 ca 2 | 56 39 52 56 5d 3a 78 ae 77 3e c1 b7 79 f2 f2 d9 9f 4a 7f 53 a6 fb b9 b0 7d 5b 71 f3 93 64 d7 39 3 | 1A345678 4 | transport 5 | aes-gcm-256 6 | 0 7 | 0 8 | 0 9 | no-vc 10 | -------------------------------------------------------------------------------- /cfg/encrypt_tunnel_crypt_off_128.cfg: -------------------------------------------------------------------------------- 1 | 34 44 8a 06 42 92 60 1b 11 a0 97 8f 56 a2 d3 4c f3 fc 35 ed e1 a6 bc 04 f8 db 3e 52 43 a2 b0 ca 2 | 56 39 52 56 5d 3a 78 ae 77 3e c1 b7 79 f2 f2 d9 9f 4a 7f 53 a6 fb b9 b0 7d 5b 71 f3 93 64 d7 39 3 | 1A345678 4 | tunnel 5 | aes-gcm-128 6 | 1 7 | 6 8 | 11 9 | no-vc 10 | -------------------------------------------------------------------------------- /cfg/encrypt_tunnel_crypt_off_256.cfg: -------------------------------------------------------------------------------- 1 | 34 44 8a 06 42 92 60 1b 11 a0 97 8f 56 a2 d3 4c f3 fc 35 ed e1 a6 bc 04 f8 db 3e 52 43 a2 b0 ca 2 | 56 39 52 56 5d 3a 78 ae 77 3e c1 b7 79 f2 f2 d9 9f 4a 7f 53 a6 fb b9 b0 7d 5b 71 f3 93 64 d7 39 3 | 1A345678 4 | tunnel 5 | aes-gcm-256 6 | 1 7 | 6 8 | 11 9 | no-vc 10 | -------------------------------------------------------------------------------- /cfg/encrypt_tunnel_crypt_off_256_empty.cfg: -------------------------------------------------------------------------------- 1 | 34 44 8a 06 42 92 60 1b 11 a0 97 8f 56 a2 d3 4c f3 fc 35 ed e1 a6 bc 04 f8 db 3e 52 43 a2 b0 ca 2 | 56 39 52 56 5d 3a 78 ae 77 3e c1 b7 79 f2 f2 d9 9f 4a 7f 53 a6 fb b9 b0 7d 5b 71 f3 93 64 d7 39 3 | 1A345678 4 | tunnel 5 | aes-gcm-256 6 | 2 7 | 7 8 | 12 9 | no-vc 10 | -------------------------------------------------------------------------------- /cfg/encrypt_tunnel_crypt_off_256_vc.cfg: -------------------------------------------------------------------------------- 1 | 34 44 8a 06 42 92 60 1b 11 a0 97 8f 56 a2 d3 4c f3 fc 35 ed e1 a6 bc 04 f8 db 3e 52 43 a2 b0 ca 2 | 56 39 52 56 5d 3a 78 ae 77 3e c1 b7 79 f2 f2 d9 9f 4a 7f 53 a6 fb b9 b0 7d 5b 71 f3 93 64 d7 39 3 | 1A345678 4 | tunnel 5 | aes-gcm-256 6 | 3 7 | 8 8 | 13 9 | vc 10 | -------------------------------------------------------------------------------- /cfg/encrypt_tunnel_no_crypt_off_128.cfg: -------------------------------------------------------------------------------- 1 | 34 44 8a 06 42 92 60 1b 11 a0 97 8f 56 a2 d3 4c f3 fc 35 ed e1 a6 bc 04 f8 db 3e 52 43 a2 b0 ca 2 | 56 39 52 56 5d 3a 78 ae 77 3e c1 b7 79 f2 f2 d9 9f 4a 7f 53 a6 fb b9 b0 7d 5b 71 f3 93 64 d7 39 3 | 9A345678 4 | tunnel 5 | aes-gcm-128 6 | 0 7 | 0 8 | 0 9 | no-vc 10 | -------------------------------------------------------------------------------- /cfg/encrypt_tunnel_no_crypt_off_256.cfg: -------------------------------------------------------------------------------- 1 | 34 44 8a 06 42 92 60 1b 11 a0 97 8f 56 a2 d3 4c f3 fc 35 ed e1 a6 bc 04 f8 db 3e 52 43 a2 b0 ca 2 | 56 39 52 56 5d 3a 78 ae 77 3e c1 b7 79 f2 f2 d9 9f 4a 7f 53 a6 fb b9 b0 7d 5b 71 f3 93 64 d7 39 3 | 9A345678 4 | tunnel 5 | aes-gcm-256 6 | 0 7 | 0 8 | 0 9 | no-vc 10 | -------------------------------------------------------------------------------- /cfg/encrypt_tunnel_no_crypt_off_256_vc.cfg: -------------------------------------------------------------------------------- 1 | 34 44 8a 06 42 92 60 1b 11 a0 97 8f 56 a2 d3 4c f3 fc 35 ed e1 a6 bc 04 f8 db 3e 52 43 a2 b0 ca 2 | 56 39 52 56 5d 3a 78 ae 77 3e c1 b7 79 f2 f2 d9 9f 4a 7f 53 a6 fb b9 b0 7d 5b 71 f3 93 64 d7 39 3 | 1A345678 4 | tunnel 5 | aes-gcm-256 6 | 0 7 | 0 8 | 0 9 | vc 10 | -------------------------------------------------------------------------------- /doc/PSP_Arch_Spec.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/psp/8ac5fc19be57fbff18f44bb0b1d8e91c34b7260a/doc/PSP_Arch_Spec.pdf -------------------------------------------------------------------------------- /pcap/create_cleartext.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ../src/create_pcap -f ../pcap/v4_cleartext.pcap 18 | tcpdump -qnts 0 -xx -r ./v4_cleartext.pcap > ./v4_cleartext_pcap.txt 19 | 20 | ../src/create_pcap -f ../pcap/v4_cleartext_empty.pcap -e 21 | tcpdump -qnts 0 -xx -r ./v4_cleartext_empty.pcap > ./v4_cleartext_empty_pcap.txt 22 | 23 | ../src/create_pcap -f ../pcap/v6_cleartext.pcap -i 6 24 | tcpdump -qnts 0 -xx -r ./v6_cleartext.pcap > ./v6_cleartext_pcap.txt 25 | 26 | ../src/create_pcap -f ../pcap/v6_cleartext_empty.pcap -i 6 -e 27 | tcpdump -qnts 0 -xx -r ./v6_cleartext_empty.pcap > ./v6_cleartext_empty_pcap.txt 28 | -------------------------------------------------------------------------------- /pcap/v4_cleartext.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/psp/8ac5fc19be57fbff18f44bb0b1d8e91c34b7260a/pcap/v4_cleartext.pcap -------------------------------------------------------------------------------- /pcap/v4_cleartext_empty.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/psp/8ac5fc19be57fbff18f44bb0b1d8e91c34b7260a/pcap/v4_cleartext_empty.pcap -------------------------------------------------------------------------------- /pcap/v4_cleartext_empty_pcap.txt: -------------------------------------------------------------------------------- 1 | IP 10.0.0.1.11111 > 10.0.0.2.22222: UDP, length 0 2 | 0x0000: 0088 99aa bb00 0022 3344 5500 0800 4500 3 | 0x0010: 001c 0000 4000 4011 26cf 0a00 0001 0a00 4 | 0x0020: 0002 2b67 56ce 0008 69a6 5 | -------------------------------------------------------------------------------- /pcap/v4_cleartext_pcap.txt: -------------------------------------------------------------------------------- 1 | IP 10.0.0.1.11111 > 10.0.0.2.22222: UDP, length 1392 2 | 0x0000: 0088 99aa bb00 0022 3344 5500 0800 4500 3 | 0x0010: 058c 0000 4000 4011 215f 0a00 0001 0a00 4 | 0x0020: 0002 2b67 56ce 0578 893b 0001 0203 0405 5 | 0x0030: 0607 0809 0a0b 0c0d 0e0f 1011 1213 1415 6 | 0x0040: 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 7 | 0x0050: 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 8 | 0x0060: 3637 3839 3a3b 3c3d 3e3f 4041 4243 4445 9 | 0x0070: 4647 4849 4a4b 4c4d 4e4f 5051 5253 5455 10 | 0x0080: 5657 5859 5a5b 5c5d 5e5f 6061 6263 6465 11 | 0x0090: 6667 6869 6a6b 6c6d 6e6f 7071 7273 7475 12 | 0x00a0: 7677 7879 7a7b 7c7d 7e7f 8081 8283 8485 13 | 0x00b0: 8687 8889 8a8b 8c8d 8e8f 9091 9293 9495 14 | 0x00c0: 9697 9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 15 | 0x00d0: a6a7 a8a9 aaab acad aeaf b0b1 b2b3 b4b5 16 | 0x00e0: b6b7 b8b9 babb bcbd bebf c0c1 c2c3 c4c5 17 | 0x00f0: c6c7 c8c9 cacb cccd cecf d0d1 d2d3 d4d5 18 | 0x0100: d6d7 d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 19 | 0x0110: e6e7 e8e9 eaeb eced eeef f0f1 f2f3 f4f5 20 | 0x0120: f6f7 f8f9 fafb fcfd feff 0001 0203 0405 21 | 0x0130: 0607 0809 0a0b 0c0d 0e0f 1011 1213 1415 22 | 0x0140: 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 23 | 0x0150: 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 24 | 0x0160: 3637 3839 3a3b 3c3d 3e3f 4041 4243 4445 25 | 0x0170: 4647 4849 4a4b 4c4d 4e4f 5051 5253 5455 26 | 0x0180: 5657 5859 5a5b 5c5d 5e5f 6061 6263 6465 27 | 0x0190: 6667 6869 6a6b 6c6d 6e6f 7071 7273 7475 28 | 0x01a0: 7677 7879 7a7b 7c7d 7e7f 8081 8283 8485 29 | 0x01b0: 8687 8889 8a8b 8c8d 8e8f 9091 9293 9495 30 | 0x01c0: 9697 9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 31 | 0x01d0: a6a7 a8a9 aaab acad aeaf b0b1 b2b3 b4b5 32 | 0x01e0: b6b7 b8b9 babb bcbd bebf c0c1 c2c3 c4c5 33 | 0x01f0: c6c7 c8c9 cacb cccd cecf d0d1 d2d3 d4d5 34 | 0x0200: d6d7 d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 35 | 0x0210: e6e7 e8e9 eaeb eced eeef f0f1 f2f3 f4f5 36 | 0x0220: f6f7 f8f9 fafb fcfd feff 0001 0203 0405 37 | 0x0230: 0607 0809 0a0b 0c0d 0e0f 1011 1213 1415 38 | 0x0240: 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 39 | 0x0250: 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 40 | 0x0260: 3637 3839 3a3b 3c3d 3e3f 4041 4243 4445 41 | 0x0270: 4647 4849 4a4b 4c4d 4e4f 5051 5253 5455 42 | 0x0280: 5657 5859 5a5b 5c5d 5e5f 6061 6263 6465 43 | 0x0290: 6667 6869 6a6b 6c6d 6e6f 7071 7273 7475 44 | 0x02a0: 7677 7879 7a7b 7c7d 7e7f 8081 8283 8485 45 | 0x02b0: 8687 8889 8a8b 8c8d 8e8f 9091 9293 9495 46 | 0x02c0: 9697 9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 47 | 0x02d0: a6a7 a8a9 aaab acad aeaf b0b1 b2b3 b4b5 48 | 0x02e0: b6b7 b8b9 babb bcbd bebf c0c1 c2c3 c4c5 49 | 0x02f0: c6c7 c8c9 cacb cccd cecf d0d1 d2d3 d4d5 50 | 0x0300: d6d7 d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 51 | 0x0310: e6e7 e8e9 eaeb eced eeef f0f1 f2f3 f4f5 52 | 0x0320: f6f7 f8f9 fafb fcfd feff 0001 0203 0405 53 | 0x0330: 0607 0809 0a0b 0c0d 0e0f 1011 1213 1415 54 | 0x0340: 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 55 | 0x0350: 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 56 | 0x0360: 3637 3839 3a3b 3c3d 3e3f 4041 4243 4445 57 | 0x0370: 4647 4849 4a4b 4c4d 4e4f 5051 5253 5455 58 | 0x0380: 5657 5859 5a5b 5c5d 5e5f 6061 6263 6465 59 | 0x0390: 6667 6869 6a6b 6c6d 6e6f 7071 7273 7475 60 | 0x03a0: 7677 7879 7a7b 7c7d 7e7f 8081 8283 8485 61 | 0x03b0: 8687 8889 8a8b 8c8d 8e8f 9091 9293 9495 62 | 0x03c0: 9697 9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 63 | 0x03d0: a6a7 a8a9 aaab acad aeaf b0b1 b2b3 b4b5 64 | 0x03e0: b6b7 b8b9 babb bcbd bebf c0c1 c2c3 c4c5 65 | 0x03f0: c6c7 c8c9 cacb cccd cecf d0d1 d2d3 d4d5 66 | 0x0400: d6d7 d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 67 | 0x0410: e6e7 e8e9 eaeb eced eeef f0f1 f2f3 f4f5 68 | 0x0420: f6f7 f8f9 fafb fcfd feff 0001 0203 0405 69 | 0x0430: 0607 0809 0a0b 0c0d 0e0f 1011 1213 1415 70 | 0x0440: 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 71 | 0x0450: 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 72 | 0x0460: 3637 3839 3a3b 3c3d 3e3f 4041 4243 4445 73 | 0x0470: 4647 4849 4a4b 4c4d 4e4f 5051 5253 5455 74 | 0x0480: 5657 5859 5a5b 5c5d 5e5f 6061 6263 6465 75 | 0x0490: 6667 6869 6a6b 6c6d 6e6f 7071 7273 7475 76 | 0x04a0: 7677 7879 7a7b 7c7d 7e7f 8081 8283 8485 77 | 0x04b0: 8687 8889 8a8b 8c8d 8e8f 9091 9293 9495 78 | 0x04c0: 9697 9899 9a9b 9c9d 9e9f a0a1 a2a3 a4a5 79 | 0x04d0: a6a7 a8a9 aaab acad aeaf b0b1 b2b3 b4b5 80 | 0x04e0: b6b7 b8b9 babb bcbd bebf c0c1 c2c3 c4c5 81 | 0x04f0: c6c7 c8c9 cacb cccd cecf d0d1 d2d3 d4d5 82 | 0x0500: d6d7 d8d9 dadb dcdd dedf e0e1 e2e3 e4e5 83 | 0x0510: e6e7 e8e9 eaeb eced eeef f0f1 f2f3 f4f5 84 | 0x0520: f6f7 f8f9 fafb fcfd feff 0001 0203 0405 85 | 0x0530: 0607 0809 0a0b 0c0d 0e0f 1011 1213 1415 86 | 0x0540: 1617 1819 1a1b 1c1d 1e1f 2021 2223 2425 87 | 0x0550: 2627 2829 2a2b 2c2d 2e2f 3031 3233 3435 88 | 0x0560: 3637 3839 3a3b 3c3d 3e3f 4041 4243 4445 89 | 0x0570: 4647 4849 4a4b 4c4d 4e4f 5051 5253 5455 90 | 0x0580: 5657 5859 5a5b 5c5d 5e5f 6061 6263 6465 91 | 0x0590: 6667 6869 6a6b 6c6d 6e6f 92 | -------------------------------------------------------------------------------- /pcap/v6_cleartext.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/psp/8ac5fc19be57fbff18f44bb0b1d8e91c34b7260a/pcap/v6_cleartext.pcap -------------------------------------------------------------------------------- /pcap/v6_cleartext_empty.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/psp/8ac5fc19be57fbff18f44bb0b1d8e91c34b7260a/pcap/v6_cleartext_empty.pcap -------------------------------------------------------------------------------- /pcap/v6_cleartext_empty_pcap.txt: -------------------------------------------------------------------------------- 1 | IP6 a00::1.11111 > a00::2.22222: UDP, length 0 2 | 0x0000: 0088 99aa bb00 0022 3344 5500 86dd 6000 3 | 0x0010: 0000 0008 1140 0a00 0000 0000 0000 0000 4 | 0x0020: 0000 0000 0001 0a00 0000 0000 0000 0000 5 | 0x0030: 0000 0000 0002 2b67 56ce 0008 69a6 6 | -------------------------------------------------------------------------------- /pcap/v6_cleartext_pcap.txt: -------------------------------------------------------------------------------- 1 | IP6 a00::1.11111 > a00::2.22222: UDP, length 1372 2 | 0x0000: 0088 99aa bb00 0022 3344 5500 86dd 6000 3 | 0x0010: 0000 0564 1140 0a00 0000 0000 0000 0000 4 | 0x0020: 0000 0000 0001 0a00 0000 0000 0000 0000 5 | 0x0030: 0000 0000 0002 2b67 56ce 0564 7f63 0001 6 | 0x0040: 0203 0405 0607 0809 0a0b 0c0d 0e0f 1011 7 | 0x0050: 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 8 | 0x0060: 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 9 | 0x0070: 3233 3435 3637 3839 3a3b 3c3d 3e3f 4041 10 | 0x0080: 4243 4445 4647 4849 4a4b 4c4d 4e4f 5051 11 | 0x0090: 5253 5455 5657 5859 5a5b 5c5d 5e5f 6061 12 | 0x00a0: 6263 6465 6667 6869 6a6b 6c6d 6e6f 7071 13 | 0x00b0: 7273 7475 7677 7879 7a7b 7c7d 7e7f 8081 14 | 0x00c0: 8283 8485 8687 8889 8a8b 8c8d 8e8f 9091 15 | 0x00d0: 9293 9495 9697 9899 9a9b 9c9d 9e9f a0a1 16 | 0x00e0: a2a3 a4a5 a6a7 a8a9 aaab acad aeaf b0b1 17 | 0x00f0: b2b3 b4b5 b6b7 b8b9 babb bcbd bebf c0c1 18 | 0x0100: c2c3 c4c5 c6c7 c8c9 cacb cccd cecf d0d1 19 | 0x0110: d2d3 d4d5 d6d7 d8d9 dadb dcdd dedf e0e1 20 | 0x0120: e2e3 e4e5 e6e7 e8e9 eaeb eced eeef f0f1 21 | 0x0130: f2f3 f4f5 f6f7 f8f9 fafb fcfd feff 0001 22 | 0x0140: 0203 0405 0607 0809 0a0b 0c0d 0e0f 1011 23 | 0x0150: 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 24 | 0x0160: 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 25 | 0x0170: 3233 3435 3637 3839 3a3b 3c3d 3e3f 4041 26 | 0x0180: 4243 4445 4647 4849 4a4b 4c4d 4e4f 5051 27 | 0x0190: 5253 5455 5657 5859 5a5b 5c5d 5e5f 6061 28 | 0x01a0: 6263 6465 6667 6869 6a6b 6c6d 6e6f 7071 29 | 0x01b0: 7273 7475 7677 7879 7a7b 7c7d 7e7f 8081 30 | 0x01c0: 8283 8485 8687 8889 8a8b 8c8d 8e8f 9091 31 | 0x01d0: 9293 9495 9697 9899 9a9b 9c9d 9e9f a0a1 32 | 0x01e0: a2a3 a4a5 a6a7 a8a9 aaab acad aeaf b0b1 33 | 0x01f0: b2b3 b4b5 b6b7 b8b9 babb bcbd bebf c0c1 34 | 0x0200: c2c3 c4c5 c6c7 c8c9 cacb cccd cecf d0d1 35 | 0x0210: d2d3 d4d5 d6d7 d8d9 dadb dcdd dedf e0e1 36 | 0x0220: e2e3 e4e5 e6e7 e8e9 eaeb eced eeef f0f1 37 | 0x0230: f2f3 f4f5 f6f7 f8f9 fafb fcfd feff 0001 38 | 0x0240: 0203 0405 0607 0809 0a0b 0c0d 0e0f 1011 39 | 0x0250: 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 40 | 0x0260: 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 41 | 0x0270: 3233 3435 3637 3839 3a3b 3c3d 3e3f 4041 42 | 0x0280: 4243 4445 4647 4849 4a4b 4c4d 4e4f 5051 43 | 0x0290: 5253 5455 5657 5859 5a5b 5c5d 5e5f 6061 44 | 0x02a0: 6263 6465 6667 6869 6a6b 6c6d 6e6f 7071 45 | 0x02b0: 7273 7475 7677 7879 7a7b 7c7d 7e7f 8081 46 | 0x02c0: 8283 8485 8687 8889 8a8b 8c8d 8e8f 9091 47 | 0x02d0: 9293 9495 9697 9899 9a9b 9c9d 9e9f a0a1 48 | 0x02e0: a2a3 a4a5 a6a7 a8a9 aaab acad aeaf b0b1 49 | 0x02f0: b2b3 b4b5 b6b7 b8b9 babb bcbd bebf c0c1 50 | 0x0300: c2c3 c4c5 c6c7 c8c9 cacb cccd cecf d0d1 51 | 0x0310: d2d3 d4d5 d6d7 d8d9 dadb dcdd dedf e0e1 52 | 0x0320: e2e3 e4e5 e6e7 e8e9 eaeb eced eeef f0f1 53 | 0x0330: f2f3 f4f5 f6f7 f8f9 fafb fcfd feff 0001 54 | 0x0340: 0203 0405 0607 0809 0a0b 0c0d 0e0f 1011 55 | 0x0350: 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 56 | 0x0360: 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 57 | 0x0370: 3233 3435 3637 3839 3a3b 3c3d 3e3f 4041 58 | 0x0380: 4243 4445 4647 4849 4a4b 4c4d 4e4f 5051 59 | 0x0390: 5253 5455 5657 5859 5a5b 5c5d 5e5f 6061 60 | 0x03a0: 6263 6465 6667 6869 6a6b 6c6d 6e6f 7071 61 | 0x03b0: 7273 7475 7677 7879 7a7b 7c7d 7e7f 8081 62 | 0x03c0: 8283 8485 8687 8889 8a8b 8c8d 8e8f 9091 63 | 0x03d0: 9293 9495 9697 9899 9a9b 9c9d 9e9f a0a1 64 | 0x03e0: a2a3 a4a5 a6a7 a8a9 aaab acad aeaf b0b1 65 | 0x03f0: b2b3 b4b5 b6b7 b8b9 babb bcbd bebf c0c1 66 | 0x0400: c2c3 c4c5 c6c7 c8c9 cacb cccd cecf d0d1 67 | 0x0410: d2d3 d4d5 d6d7 d8d9 dadb dcdd dedf e0e1 68 | 0x0420: e2e3 e4e5 e6e7 e8e9 eaeb eced eeef f0f1 69 | 0x0430: f2f3 f4f5 f6f7 f8f9 fafb fcfd feff 0001 70 | 0x0440: 0203 0405 0607 0809 0a0b 0c0d 0e0f 1011 71 | 0x0450: 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 72 | 0x0460: 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 73 | 0x0470: 3233 3435 3637 3839 3a3b 3c3d 3e3f 4041 74 | 0x0480: 4243 4445 4647 4849 4a4b 4c4d 4e4f 5051 75 | 0x0490: 5253 5455 5657 5859 5a5b 5c5d 5e5f 6061 76 | 0x04a0: 6263 6465 6667 6869 6a6b 6c6d 6e6f 7071 77 | 0x04b0: 7273 7475 7677 7879 7a7b 7c7d 7e7f 8081 78 | 0x04c0: 8283 8485 8687 8889 8a8b 8c8d 8e8f 9091 79 | 0x04d0: 9293 9495 9697 9899 9a9b 9c9d 9e9f a0a1 80 | 0x04e0: a2a3 a4a5 a6a7 a8a9 aaab acad aeaf b0b1 81 | 0x04f0: b2b3 b4b5 b6b7 b8b9 babb bcbd bebf c0c1 82 | 0x0500: c2c3 c4c5 c6c7 c8c9 cacb cccd cecf d0d1 83 | 0x0510: d2d3 d4d5 d6d7 d8d9 dadb dcdd dedf e0e1 84 | 0x0520: e2e3 e4e5 e6e7 e8e9 eaeb eced eeef f0f1 85 | 0x0530: f2f3 f4f5 f6f7 f8f9 fafb fcfd feff 0001 86 | 0x0540: 0203 0405 0607 0809 0a0b 0c0d 0e0f 1011 87 | 0x0550: 1213 1415 1617 1819 1a1b 1c1d 1e1f 2021 88 | 0x0560: 2223 2425 2627 2829 2a2b 2c2d 2e2f 3031 89 | 0x0570: 3233 3435 3637 3839 3a3b 3c3d 3e3f 4041 90 | 0x0580: 4243 4445 4647 4849 4a4b 4c4d 4e4f 5051 91 | 0x0590: 5253 5455 5657 5859 5a5b 92 | -------------------------------------------------------------------------------- /rfc/README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/psp/8ac5fc19be57fbff18f44bb0b1d8e91c34b7260a/rfc/README -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2022 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | CC = gcc 16 | CFLAGS = -Wall 17 | 18 | LIBS = -lpcap -lssl -lcrypto 19 | 20 | all: create_pcap psp_encrypt psp_decrypt 21 | 22 | create_pcap: create_pcap.c psp.h 23 | $(CC) $(CFLAGS) create_pcap.c -o create_pcap -lpcap 24 | 25 | psp_encrypt: psp_encrypt.c psp.h 26 | $(CC) $(CFLAGS) psp_encrypt.c -o psp_encrypt $(LIBS) 27 | 28 | psp_decrypt: psp_decrypt.c psp.h 29 | $(CC) $(CFLAGS) psp_decrypt.c -o psp_decrypt $(LIBS) 30 | 31 | clean: 32 | rm -f create_pcap psp_encrypt psp_decrypt 33 | -------------------------------------------------------------------------------- /src/create_pcap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Program to create a pcap file containing cleartext packets 3 | * for testing purposes 4 | * 5 | * The created packets are of the form Eth-IP-UDP-Payload with 6 | * a fixed size of 1434 octets (unless the -e option is specified) 7 | * 8 | * All of the created packets are for the same flow (i.e., they all have 9 | * the same MAC addresses, IP addresses, and UDP port numbers) 10 | * 11 | * Command Line Args: 12 | * [-n N] [-f file_name] [-i ver] [-e] 13 | * 14 | * N is the number of packets to create, defaults to 1 15 | * 16 | * file_name is the name of the pcap output file, 17 | * defaults to "cleartext.pcap" 18 | * 19 | * ver is 4 or 6, 4 indicates create ipv4 packets, 20 | * 6 indicates create ipv6 packets, default is 4 21 | * 22 | * the -e option indicates that empty packets are to be 23 | * created, where empty means the size of the l4 payload is 0 24 | * 25 | * Copyright 2022 Google LLC 26 | * 27 | * Licensed under the Apache License, Version 2.0 (the "License"); 28 | * you may not use this file except in compliance with the License. 29 | * You may obtain a copy of the License at 30 | * 31 | * https://www.apache.org/licenses/LICENSE-2.0 32 | * 33 | * Unless required by applicable law or agreed to in writing, software 34 | * distributed under the License is distributed on an "AS IS" BASIS, 35 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 36 | * See the License for the specific language governing permissions and 37 | * limitations under the License. 38 | */ 39 | 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | 49 | #include "psp.h" 50 | 51 | #define IPV4 4 52 | #define IPV6 6 53 | 54 | #define DEFAULT_N 1 55 | #define DEFAULT_IP_VER IPV4 56 | 57 | struct ipv4_pkt_hdrs { /* hdrs of plaintext ipv4 packet */ 58 | struct eth_hdr eth; 59 | struct ipv4_hdr ipv4; 60 | struct udp_hdr udp; 61 | } PACKED; 62 | 63 | struct ipv4_pkt { /* plaintext ipv4 packet */ 64 | struct eth_hdr eth; 65 | struct ipv4_hdr ipv4; 66 | struct udp_hdr udp; 67 | uint8_t payload[0]; 68 | } PACKED; 69 | 70 | /* size of payload for plaintext ipv4 packet */ 71 | #define IPV4_PAYLOAD_OCTETS \ 72 | (ETH_MAX_OCTETS - (sizeof(struct ipv4_pkt_hdrs) + sizeof(struct psp_hdr) + \ 73 | sizeof(struct ipv6_hdr) + /* for tunnel mode */ \ 74 | sizeof(struct udp_hdr) + /* for PSP encap */ \ 75 | sizeof(struct psp_trailer))) 76 | 77 | /* size of plaintext ipv4 packet */ 78 | #define IPV4_PKT_OCTETS (sizeof(struct ipv4_pkt) + IPV4_PAYLOAD_OCTETS) 79 | 80 | struct ipv6_pkt_hdrs { /* hdrs of plaintext ipv6 packet */ 81 | struct eth_hdr eth; 82 | struct ipv6_hdr ipv6; 83 | struct udp_hdr udp; 84 | } PACKED; 85 | 86 | struct ipv6_pkt { /* plaintext ipv6 packet */ 87 | struct eth_hdr eth; 88 | struct ipv6_hdr ipv6; 89 | struct udp_hdr udp; 90 | uint8_t payload[0]; 91 | } PACKED; 92 | 93 | /* size of payload for plaintext ipv6 packet */ 94 | #define IPV6_PAYLOAD_OCTETS \ 95 | (ETH_MAX_OCTETS - (sizeof(struct ipv6_pkt_hdrs) + sizeof(struct psp_hdr) + \ 96 | sizeof(struct ipv6_hdr) + /* for tunnel mode */ \ 97 | sizeof(struct udp_hdr) + /* for PSP encap */ \ 98 | sizeof(struct psp_trailer))) 99 | 100 | /* size of plaintext ipv6 packet */ 101 | #define IPV6_PKT_OCTETS (sizeof(struct ipv6_pkt) + IPV6_PAYLOAD_OCTETS) 102 | 103 | struct pkt { /* plaintext packet */ 104 | union { 105 | struct ipv4_pkt v4; 106 | struct ipv6_pkt v6; 107 | } PACKED; 108 | } PACKED; 109 | 110 | /* MAC addresses for packets */ 111 | char smac[MAC_ADDR_OCTETS] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x00}; 112 | char dmac[MAC_ADDR_OCTETS] = {0x00, 0x88, 0x99, 0xAA, 0xBB, 0x00}; 113 | 114 | /* IPv4 addresses for packets */ 115 | uint32_t sip4 = ((10 << 24) + (0 << 16) + (0 << 8) + 1); 116 | uint32_t dip4 = ((10 << 24) + (0 << 16) + (0 << 8) + 2); 117 | 118 | /* IPv6 addresses for packets */ 119 | uint8_t sip6[IPV6_ADDR_OCTETS] = {10, 0, 0, 0, 0, 0, 0, 0, 120 | 0, 0, 0, 0, 0, 0, 0, 1}; 121 | uint8_t dip6[IPV6_ADDR_OCTETS] = {10, 0, 0, 0, 0, 0, 0, 0, 122 | 0, 0, 0, 0, 0, 0, 0, 2}; 123 | 124 | /* port numbers for packets */ 125 | uint16_t sport = 11111; 126 | uint16_t dport = 22222; 127 | 128 | /* empty packet flag */ 129 | bool empty = false; 130 | 131 | /* 132 | * compute udp checksum for ipv4 packet 133 | * - ipv4 header and udp header are in network byte order, and 134 | * are initialized 135 | * - udp payload follows udp header 136 | */ 137 | #pragma GCC diagnostic push 138 | #pragma GCC diagnostic ignored "-Waddress-of-packed-member" 139 | static uint16_t ipv4_udp_csum(struct ipv4_pkt *pkt) { 140 | long sum = 0; 141 | uint16_t *p, len, odd_byte = 0, csum; 142 | int i; 143 | 144 | pkt->udp.csum = 0; 145 | p = (uint16_t *)(&pkt->udp); 146 | len = ntohs(pkt->udp.len); 147 | 148 | for (i = 0; i < (len / 2); i++) sum += p[i]; 149 | 150 | if (len & 1) { 151 | *((uint8_t *)(&odd_byte)) = *((uint8_t *)(&p[i])); 152 | sum += odd_byte; 153 | } 154 | 155 | /* include pseudo header */ 156 | p = (uint16_t *)(&pkt->ipv4.sip); 157 | sum += p[0]; 158 | sum += p[1]; 159 | sum += p[2]; 160 | sum += p[3]; 161 | 162 | sum += IP_PROTO_UDP << 8; 163 | sum += pkt->udp.len; 164 | 165 | while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16); 166 | 167 | csum = (uint16_t)~sum; 168 | if (csum == 0) csum = 0xffff; 169 | 170 | return csum; 171 | } 172 | 173 | /* 174 | * compute udp checksum for ipv6 packet 175 | * - ipv6 header and udp header are in network byte order, and 176 | * are initialized 177 | * - udp payload follows udp header 178 | */ 179 | static uint16_t ipv6_udp_csum(struct ipv6_pkt *pkt) { 180 | long sum = 0; 181 | uint16_t *p, len, odd_byte = 0, csum; 182 | int i; 183 | 184 | pkt->udp.csum = 0; 185 | p = (uint16_t *)(&pkt->udp); 186 | len = ntohs(pkt->udp.len); 187 | 188 | for (i = 0; i < (len / 2); i++) sum += p[i]; 189 | 190 | if (len & 1) { 191 | *((uint8_t *)(&odd_byte)) = *((uint8_t *)(&p[i])); 192 | sum += odd_byte; 193 | } 194 | 195 | /* include pseudo header */ 196 | p = (uint16_t *)(pkt->ipv6.sip); 197 | for (i = 0; i < IPV6_ADDR_OCTETS; i++) sum += p[i]; 198 | 199 | sum += IP_PROTO_UDP << 8; 200 | sum += pkt->udp.len; 201 | 202 | while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16); 203 | 204 | csum = (uint16_t)~sum; 205 | if (csum == 0) csum = 0xffff; 206 | 207 | return csum; 208 | } 209 | 210 | /* initialize packet headers */ 211 | static void init_ipv4_pkt_hdrs(struct ipv4_pkt *p) { 212 | uint16_t ip_len; 213 | 214 | memset(p, 0, sizeof(struct ipv4_pkt_hdrs)); 215 | 216 | memcpy(p->eth.dmac, dmac, MAC_ADDR_OCTETS); 217 | memcpy(p->eth.smac, smac, MAC_ADDR_OCTETS); 218 | p->eth.etype = htons(IPV4_ETYPE); 219 | 220 | p->ipv4.ver_ihl = IPV4_VER_IHL; 221 | if (empty) { 222 | ip_len = sizeof(struct ipv4_pkt_hdrs) - sizeof(struct eth_hdr); 223 | } else { 224 | ip_len = IPV4_PKT_OCTETS - sizeof(struct eth_hdr); 225 | } 226 | p->ipv4.len = htons(ip_len); 227 | p->ipv4.flags_offset = htons(IPV4_FLAGS_DF); 228 | p->ipv4.ttl = IP_TTL_DEF; 229 | p->ipv4.proto = IP_PROTO_UDP; 230 | p->ipv4.sip = htonl(sip4); 231 | p->ipv4.dip = htonl(dip4); 232 | p->ipv4.csum = ipv4_hdr_csum(&p->ipv4); 233 | 234 | p->udp.sport = htons(sport); 235 | p->udp.dport = htons(dport); 236 | p->udp.len = htons(ip_len - sizeof(struct ipv4_hdr)); 237 | p->udp.csum = 0; 238 | 239 | return; 240 | } 241 | #pragma GCC diagnostic pop 242 | 243 | static void init_ipv6_pkt_hdrs(struct ipv6_pkt *p) { 244 | uint16_t ip_len; 245 | 246 | memset(p, 0, sizeof(struct ipv6_pkt_hdrs)); 247 | 248 | memcpy(p->eth.dmac, dmac, MAC_ADDR_OCTETS); 249 | memcpy(p->eth.smac, smac, MAC_ADDR_OCTETS); 250 | p->eth.etype = htons(IPV6_ETYPE); 251 | 252 | p->ipv6.ver_tc_flow = htonl(IPV6_VER); 253 | if (empty) 254 | ip_len = sizeof(struct udp_hdr); 255 | else 256 | ip_len = IPV6_PKT_OCTETS - sizeof(struct eth_hdr) - sizeof(struct ipv6_hdr); 257 | p->ipv6.plen = htons(ip_len); 258 | p->ipv6.proto = IP_PROTO_UDP; 259 | p->ipv6.ttl = IP_TTL_DEF; 260 | memcpy(p->ipv6.sip, sip6, IPV6_ADDR_OCTETS); 261 | memcpy(p->ipv6.dip, dip6, IPV6_ADDR_OCTETS); 262 | 263 | p->udp.sport = htons(sport); 264 | p->udp.dport = htons(dport); 265 | p->udp.len = htons(ip_len); 266 | p->udp.csum = 0; 267 | 268 | return; 269 | } 270 | 271 | /* initialize packet payload */ 272 | static void init_pkt_payload(uint8_t *payload, int payload_octets, 273 | int packet_id) { 274 | int i; 275 | uint8_t octet = (uint8_t)packet_id; 276 | 277 | for (i = 0; i < payload_octets; i++) payload[i] = octet++; 278 | 279 | return; 280 | } 281 | 282 | int main(int argc, char *argv[]) { 283 | int opt, i, n = DEFAULT_N, ip_ver = DEFAULT_IP_VER, rc = EXIT_SUCCESS; 284 | int pkt_octets, payload_octets; 285 | pcap_t *pd = NULL; 286 | pcap_dumper_t *pdumper = NULL; 287 | char *pcap_file = DEFAULT_CLEARTEXT_PCAP_FILE; 288 | uint8_t *payload; 289 | struct pkt *p = NULL; 290 | struct ipv4_pkt *v4_pkt; 291 | struct ipv6_pkt *v6_pkt; 292 | struct pcap_pkthdr pcap_pkt_hdr; 293 | 294 | while ((opt = getopt(argc, argv, "n:f:i:e")) != -1) { 295 | switch (opt) { 296 | case 'e': 297 | empty = true; 298 | break; 299 | case 'n': 300 | n = atoi(optarg); 301 | break; 302 | case 'f': 303 | pcap_file = optarg; 304 | break; 305 | case 'i': 306 | ip_ver = atoi(optarg); 307 | if ((ip_ver == IPV4) || (ip_ver == IPV6)) break; 308 | fprintf(stderr, "Invalid ip_ver\n"); 309 | /* intentional fall-through */ 310 | default: 311 | fprintf(stderr, "Usage: %s [-n N] [-f file_name] [-i ver] [-e]\n", 312 | argv[0]); 313 | goto err_exit; 314 | break; 315 | } 316 | } 317 | 318 | if (ip_ver == IPV4) { 319 | pkt_octets = IPV4_PKT_OCTETS; 320 | } else { 321 | pkt_octets = IPV6_PKT_OCTETS; 322 | } 323 | 324 | pd = pcap_open_dead(DLT_EN10MB, pkt_octets); 325 | if (pd == NULL) { 326 | fprintf(stderr, "pcap_open_dead() failed\n"); 327 | goto err_exit; 328 | } 329 | 330 | pdumper = pcap_dump_open(pd, pcap_file); 331 | if (pdumper == NULL) { 332 | fprintf(stderr, "pcap_dump_open() failed\n"); 333 | goto err_exit; 334 | } 335 | 336 | if (gettimeofday(&pcap_pkt_hdr.ts, NULL)) { 337 | fprintf(stderr, "gettimeofday() failed\n"); 338 | goto err_exit; 339 | } 340 | 341 | p = malloc(pkt_octets); 342 | if (p == NULL) { 343 | fprintf(stderr, "malloc() failed\n"); 344 | goto err_exit; 345 | } 346 | 347 | if (ip_ver == IPV4) { 348 | v4_pkt = (struct ipv4_pkt *)p; 349 | init_ipv4_pkt_hdrs(v4_pkt); 350 | payload = (uint8_t *)v4_pkt->payload; 351 | if (empty) { 352 | pcap_pkt_hdr.caplen = sizeof(struct ipv4_pkt_hdrs); 353 | pcap_pkt_hdr.len = pcap_pkt_hdr.caplen; 354 | payload_octets = 0; 355 | } else { 356 | pcap_pkt_hdr.caplen = pkt_octets; 357 | pcap_pkt_hdr.len = pkt_octets; 358 | payload_octets = IPV4_PAYLOAD_OCTETS; 359 | } 360 | } else { 361 | v6_pkt = (struct ipv6_pkt *)p; 362 | init_ipv6_pkt_hdrs(v6_pkt); 363 | payload = (uint8_t *)v6_pkt->payload; 364 | if (empty) { 365 | pcap_pkt_hdr.caplen = sizeof(struct ipv6_pkt_hdrs); 366 | pcap_pkt_hdr.len = pcap_pkt_hdr.caplen; 367 | payload_octets = 0; 368 | } else { 369 | pcap_pkt_hdr.caplen = pkt_octets; 370 | pcap_pkt_hdr.len = pkt_octets; 371 | payload_octets = IPV6_PAYLOAD_OCTETS; 372 | } 373 | } 374 | 375 | for (i = 0; i < n; i++) { 376 | init_pkt_payload(payload, payload_octets, i); 377 | if (ip_ver == IPV4) 378 | v4_pkt->udp.csum = ipv4_udp_csum(v4_pkt); 379 | else 380 | v6_pkt->udp.csum = ipv6_udp_csum(v6_pkt); 381 | pcap_dump((u_char *)pdumper, &pcap_pkt_hdr, (u_char *)p); 382 | pcap_pkt_hdr.ts.tv_usec++; 383 | } 384 | 385 | printf("created %d packets in %s\n", n, pcap_file); 386 | goto exit; 387 | 388 | err_exit: 389 | fprintf(stderr, "pcap file creation failed\n"); 390 | rc = EXIT_FAILURE; 391 | 392 | exit: 393 | free(p); 394 | if (pdumper != NULL) pcap_dump_close(pdumper); 395 | if (pd != NULL) pcap_close(pd); 396 | 397 | exit(rc); 398 | } 399 | -------------------------------------------------------------------------------- /src/psp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Definitions of constants and structures used to 3 | * add PSP encapsulations when encrypting packets 4 | * and remove PSP encapsulations when decrypting packets 5 | * 6 | * Copyright 2022 Google LLC 7 | * 8 | * Licensed under the Apache License, Version 2.0 (the "License"); 9 | * you may not use this file except in compliance with the License. 10 | * You may obtain a copy of the License at 11 | * 12 | * https://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | #ifndef _PSP_H_ 22 | #define _PSP_H_ 23 | 24 | #define PACKED __attribute__((packed)) 25 | 26 | typedef enum { /* return codes */ 27 | SUCCESS_RC, 28 | ERR_RC 29 | } rc_t; 30 | 31 | #define DEFAULT_CLEARTEXT_PCAP_FILE "cleartext.pcap" 32 | #define DEFAULT_ENCRYPT_PCAP_FILE "psp_encrypt.pcap" 33 | #define DEFAULT_DECRYPT_PCAP_FILE "psp_decrypt.pcap" 34 | #define DEFAULT_ENCRYPT_CFG_FILE "psp_encrypt.cfg" 35 | #define DEFAULT_DECRYPT_CFG_FILE "psp_decrypt.cfg" 36 | 37 | #define MAX_PCAP_CAPTURE_OCTETS 65535 38 | 39 | #define ETH_MIN_OCTETS 64 40 | #define ETH_MAX_OCTETS 1514 41 | #define ETH_JUMBO_MAX_OCTETS 9014 42 | 43 | #define MAC_ADDR_OCTETS 6 44 | #define IPV4_ETYPE 0x0800 45 | #define IPV6_ETYPE 0x86DD 46 | 47 | #define IPV4_VER_IHL 0x45 48 | #define IPV4_IHL_MASK 0x0f 49 | #define IPV4_IHL_UNITS 4 /* units of 4 octets */ 50 | #define IPV4_IHL_NO_OPTIONS 5 51 | #define IPV4_HDR_OCTETS_NO_OPTIONS (IPV4_IHL_NO_OPTIONS * IPV4_IHL_UNITS) 52 | #define IPV4_FLAGS_DF 0x4000 53 | #define IPV4_FLAGS_MF 0x2000 54 | #define IP_TTL_DEF 0x40 55 | 56 | #define IPV6_VER 0x60000000 57 | #define IPV6_ADDR_OCTETS 16 58 | 59 | #define IP_PROTO_IPV4 0x04 60 | #define IP_PROTO_IPV6 0x29 61 | #define IP_PROTO_UDP 0x11 62 | #define IP_PROTO_TCP 0x06 63 | 64 | #define UDP_PORT_PSP 1000 65 | 66 | #define TCP_DATA_OFFSET 0x5000 /* default */ 67 | #define TCP_FLAG_NS 0x0100 68 | #define TCP_FLAG_CWR 0x0080 69 | #define TCP_FLAG_ECE 0x0040 70 | #define TCP_FLAG_URG 0x0020 71 | #define TCP_FLAG_ACK 0x0010 72 | #define TCP_FLAG_PSH 0x0008 73 | #define TCP_FLAG_RST 0x0004 74 | #define TCP_FLAG_SYN 0x0002 75 | #define TCP_FLAG_FIN 0x0001 76 | 77 | typedef enum { PSP_TRANSPORT, PSP_TUNNEL } psp_encap_t; 78 | 79 | typedef enum { AES_GCM_128, AES_GCM_256 } crypto_alg_t; 80 | 81 | #define PSP_HDR_EXT_LEN_UNITS 8 /* units of 8 octets */ 82 | #define PSP_HDR_EXT_LEN_MIN 1 83 | #define PSP_HDR_EXT_LEN_WITH_VC 2 84 | #define PSP_HDR_VC_OCTETS 8 85 | 86 | /* values to expose L4 port numbers, units of 4 octets */ 87 | #define PSP_CRYPT_OFFSET_UNITS 4 /* units of 4 octets */ 88 | #define PSP_CRYPT_OFFSET_MASK 0x3f 89 | #define PSP_CRYPT_OFFSET_MAX 64 90 | #define PSP_CRYPT_OFFSET_RESERVED_BIT7 0x80 91 | #define PSP_CRYPT_OFFSET_RESERVED_BIT6 0x40 92 | #define PSP_CRYPT_OFFSET_V4_TUNNEL 6 93 | #define PSP_CRYPT_OFFSET_V6_TUNNEL 11 94 | 95 | typedef enum { 96 | PSP_VER0 = 0, /* AES-GCM-128 */ 97 | PSP_VER1, /* AES-GCM-256 */ 98 | PSP_VER2, /* AES-GMAC-128 */ 99 | PSP_VER3 /* AES-GMAC-256 */ 100 | } psp_ver_t; 101 | 102 | #define PSP_HDR_FLAG_S_SHIFT 7 /* sample bit */ 103 | #define PSP_HDR_FLAG_D_SHIFT 6 /* drop bit */ 104 | #define PSP_HDR_VER_SHIFT 2 /* version bits */ 105 | #define PSP_HDR_VER_MASK 0x0f 106 | #define PSP_HDR_FLAG_V_SHIFT 1 /* virtualization-cookie-present bit */ 107 | #define PSP_HDR_FLAG_V (1 << PSP_HDR_FLAG_V_SHIFT) 108 | #define PSP_HDR_ALWAYS_1 1 109 | 110 | #define PSP_SPI_OCTETS 4 111 | #define PSP_SPI_KEY_SELECTOR_BIT 0x80000000 /* for uint32_t compare */ 112 | #define PSP_SPI_MSB_KEY_SELECTOR_BIT 0x80 /* for uint8_t compare */ 113 | 114 | #define PSP_INITIAL_IV 1 /* starting value for psp initialization vector */ 115 | #define PSP_IV_OCTETS 8 116 | #define AES_GCM_IV_OCTETS 12 117 | 118 | #define AES_128_KEY_OCTETS 16 119 | #define AES_256_KEY_OCTETS 32 120 | 121 | #define PSP_MASTER_KEY_OCTETS AES_256_KEY_OCTETS 122 | #define PSP_DERIVED_KEY_MAX_OCTETS AES_256_KEY_OCTETS 123 | #define PSP_KEY_DERIVATION_BLOCK_OCTETS 16 124 | #define PSP_ICV_OCTETS 16 125 | 126 | struct eth_hdr { 127 | char dmac[MAC_ADDR_OCTETS]; 128 | char smac[MAC_ADDR_OCTETS]; 129 | uint16_t etype; 130 | } PACKED; 131 | 132 | struct ipv4_hdr { 133 | uint8_t ver_ihl; 134 | uint8_t tos; 135 | uint16_t len; 136 | uint16_t id; 137 | uint16_t flags_offset; 138 | uint8_t ttl; 139 | uint8_t proto; 140 | uint16_t csum; 141 | uint32_t sip; 142 | uint32_t dip; 143 | }; 144 | 145 | struct ipv6_hdr { 146 | uint32_t ver_tc_flow; 147 | uint16_t plen; 148 | uint8_t proto; 149 | uint8_t ttl; 150 | uint8_t sip[IPV6_ADDR_OCTETS]; 151 | uint8_t dip[IPV6_ADDR_OCTETS]; 152 | }; 153 | 154 | struct udp_hdr { 155 | uint16_t sport; 156 | uint16_t dport; 157 | uint16_t len; 158 | uint16_t csum; 159 | }; 160 | 161 | struct tcp_hdr { 162 | uint16_t sport; 163 | uint16_t dport; 164 | uint32_t seq; 165 | uint32_t ack; 166 | uint16_t off_flags; 167 | uint16_t win; 168 | uint16_t csum; 169 | uint16_t urp; 170 | }; 171 | 172 | struct psp_hdr { 173 | uint8_t next_hdr; 174 | uint8_t hdr_ext_len; 175 | uint8_t crypt_off; 176 | uint8_t s_d_ver_v_1; 177 | uint32_t spi; 178 | uint64_t iv; 179 | }; 180 | 181 | struct psp_icv { 182 | uint8_t octets[PSP_ICV_OCTETS]; 183 | }; 184 | 185 | struct psp_trailer { 186 | struct psp_icv icv; 187 | }; 188 | 189 | struct psp_v4_hdrs { 190 | struct eth_hdr eth; 191 | struct ipv4_hdr ipv4; 192 | struct udp_hdr udp; 193 | struct psp_hdr psp; 194 | } PACKED; 195 | 196 | struct psp_v6_hdrs { 197 | struct eth_hdr eth; 198 | struct ipv6_hdr ipv6; 199 | struct udp_hdr udp; 200 | struct psp_hdr psp; 201 | } PACKED; 202 | 203 | #define PSP_TRANSPORT_ENCAP_OCTETS \ 204 | (sizeof(struct udp_hdr) + sizeof(struct psp_hdr) + sizeof(struct psp_trailer)) 205 | 206 | #define PSP_V4_TUNNEL_ENCAP_OCTETS \ 207 | (PSP_TRANSPORT_ENCAP_OCTETS + sizeof(struct ipv4_hdr)) 208 | 209 | #define PSP_V6_TUNNEL_ENCAP_OCTETS \ 210 | (PSP_TRANSPORT_ENCAP_OCTETS + sizeof(struct ipv6_hdr)) 211 | 212 | struct psp_master_key { 213 | uint8_t octets[PSP_MASTER_KEY_OCTETS]; 214 | }; 215 | 216 | struct psp_key_derivation_block { 217 | uint8_t octets[PSP_KEY_DERIVATION_BLOCK_OCTETS]; 218 | }; 219 | 220 | struct psp_derived_key { 221 | uint8_t octets[PSP_DERIVED_KEY_MAX_OCTETS]; 222 | }; 223 | 224 | struct aes_gcm_iv { 225 | uint8_t octets[AES_GCM_IV_OCTETS]; 226 | }; 227 | 228 | /* host-to-network and network-to-host for 64b */ 229 | #define HTONLL(x) \ 230 | ((1 == htonl(1)) ? (x) \ 231 | : ((((uint64_t)htonl((x)&0xFFFFFFFFUL)) << 32) | \ 232 | htonl((uint32_t)((x) >> 32)))) 233 | #define NTOHLL(x) \ 234 | ((1 == ntohl(1)) ? (x) \ 235 | : ((((uint64_t)ntohl((x)&0xFFFFFFFFUL)) << 32) | \ 236 | ntohl((uint32_t)((x) >> 32)))) 237 | 238 | /* compute IPv4 header checksum */ 239 | static inline uint16_t ipv4_hdr_csum(struct ipv4_hdr *h) { 240 | long sum = 0; 241 | uint16_t *p = (uint16_t *)h; 242 | int i, ihl_octets; 243 | 244 | ihl_octets = (h->ver_ihl & IPV4_IHL_MASK) * IPV4_IHL_UNITS; 245 | for (i = 0, sum = 0; i < (ihl_octets / 2); i++) sum += p[i]; 246 | 247 | while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16); 248 | 249 | return ((uint16_t)~sum); 250 | } 251 | 252 | #endif /* _PSP_H_*/ 253 | -------------------------------------------------------------------------------- /src/psp_decrypt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Program to perform PSP decryption 3 | * 4 | * Reads PSP-encrypted packets from a pcap input file 5 | * 6 | * Performs the following for each packet: 7 | * - Removes the PSP encapsulation (supports transport and tunnel encaps) 8 | * - Checks that ICV is correct 9 | * - Decrypts data 10 | * 11 | * Then writes each cleartext packet to a pcap output 12 | * 13 | * Command Line Args: 14 | * [-c psp_cfg_file_name] [-i input_file_name] [-o output_file_name] [-v] 15 | * 16 | * -v enables verbose mode 17 | * 18 | * Defaults: 19 | * psp_cfg_file: "psp_decrypt.cfg" 20 | * input_file_name: "psp_encrypt.pcap" 21 | * output_file_name: "psp_decrypt.pcap" 22 | * 23 | * The format of the PSP encryption configuration file is: 24 | * series of 32 hex bytes (e.g., 34 44 8a ...): Master Key 0 25 | * series of 32 hex bytes (e.g., 56 39 52 ...): Master Key 1 26 | * 27 | * The program uses OpenSSL crypto libraries. 28 | * 29 | * Copyright 2022 Google LLC 30 | * 31 | * Licensed under the Apache License, Version 2.0 (the "License"); 32 | * you may not use this file except in compliance with the License. 33 | * You may obtain a copy of the License at 34 | * 35 | * https://www.apache.org/licenses/LICENSE-2.0 36 | * 37 | * Unless required by applicable law or agreed to in writing, software 38 | * distributed under the License is distributed on an "AS IS" BASIS, 39 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 40 | * See the License for the specific language governing permissions and 41 | * limitations under the License. 42 | 43 | */ 44 | 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | 60 | #include "psp.h" 61 | 62 | typedef enum { /* return codes for packet processsing */ 63 | PKT_DECRYPTED, /* success */ 64 | PKT_SKIPPED, /* packet not decrypted */ 65 | PKT_ERR 66 | } pkt_rc_t; 67 | 68 | struct psp_decrypt_cfg { /* decryption config parms */ 69 | struct psp_master_key master_key0; 70 | struct psp_master_key master_key1; 71 | }; 72 | 73 | /* 74 | * context info associated with packet 75 | * 76 | * passed as parm to packet processing functions 77 | * 78 | * fields: 79 | * max_pkt_octets: max packet size supported 80 | * psp_cfg: psp decryption config parms 81 | * crypto_alg: crypto algorithm to use 82 | * derived: derived psp encryption key 83 | * in_pcap_pkt_hdr: ptr to pcap_pkt_hdr for input packet 84 | * in_pkt: ptr to input packet 85 | * psp: ptr to psp header of input packet 86 | * out_pcap_pkt_hdr: pcap_pkt_hdr for output packet 87 | * out_pkt: ptr to output packet 88 | * scratch_buf: ptr to scratch packet buffer 89 | */ 90 | struct pkt_context { 91 | uint32_t max_pkt_octets; 92 | struct psp_decrypt_cfg psp_cfg; 93 | crypto_alg_t crypto_alg; 94 | struct psp_derived_key key; 95 | struct pcap_pkthdr *in_pcap_pkt_hdr; 96 | uint8_t *in_pkt; 97 | struct psp_hdr *psp; 98 | struct pcap_pkthdr out_pcap_pkt_hdr; 99 | uint8_t *out_pkt; 100 | uint8_t *scratch_buf; 101 | }; 102 | 103 | bool verbose = false; 104 | 105 | /* 106 | * get psp configuration by: 107 | * - reading from configuration file, 108 | * - parsing the configuration data, and 109 | * - saving the results in the packet context structure 110 | */ 111 | static rc_t get_psp_cfg(char *cfg_file, struct pkt_context *pkt_ctx) { 112 | int i; 113 | FILE *fp; 114 | 115 | fp = fopen(cfg_file, "r"); 116 | if (fp == NULL) { 117 | perror("fopen() failed for psp_cfg_file"); 118 | goto err_exit; 119 | } 120 | 121 | for (i = 0; i < PSP_MASTER_KEY_OCTETS; i++) { 122 | if (fscanf(fp, "%hhx", &pkt_ctx->psp_cfg.master_key0.octets[i]) != 1) { 123 | fprintf(stderr, "read of master key 0 from psp_cfg_file failed\n"); 124 | goto err_exit; 125 | } 126 | } 127 | 128 | if (verbose) { 129 | printf("Master Key 0:\n "); 130 | for (i = 0; i < PSP_MASTER_KEY_OCTETS; i++) 131 | printf("%02hhx ", pkt_ctx->psp_cfg.master_key0.octets[i]); 132 | printf("\n"); 133 | fflush(stdout); 134 | } 135 | 136 | for (i = 0; i < PSP_MASTER_KEY_OCTETS; i++) { 137 | if (fscanf(fp, "%hhx", &pkt_ctx->psp_cfg.master_key1.octets[i]) != 1) { 138 | fprintf(stderr, "read of master key 1 from psp_cfg_file failed\n"); 139 | goto err_exit; 140 | } 141 | } 142 | 143 | if (verbose) { 144 | printf("Master Key 1:\n "); 145 | for (i = 0; i < PSP_MASTER_KEY_OCTETS; i++) 146 | printf("%02hhx ", pkt_ctx->psp_cfg.master_key1.octets[i]); 147 | printf("\n"); 148 | fflush(stdout); 149 | } 150 | 151 | fclose(fp); 152 | return SUCCESS_RC; 153 | 154 | err_exit: 155 | if (fp != NULL) fclose(fp); 156 | return ERR_RC; 157 | } 158 | 159 | /* 160 | * derive 128b of psp encryption key 161 | * 162 | * parms: 163 | * pkt_ctx: ptr to pcaket context struct 164 | * counter: 1 => derive first 128b of key 165 | * 2 => derive second 128b of key 166 | * derived_key: ptr to location where derived key is returned 167 | * 168 | * returns: 169 | * SUCCESS_RC: key derived successfully 170 | * ERR_RC: error deriving key 171 | */ 172 | static rc_t derive_psp_key_128(struct pkt_context *pkt_ctx, uint8_t counter, 173 | uint8_t *derived_key) { 174 | CMAC_CTX *ctx = NULL; 175 | uint32_t spi; 176 | struct psp_key_derivation_block input_block; 177 | size_t key_len, input_block_len, final_len; 178 | const void *key; 179 | 180 | spi = ntohl(pkt_ctx->psp->spi); 181 | input_block_len = (size_t)PSP_KEY_DERIVATION_BLOCK_OCTETS; 182 | input_block.octets[0] = 0x00; 183 | input_block.octets[1] = 0x00; 184 | input_block.octets[2] = 0x00; 185 | input_block.octets[3] = counter; 186 | input_block.octets[4] = 0x50; 187 | input_block.octets[5] = 0x76; 188 | if (pkt_ctx->crypto_alg == AES_GCM_128) { 189 | input_block.octets[6] = 0x30; 190 | input_block.octets[14] = 0x00; 191 | input_block.octets[15] = 0x80; 192 | } else { 193 | input_block.octets[6] = 0x31; 194 | input_block.octets[14] = 0x01; 195 | input_block.octets[15] = 0x00; 196 | } 197 | input_block.octets[7] = 0x00; 198 | input_block.octets[8] = (spi >> 24) & 0xff; 199 | input_block.octets[9] = (spi >> 16) & 0xff; 200 | input_block.octets[10] = (spi >> 8) & 0xff; 201 | input_block.octets[11] = spi & 0xff; 202 | input_block.octets[12] = 0x00; 203 | input_block.octets[13] = 0x00; 204 | 205 | if (spi & PSP_SPI_KEY_SELECTOR_BIT) 206 | key = (const void *)pkt_ctx->psp_cfg.master_key1.octets; 207 | else 208 | key = (const void *)pkt_ctx->psp_cfg.master_key0.octets; 209 | key_len = (size_t)AES_256_KEY_OCTETS; 210 | 211 | ctx = CMAC_CTX_new(); 212 | if (ctx == NULL) { 213 | fprintf(stderr, "CMAC_CTX_new() failed\n"); 214 | goto err_exit; 215 | } 216 | 217 | if (!CMAC_Init(ctx, key, key_len, EVP_aes_256_cbc(), NULL)) { 218 | fprintf(stderr, "CMAC_Init() failed\n"); 219 | goto err_exit; 220 | } 221 | 222 | if (!CMAC_Update(ctx, (const uint8_t *)input_block.octets, input_block_len)) { 223 | fprintf(stderr, "CMAC_Update() failed\n"); 224 | goto err_exit; 225 | } 226 | 227 | if (!CMAC_Final(ctx, derived_key, &final_len)) { 228 | fprintf(stderr, "CMAC_Final() failed\n"); 229 | goto err_exit; 230 | } 231 | 232 | CMAC_CTX_free(ctx); 233 | return SUCCESS_RC; 234 | 235 | err_exit: 236 | if (ctx != NULL) CMAC_CTX_free(ctx); 237 | return ERR_RC; 238 | } 239 | 240 | /* 241 | * derive psp encryption key 242 | * 243 | * returns: 244 | * SUCCESS_RC: derived key is returned in packet context structure 245 | * ERR_RC: error deriving key 246 | */ 247 | static rc_t derive_psp_key(struct pkt_context *pkt_ctx) { 248 | rc_t rc; 249 | 250 | rc = derive_psp_key_128(pkt_ctx, (uint8_t)1, pkt_ctx->key.octets); 251 | if ((rc != SUCCESS_RC) || (pkt_ctx->crypto_alg == AES_GCM_128)) return rc; 252 | return derive_psp_key_128( 253 | pkt_ctx, (uint8_t)2, 254 | &pkt_ctx->key.octets[PSP_KEY_DERIVATION_BLOCK_OCTETS]); 255 | } 256 | 257 | /* 258 | * perform psp decryption 259 | * 260 | * the code for this function is based off an example on the 261 | * OpenSSL website (see https://wiki.openssl.org/images/0/08/Evp-gcm-encrypt.c) 262 | * 263 | * parms: 264 | * pkt_ctx: ptr to context info for packet 265 | * ciphertext_len: length of encrypted data to be decrypted in octets 266 | * ciphertext: ptr to encrypted data to decrypt 267 | * aad_len: length of additional data to be authenticated in octets 268 | * aad: ptr to additional data to authenticate 269 | * cleartext: ptr to location where decrypted data is to be returned 270 | * expected_icv: ptr to expected integrity check value 271 | * 272 | * 273 | * returns: 274 | * PKT_DECRYPTED 275 | * PKT_ERR 276 | * */ 277 | static pkt_rc_t psp_decrypt(struct pkt_context *pkt_ctx, 278 | uint32_t ciphertext_len, uint8_t *ciphertext, 279 | uint32_t aad_len, uint8_t *aad, uint8_t *cleartext, 280 | struct psp_icv *expected_icv) { 281 | int rc, len; 282 | uint8_t psp_ver; 283 | uint32_t *spi; 284 | uint64_t *psp_iv; 285 | struct aes_gcm_iv gcm_iv; 286 | EVP_CIPHER_CTX *ctx = NULL; 287 | 288 | if (ciphertext_len == 0) return PKT_DECRYPTED; 289 | 290 | /* form aes-gsm iv */ 291 | spi = &pkt_ctx->psp->spi; 292 | psp_iv = &pkt_ctx->psp->iv; 293 | memcpy(gcm_iv.octets, spi, PSP_SPI_OCTETS); 294 | memcpy(&gcm_iv.octets[PSP_SPI_OCTETS], psp_iv, PSP_IV_OCTETS); 295 | 296 | /* derive the key */ 297 | rc = derive_psp_key(pkt_ctx); 298 | if (rc != SUCCESS_RC) goto err_exit; 299 | 300 | if (verbose) { 301 | int i; 302 | 303 | printf("Derived Key:\n "); 304 | for (i = 0; i < PSP_KEY_DERIVATION_BLOCK_OCTETS; i++) 305 | printf("%02hhx ", pkt_ctx->key.octets[i]); 306 | if (pkt_ctx->crypto_alg == AES_GCM_256) { 307 | for (i = 0; i < PSP_KEY_DERIVATION_BLOCK_OCTETS; i++) 308 | printf("%02hhx ", 309 | pkt_ctx->key.octets[PSP_KEY_DERIVATION_BLOCK_OCTETS + i]); 310 | } 311 | printf("\n"); 312 | fflush(stdout); 313 | } 314 | 315 | /* create and initialize the cipher context */ 316 | ctx = EVP_CIPHER_CTX_new(); 317 | if (ctx == NULL) { 318 | fprintf(stderr, "EVP_CIPHER_CTX_new() failed\n"); 319 | goto err_exit; 320 | } 321 | 322 | /* initialize the decryption operation */ 323 | psp_ver = (pkt_ctx->psp->s_d_ver_v_1 >> PSP_HDR_VER_SHIFT) & PSP_HDR_VER_MASK; 324 | if (psp_ver == PSP_VER0) 325 | rc = EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL); 326 | else 327 | rc = EVP_DecryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL); 328 | if (rc != 1) { 329 | fprintf(stderr, "EVP_DecryptInit_ex() failed\n"); 330 | goto err_exit; 331 | } 332 | 333 | /* initialize key and iv */ 334 | if (EVP_DecryptInit_ex(ctx, NULL, NULL, pkt_ctx->key.octets, gcm_iv.octets) != 335 | 1) { 336 | fprintf(stderr, "EVP_DecryptInit_ex() failed\n"); 337 | goto err_exit; 338 | } 339 | 340 | /* provide additional authentication data */ 341 | if (EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len) != 1) { 342 | fprintf(stderr, "EVP_DecryptUpdate() failed\n"); 343 | goto err_exit; 344 | } 345 | 346 | /* do decryption */ 347 | if (EVP_DecryptUpdate(ctx, cleartext, &len, ciphertext, ciphertext_len) != 348 | 1) { 349 | fprintf(stderr, "EVP_DecryptUpdate() failed\n"); 350 | goto err_exit; 351 | } 352 | 353 | /* set the expected icv */ 354 | if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, PSP_ICV_OCTETS, 355 | expected_icv->octets) != 1) { 356 | fprintf(stderr, "EVP_CIPHER_CTX_ctrl() failed\n"); 357 | goto err_exit; 358 | } 359 | 360 | /* finalize decryption */ 361 | if (EVP_DecryptFinal_ex(ctx, cleartext + len, &len) < 1) { 362 | fprintf(stderr, "EVP_DecryptFinal_ex() failed\n"); 363 | goto err_exit; 364 | } 365 | 366 | EVP_CIPHER_CTX_free(ctx); 367 | return PKT_DECRYPTED; 368 | 369 | err_exit: 370 | if (ctx != NULL) EVP_CIPHER_CTX_free(ctx); 371 | return PKT_ERR; 372 | } 373 | 374 | /* 375 | * process packet read from input pcap file 376 | * - parse the input packet and check for errors 377 | * - decrypt and autheticate the packet 378 | * - build cleartext packet without PSP encapsulation 379 | * 380 | * returns: 381 | * PKT_DECRYPTED 382 | * PKT_SKIPPED 383 | * PKT_ERR 384 | */ 385 | static pkt_rc_t process_in_pkt(struct pkt_context *pkt_ctx) { 386 | struct eth_hdr *eth; 387 | struct ipv4_hdr *ipv4, *out_ipv4; 388 | struct ipv6_hdr *ipv6, *out_ipv6; 389 | struct udp_hdr *psp_udp; 390 | struct psp_hdr *psp; 391 | struct psp_icv *icv; 392 | uint8_t *ip_proto, *out_pkt, *after_base_psp_hdr, *after_ext_psp_hdr, 393 | *cipher_start, *aad, *out_cleartext; 394 | uint16_t etype, ip_len, strip_len, dport; 395 | uint32_t pkt_len, eth_hdr_len, ip_pkt_len, ip_hdr_len, udp_hdr_len, 396 | psp_hdr_len, hdr_ext_len, psp_trailer_len, psp_payload_len, psp_ver, 397 | crypt_off, crypt_off_after_ext, encrypted_ext_len, out_pkt_len, 398 | cipher_len, aad_len, cleartext_copy_len; 399 | crypto_alg_t crypto_alg; 400 | psp_encap_t psp_encap; 401 | pkt_rc_t pkt_rc; 402 | 403 | /* check input packet length */ 404 | pkt_len = pkt_ctx->in_pcap_pkt_hdr->len; 405 | if (pkt_ctx->in_pcap_pkt_hdr->caplen != pkt_len) { 406 | fprintf(stderr, "partial packet captures not supported\n"); 407 | return PKT_ERR; 408 | } 409 | 410 | if (pkt_len < ETH_MIN_OCTETS) { 411 | fprintf(stderr, "invalid packet, too small, %u bytes\n", pkt_len); 412 | return PKT_ERR; 413 | } 414 | 415 | if (pkt_len > pkt_ctx->max_pkt_octets) { 416 | fprintf(stderr, "invalid packet, too big, %u bytes\n", pkt_len); 417 | return PKT_ERR; 418 | } 419 | 420 | /* parse input packet */ 421 | eth = (struct eth_hdr *)pkt_ctx->in_pkt; 422 | etype = ntohs(eth->etype); 423 | eth_hdr_len = sizeof(struct eth_hdr); 424 | ip_pkt_len = pkt_len - eth_hdr_len; 425 | switch (etype) { 426 | case IPV4_ETYPE: 427 | ipv4 = (struct ipv4_hdr *)(((uint8_t *)eth) + eth_hdr_len); 428 | ip_proto = &ipv4->proto; 429 | ip_hdr_len = (ipv4->ver_ihl & IPV4_IHL_MASK) * IPV4_IHL_UNITS; 430 | ip_len = ntohs(ipv4->len); 431 | if (ip_len != ip_pkt_len) { 432 | fprintf(stderr, "invalid packet, bad IP len\n"); 433 | return PKT_ERR; 434 | } 435 | break; 436 | case IPV6_ETYPE: 437 | ipv6 = (struct ipv6_hdr *)(((uint8_t *)eth) + eth_hdr_len); 438 | ip_proto = &ipv6->proto; 439 | ip_hdr_len = sizeof(struct ipv6_hdr); 440 | ip_len = ntohs(ipv6->plen); 441 | if (((*ip_proto) == IP_PROTO_UDP) && 442 | (ip_len != (ip_pkt_len - ip_hdr_len))) { 443 | fprintf(stderr, "invalid packet, bad IP len\n"); 444 | return PKT_ERR; 445 | } 446 | break; 447 | default: 448 | fprintf(stderr, "skipping non-IP packet, etype = 0x%04x\n", etype); 449 | return PKT_SKIPPED; 450 | } 451 | 452 | if ((*ip_proto) != IP_PROTO_UDP) { 453 | fprintf(stderr, "skipping non-PSP packet, IP proto = 0x%02hhx\n", 454 | *ip_proto); 455 | return PKT_SKIPPED; 456 | } 457 | 458 | psp_udp = (struct udp_hdr *)(((uint8_t *)eth) + eth_hdr_len + ip_hdr_len); 459 | dport = ntohs(psp_udp->dport); 460 | if (dport != UDP_PORT_PSP) { 461 | fprintf(stderr, "skipping non-PSP packet, UDP dport = 0x%04hx\n", dport); 462 | return PKT_SKIPPED; 463 | } 464 | if (ntohs(psp_udp->len) != (pkt_len - (eth_hdr_len + ip_hdr_len))) { 465 | fprintf(stderr, "invalid packet, bad UDP len\n"); 466 | return PKT_ERR; 467 | } 468 | udp_hdr_len = sizeof(struct udp_hdr); 469 | 470 | psp = (struct psp_hdr *)(((uint8_t *)psp_udp) + udp_hdr_len); 471 | pkt_ctx->psp = psp; 472 | psp_hdr_len = sizeof(struct psp_hdr); 473 | psp_trailer_len = sizeof(struct psp_trailer); 474 | /* including psp hdr ext in psp_payload_len */ 475 | psp_payload_len = pkt_len - (eth_hdr_len + ip_hdr_len + udp_hdr_len + 476 | psp_hdr_len + psp_trailer_len); 477 | hdr_ext_len = 478 | (psp->hdr_ext_len - PSP_HDR_EXT_LEN_MIN) * PSP_HDR_EXT_LEN_UNITS; 479 | if (hdr_ext_len > psp_payload_len) { 480 | fprintf(stderr, "invalid packet, hdr_ext_len exceeds packet size\n"); 481 | return PKT_ERR; 482 | } 483 | 484 | crypt_off = (psp->crypt_off & PSP_CRYPT_OFFSET_MASK) * PSP_CRYPT_OFFSET_UNITS; 485 | if (crypt_off > psp_payload_len) { 486 | fprintf(stderr, "invalid packet, crypt offset too big, %u\n", crypt_off); 487 | return PKT_ERR; 488 | } 489 | 490 | psp_ver = (psp->s_d_ver_v_1 >> PSP_HDR_VER_SHIFT) & PSP_HDR_VER_MASK; 491 | switch (psp_ver) { 492 | case PSP_VER0: 493 | crypto_alg = AES_GCM_128; 494 | break; 495 | case PSP_VER1: 496 | crypto_alg = AES_GCM_256; 497 | break; 498 | default: 499 | fprintf(stderr, "invalid packet, unsupported PSP version, %u\n", psp_ver); 500 | return PKT_ERR; 501 | } 502 | pkt_ctx->crypto_alg = crypto_alg; 503 | 504 | if ((psp->s_d_ver_v_1 & PSP_HDR_ALWAYS_1) != PSP_HDR_ALWAYS_1) { 505 | fprintf(stderr, 506 | "invalid packet, invalid word 0 in PSP header, " 507 | "0x%08x\n", 508 | *((uint32_t *)psp)); 509 | return PKT_ERR; 510 | } 511 | 512 | switch (psp->next_hdr) { 513 | case IP_PROTO_IPV4: 514 | case IP_PROTO_IPV6: 515 | psp_encap = PSP_TUNNEL; 516 | break; 517 | default: 518 | psp_encap = PSP_TRANSPORT; 519 | break; 520 | } 521 | 522 | /* 523 | * build the cleartext packet 524 | * - copy the ethernet header of the input packet 525 | * - if transport mode 526 | * - insert ip header based on ip header of input packet 527 | * - copy data from input packet starting after psp header 528 | * - check icv and decrypt data 529 | */ 530 | out_pkt = pkt_ctx->out_pkt; 531 | memcpy(out_pkt, eth, eth_hdr_len); 532 | out_pkt += eth_hdr_len; 533 | 534 | if (psp_encap == PSP_TRANSPORT) { 535 | if (etype == IPV4_ETYPE) { 536 | memcpy(out_pkt, ipv4, ip_hdr_len); 537 | out_ipv4 = (struct ipv4_hdr *)out_pkt; 538 | strip_len = PSP_TRANSPORT_ENCAP_OCTETS + hdr_ext_len; 539 | out_ipv4->len = htons(ip_len - strip_len); 540 | out_ipv4->proto = psp->next_hdr; 541 | out_ipv4->csum = 0; 542 | out_ipv4->csum = ipv4_hdr_csum(out_ipv4); 543 | } else { 544 | memcpy(out_pkt, ipv6, ip_hdr_len); 545 | out_ipv6 = (struct ipv6_hdr *)out_pkt; 546 | strip_len = PSP_TRANSPORT_ENCAP_OCTETS + hdr_ext_len; 547 | out_ipv6->plen = htons(ip_len - strip_len); 548 | out_ipv6->proto = psp->next_hdr; 549 | } 550 | out_pkt += ip_hdr_len; 551 | } 552 | 553 | after_base_psp_hdr = ((uint8_t *)psp) + psp_hdr_len; 554 | after_ext_psp_hdr = after_base_psp_hdr + hdr_ext_len; 555 | if (crypt_off >= hdr_ext_len) { 556 | encrypted_ext_len = 0; 557 | crypt_off_after_ext = crypt_off - hdr_ext_len; 558 | } else { 559 | encrypted_ext_len = hdr_ext_len - crypt_off; 560 | crypt_off_after_ext = 0; 561 | } 562 | memcpy(out_pkt, after_ext_psp_hdr, crypt_off_after_ext); 563 | out_pkt += crypt_off_after_ext; 564 | 565 | cipher_start = after_base_psp_hdr + crypt_off; 566 | cipher_len = psp_payload_len - crypt_off; 567 | aad = (uint8_t *)psp; 568 | aad_len = psp_hdr_len + crypt_off; 569 | out_cleartext = pkt_ctx->scratch_buf; 570 | icv = (struct psp_icv *)(cipher_start + cipher_len); 571 | pkt_rc = psp_decrypt(pkt_ctx, cipher_len, cipher_start, aad_len, aad, 572 | out_cleartext, icv); 573 | if (pkt_rc != PKT_DECRYPTED) return pkt_rc; 574 | cleartext_copy_len = cipher_len - encrypted_ext_len; 575 | memcpy(out_pkt, out_cleartext + encrypted_ext_len, cleartext_copy_len); 576 | out_pkt += cleartext_copy_len; 577 | 578 | /* set pcap packet header fields for output packet */ 579 | out_pkt_len = out_pkt - pkt_ctx->out_pkt; 580 | pkt_ctx->out_pcap_pkt_hdr.caplen = out_pkt_len; 581 | pkt_ctx->out_pcap_pkt_hdr.len = out_pkt_len; 582 | pkt_ctx->out_pcap_pkt_hdr.ts = pkt_ctx->in_pcap_pkt_hdr->ts; 583 | 584 | return PKT_DECRYPTED; 585 | } 586 | 587 | int main(int argc, char *argv[]) { 588 | int opt, n = 0, skipped = 0, rc = EXIT_SUCCESS, pcap_rc; 589 | pkt_rc_t pkt_rc; 590 | pcap_t *in_pd = NULL, *out_pd = NULL; 591 | pcap_dumper_t *pdumper = NULL; 592 | char *in_pcap_file = DEFAULT_ENCRYPT_PCAP_FILE, 593 | *out_pcap_file = DEFAULT_DECRYPT_PCAP_FILE, 594 | *cfg_file = DEFAULT_DECRYPT_CFG_FILE; 595 | struct stat stat_buf; 596 | struct pkt_context pkt_ctx; 597 | 598 | pkt_ctx.max_pkt_octets = ETH_JUMBO_MAX_OCTETS; 599 | pkt_ctx.out_pkt = NULL; 600 | pkt_ctx.scratch_buf = NULL; 601 | 602 | /* handle command line args */ 603 | while ((opt = getopt(argc, argv, "c:i:o:v")) != -1) { 604 | switch (opt) { 605 | case 'c': 606 | cfg_file = optarg; 607 | break; 608 | case 'i': 609 | in_pcap_file = optarg; 610 | break; 611 | case 'o': 612 | out_pcap_file = optarg; 613 | break; 614 | case 'v': 615 | verbose = true; 616 | break; 617 | default: 618 | fprintf(stderr, 619 | "Usage: %s [-c cfg_file] [-i in_file] " 620 | "[-o out_file] [-v]\n", 621 | argv[0]); 622 | goto err_exit; 623 | break; 624 | } 625 | } 626 | 627 | if (verbose) { 628 | printf("starting %s\n", argv[0]); 629 | fflush(stdout); 630 | } 631 | 632 | /* read psp config file */ 633 | if (get_psp_cfg(cfg_file, &pkt_ctx) != SUCCESS_RC) goto err_exit; 634 | 635 | /* open output pcap file */ 636 | out_pd = pcap_open_dead(DLT_EN10MB, pkt_ctx.max_pkt_octets); 637 | if (out_pd == NULL) { 638 | fprintf(stderr, "pcap_open_dead() failed\n"); 639 | goto err_exit; 640 | } 641 | 642 | pdumper = pcap_dump_open(out_pd, out_pcap_file); 643 | if (pdumper == NULL) { 644 | fprintf(stderr, "pcap_dump_open() failed\n"); 645 | goto err_exit; 646 | } 647 | 648 | /* open input pcap file */ 649 | if (stat(in_pcap_file, &stat_buf) != 0) { 650 | fprintf(stderr, "stat() failed for %s\n", in_pcap_file); 651 | goto err_exit; 652 | } 653 | 654 | in_pd = pcap_open_offline(in_pcap_file, NULL); 655 | if (in_pd == NULL) { 656 | fprintf(stderr, "pcap_open_offline() failed\n"); 657 | goto err_exit; 658 | } 659 | 660 | /* allocate packet buffers */ 661 | pkt_ctx.out_pkt = calloc(1, pkt_ctx.max_pkt_octets); 662 | if (pkt_ctx.out_pkt == NULL) { 663 | fprintf(stderr, "calloc() failed\n"); 664 | goto err_exit; 665 | } 666 | 667 | pkt_ctx.scratch_buf = calloc(1, pkt_ctx.max_pkt_octets); 668 | if (pkt_ctx.scratch_buf == NULL) { 669 | fprintf(stderr, "calloc() failed\n"); 670 | goto err_exit; 671 | } 672 | 673 | /* process packets from input pcap file */ 674 | while (1) { 675 | pcap_rc = pcap_next_ex(in_pd, &pkt_ctx.in_pcap_pkt_hdr, 676 | (const u_char **)&pkt_ctx.in_pkt); 677 | if (pcap_rc == 1) { 678 | /* packet read without error from pcap file */ 679 | pkt_rc = process_in_pkt(&pkt_ctx); 680 | if (pkt_rc == PKT_ERR) { 681 | goto err_exit; 682 | } else if (pkt_rc == PKT_SKIPPED) { 683 | skipped++; 684 | } else { 685 | /* write decrypted packet to output pcap file */ 686 | pcap_dump((u_char *)pdumper, &pkt_ctx.out_pcap_pkt_hdr, 687 | (u_char *)pkt_ctx.out_pkt); 688 | n++; 689 | } 690 | } else if (pcap_rc == PCAP_ERROR_BREAK) { 691 | /* no more packets to read */ 692 | break; 693 | } else { 694 | pcap_perror(in_pd, "pcap_next_ex() failed"); 695 | goto err_exit; 696 | } 697 | } 698 | 699 | printf("decrypted %d packets in %s, skipped %d packets\n", n, out_pcap_file, 700 | skipped); 701 | goto exit; 702 | 703 | err_exit: 704 | fflush(stdout); 705 | fprintf(stderr, "psp decryption failed\n"); 706 | fflush(stderr); 707 | rc = EXIT_FAILURE; 708 | 709 | exit: 710 | free(pkt_ctx.out_pkt); 711 | free(pkt_ctx.scratch_buf); 712 | if (pdumper != NULL) pcap_dump_close(pdumper); 713 | if (out_pd != NULL) pcap_close(out_pd); 714 | if (in_pd != NULL) pcap_close(in_pd); 715 | exit(rc); 716 | } 717 | -------------------------------------------------------------------------------- /src/psp_encrypt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Program to perform PSP encryption 3 | * 4 | * Reads plaintext packets from a pcap input file 5 | * 6 | * Performs the following for each packet: 7 | * - Adds appropriate PSP encapsulation 8 | * - Computes ICV 9 | * - Encrypts data 10 | * 11 | * Then writes each PSP-encrypted packet to a pcap output 12 | * 13 | * Command Line Args: 14 | * [-c psp_cfg_file_name] [-i in_file] [-o out_file] [-v] [-e] 15 | * 16 | * -v enables verbose mode 17 | * 18 | * -e forces a single bit error in each output packet, 19 | * which will cause authentication to fail 20 | * 21 | * Defaults: 22 | * psp_cfg_file: "psp_encrypt.cfg" 23 | * in_file: "cleartext.pcap" 24 | * out_file: "psp_encrypt.pcap" 25 | * 26 | * The format of the PSP encryption configuration file is: 27 | * series of 32 hex bytes (e.g., 34 44 8a ...): Master Key 0 28 | * series of 32 hex bytes (e.g., 56 39 52 ...): Master Key 1 29 | * 32b hex value (e.g., 9A345678), msb selects master key: SPI 30 | * encap string (either "transport" or "tunnel"): PSP Encap Mode 31 | * crypro algorithm string 32 | * (either "aes-gcm-128" or "aes-gcm-256"): Crypto Algorithm 33 | * non-negative integer with units of 4 bytes (e.g., 1): Transport Mode 34 | * Crypt Offset 35 | * non-negative integer with units of 4 bytes (e.g., 6): IPv4 Tunnel Mode 36 | * Crypt Offset 37 | * non-negative integer with units of 4 bytes (e.g., 11): IPv6 Tunnel Mode 38 | * Crypt Offset 39 | * virtual cookie string (either "vc" or "no-vc") Include VC in 40 | * PSP Header 41 | * 42 | * The program uses OpenSSL crypto libraries. 43 | * 44 | * Copyright 2022 Google LLC 45 | * 46 | * Licensed under the Apache License, Version 2.0 (the "License"); 47 | * you may not use this file except in compliance with the License. 48 | * You may obtain a copy of the License at 49 | * 50 | * https://www.apache.org/licenses/LICENSE-2.0 51 | * 52 | * Unless required by applicable law or agreed to in writing, software 53 | * distributed under the License is distributed on an "AS IS" BASIS, 54 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 55 | * See the License for the specific language governing permissions and 56 | * limitations under the License. 57 | */ 58 | 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | #include 65 | #include 66 | #include 67 | #include 68 | #include 69 | #include 70 | #include 71 | #include 72 | #include 73 | 74 | #include "psp.h" 75 | 76 | typedef enum { /* return codes for packet processsing */ 77 | PKT_ENCRYPTED, /* success */ 78 | PKT_SKIPPED, /* packet not encrypted */ 79 | PKT_ERR 80 | } pkt_rc_t; 81 | 82 | struct psp_encrypt_cfg { /* encryption config parms */ 83 | struct psp_master_key master_key0; 84 | struct psp_master_key master_key1; 85 | uint32_t spi; 86 | psp_encap_t psp_encap; 87 | crypto_alg_t crypto_alg; 88 | /* crypt offset for transport mode, units = 4B */ 89 | uint8_t transport_crypt_off; 90 | /* crypt offset for ipv4 packets in tunnel mode, units = 4B */ 91 | uint8_t ipv4_tunnel_crypt_off; 92 | /* crypt offset for ipv6 packets in tunnel mode, units = 4B */ 93 | uint8_t ipv6_tunnel_crypt_off; 94 | bool include_vc; /* include vc in psp header */ 95 | }; 96 | 97 | /* 98 | * context info associated with packet 99 | * 100 | * passed as parm to packet processing functions 101 | * 102 | * fields: 103 | * max_pkt_octets: max packet size supported 104 | * psp_cfg: psp encryption config parms 105 | * key: derived psp encryption key 106 | * next_iv: next psp initialization vector to use 107 | * (since we don't have a picosecond resolution timer, 108 | * we use a 64b counter instead) 109 | * in_pcap_pkt_hdr: ptr to pcap_pkt_hdr for input packet 110 | * in_pkt: ptr to input packet 111 | * eth_hdr_len: length of ethernet header in octets 112 | * out_pcap_pkt_hdr: pcap_pkt_hdr for output packet 113 | * out_pkt: ptr to output packet 114 | * scratch_buf: ptr to scratch packet buffer 115 | */ 116 | struct pkt_context { 117 | uint32_t max_pkt_octets; 118 | struct psp_encrypt_cfg psp_cfg; 119 | struct psp_derived_key key; 120 | uint64_t next_iv; 121 | struct pcap_pkthdr *in_pcap_pkt_hdr; 122 | uint8_t *in_pkt; 123 | uint32_t eth_hdr_len; 124 | struct pcap_pkthdr out_pcap_pkt_hdr; 125 | uint8_t *out_pkt; 126 | uint8_t *scratch_buf; 127 | }; 128 | 129 | bool verbose = false, force_corruption = false; 130 | 131 | /* 132 | * get psp configuration by: 133 | * - reading from configuration file, 134 | * - parsing the configuration data, and 135 | * - saving the results in the packet context structure 136 | */ 137 | static rc_t get_psp_cfg(char *cfg_file, struct pkt_context *pkt_ctx) { 138 | int i; 139 | FILE *fp; 140 | char string[16]; 141 | 142 | fp = fopen(cfg_file, "r"); 143 | if (fp == NULL) { 144 | perror("fopen() failed for psp_cfg_file"); 145 | goto err_exit; 146 | } 147 | 148 | for (i = 0; i < PSP_MASTER_KEY_OCTETS; i++) { 149 | if (fscanf(fp, "%hhx", &pkt_ctx->psp_cfg.master_key0.octets[i]) != 1) { 150 | fprintf(stderr, "read of master key 0 from psp_cfg_file failed\n"); 151 | goto err_exit; 152 | } 153 | } 154 | 155 | if (verbose) { 156 | printf("Master Key 0:\n "); 157 | for (i = 0; i < PSP_MASTER_KEY_OCTETS; i++) 158 | printf("%02hhx ", pkt_ctx->psp_cfg.master_key0.octets[i]); 159 | printf("\n"); 160 | fflush(stdout); 161 | } 162 | 163 | for (i = 0; i < PSP_MASTER_KEY_OCTETS; i++) { 164 | if (fscanf(fp, "%hhx", &pkt_ctx->psp_cfg.master_key1.octets[i]) != 1) { 165 | fprintf(stderr, "read of master key 1 from psp_cfg_file failed\n"); 166 | goto err_exit; 167 | } 168 | } 169 | 170 | if (verbose) { 171 | printf("Master Key 1:\n "); 172 | for (i = 0; i < PSP_MASTER_KEY_OCTETS; i++) 173 | printf("%02hhx ", pkt_ctx->psp_cfg.master_key1.octets[i]); 174 | printf("\n"); 175 | fflush(stdout); 176 | } 177 | 178 | if (fscanf(fp, "%x", &pkt_ctx->psp_cfg.spi) != 1) { 179 | fprintf(stderr, "read of spi from psp_cfg_file failed\n"); 180 | goto err_exit; 181 | } 182 | 183 | if (verbose) { 184 | printf("SPI: %08x\n", pkt_ctx->psp_cfg.spi); 185 | fflush(stdout); 186 | } 187 | 188 | if (fscanf(fp, "%15s", string) != 1) { 189 | fprintf(stderr, "read of psp encap mode from psp_cfg_file failed\n"); 190 | goto err_exit; 191 | } 192 | if (strcmp(string, "transport") == 0) { 193 | pkt_ctx->psp_cfg.psp_encap = PSP_TRANSPORT; 194 | } else if (strcmp(string, "tunnel") == 0) { 195 | pkt_ctx->psp_cfg.psp_encap = PSP_TUNNEL; 196 | } else { 197 | fprintf(stderr, "invalid psp encap mode in psp_cfg_file\n"); 198 | goto err_exit; 199 | } 200 | 201 | if (verbose) { 202 | printf("Encap Mode: %s\n", string); 203 | fflush(stdout); 204 | } 205 | 206 | if (fscanf(fp, "%15s", string) != 1) { 207 | fprintf(stderr, "read of crypto algorithm from psp_cfg_file failed\n"); 208 | goto err_exit; 209 | } 210 | if (strcmp(string, "aes-gcm-128") == 0) { 211 | pkt_ctx->psp_cfg.crypto_alg = AES_GCM_128; 212 | } else if (strcmp(string, "aes-gcm-256") == 0) { 213 | pkt_ctx->psp_cfg.crypto_alg = AES_GCM_256; 214 | } else { 215 | fprintf(stderr, "invalid crypto algotithm in psp_cfg_file\n"); 216 | goto err_exit; 217 | } 218 | 219 | if (verbose) { 220 | printf("Crypto Alg: %s\n", string); 221 | fflush(stdout); 222 | } 223 | 224 | if (fscanf(fp, "%hhu", &pkt_ctx->psp_cfg.transport_crypt_off) != 1) { 225 | fprintf(stderr, 226 | "read of transport crypt offset from psp_cfg_file failed\n"); 227 | goto err_exit; 228 | } 229 | if (pkt_ctx->psp_cfg.transport_crypt_off > PSP_CRYPT_OFFSET_MAX) { 230 | fprintf(stderr, 231 | "invalid transport crypt offset in psp_cfg_file: " 232 | "value = %hhu, max value = %d\n", 233 | pkt_ctx->psp_cfg.transport_crypt_off, PSP_CRYPT_OFFSET_MAX); 234 | goto err_exit; 235 | } 236 | 237 | if (verbose) { 238 | printf("Transport Mode Crypt Offset: %hhu (%u bytes)\n", 239 | pkt_ctx->psp_cfg.transport_crypt_off, 240 | pkt_ctx->psp_cfg.transport_crypt_off * PSP_CRYPT_OFFSET_UNITS); 241 | fflush(stdout); 242 | } 243 | 244 | if (fscanf(fp, "%hhu", &pkt_ctx->psp_cfg.ipv4_tunnel_crypt_off) != 1) { 245 | fprintf(stderr, 246 | "read of ipv4 tunnel crypt offset from psp_cfg_file failed\n"); 247 | goto err_exit; 248 | } 249 | if (pkt_ctx->psp_cfg.ipv4_tunnel_crypt_off > PSP_CRYPT_OFFSET_MAX) { 250 | fprintf(stderr, 251 | "invalid ipv4 tunnel crypt offset in psp_cfg_file: " 252 | "value = %hhu, max value = %d\n", 253 | pkt_ctx->psp_cfg.ipv4_tunnel_crypt_off, PSP_CRYPT_OFFSET_MAX); 254 | goto err_exit; 255 | } 256 | 257 | if (verbose) { 258 | printf("Tunnel Mode IPv4 Crypt Offset: %hhu (%u bytes)\n", 259 | pkt_ctx->psp_cfg.ipv4_tunnel_crypt_off, 260 | pkt_ctx->psp_cfg.ipv4_tunnel_crypt_off * PSP_CRYPT_OFFSET_UNITS); 261 | fflush(stdout); 262 | } 263 | 264 | if (fscanf(fp, "%hhu", &pkt_ctx->psp_cfg.ipv6_tunnel_crypt_off) != 1) { 265 | fprintf(stderr, 266 | "read of ipv6 tunnel crypt offset from psp_cfg_file failed\n"); 267 | goto err_exit; 268 | } 269 | if (pkt_ctx->psp_cfg.ipv6_tunnel_crypt_off > PSP_CRYPT_OFFSET_MAX) { 270 | fprintf(stderr, 271 | "invalid ipv6 tunnel crypt offset in psp_cfg_file: " 272 | "value = %hhu, max value = %d\n", 273 | pkt_ctx->psp_cfg.ipv6_tunnel_crypt_off, PSP_CRYPT_OFFSET_MAX); 274 | goto err_exit; 275 | } 276 | 277 | if (verbose) { 278 | printf("Tunnel Mode IPv6 Crypt Offset: %hhu (%u bytes)\n", 279 | pkt_ctx->psp_cfg.ipv6_tunnel_crypt_off, 280 | pkt_ctx->psp_cfg.ipv6_tunnel_crypt_off * PSP_CRYPT_OFFSET_UNITS); 281 | fflush(stdout); 282 | } 283 | 284 | if (fscanf(fp, "%15s", string) != 1) { 285 | fprintf(stderr, "read of vc string from psp_cfg_file failed\n"); 286 | goto err_exit; 287 | } 288 | if (strcmp(string, "vc") == 0) { 289 | pkt_ctx->psp_cfg.include_vc = true; 290 | } else if (strcmp(string, "no-vc") == 0) { 291 | pkt_ctx->psp_cfg.include_vc = false; 292 | } else { 293 | fprintf(stderr, "invalid vc string in psp_cfg_file\n"); 294 | goto err_exit; 295 | } 296 | 297 | if (verbose) { 298 | printf("VC Mode: %s\n", string); 299 | fflush(stdout); 300 | } 301 | 302 | fclose(fp); 303 | return SUCCESS_RC; 304 | 305 | err_exit: 306 | if (fp != NULL) fclose(fp); 307 | return ERR_RC; 308 | } 309 | 310 | /* get next psp initialization vector */ 311 | static inline uint64_t get_psp_iv(struct pkt_context *pkt_ctx) { 312 | uint64_t iv; 313 | 314 | iv = HTONLL(pkt_ctx->next_iv); 315 | pkt_ctx->next_iv++; 316 | return iv; 317 | } 318 | 319 | /* 320 | * derive 128b of psp encryption key 321 | * 322 | * parms: 323 | * pkt_ctx: ptr to pcaket context struct 324 | * counter: 1 => derive first 128b of key 325 | * 2 => derive second 128b of key 326 | * derived_key: ptr to location where derived ket is returned 327 | * 328 | * returns: 329 | * SUCCESS_RC: key derived successfully 330 | * ERR_RC: error deriving key 331 | */ 332 | static rc_t derive_psp_key_128(struct pkt_context *pkt_ctx, uint8_t counter, 333 | uint8_t *derived_key) { 334 | CMAC_CTX *ctx = NULL; 335 | uint32_t spi; 336 | struct psp_key_derivation_block input_block; 337 | size_t key_len, input_block_len, final_len; 338 | const void *key; 339 | 340 | spi = pkt_ctx->psp_cfg.spi; 341 | input_block_len = (size_t)PSP_KEY_DERIVATION_BLOCK_OCTETS; 342 | input_block.octets[0] = 0x00; 343 | input_block.octets[1] = 0x00; 344 | input_block.octets[2] = 0x00; 345 | input_block.octets[3] = counter; 346 | input_block.octets[4] = 0x50; 347 | input_block.octets[5] = 0x76; 348 | if (pkt_ctx->psp_cfg.crypto_alg == AES_GCM_128) { 349 | input_block.octets[6] = 0x30; 350 | input_block.octets[14] = 0x00; 351 | input_block.octets[15] = 0x80; 352 | } else { 353 | input_block.octets[6] = 0x31; 354 | input_block.octets[14] = 0x01; 355 | input_block.octets[15] = 0x00; 356 | } 357 | input_block.octets[7] = 0x00; 358 | input_block.octets[8] = (spi >> 24) & 0xff; 359 | input_block.octets[9] = (spi >> 16) & 0xff; 360 | input_block.octets[10] = (spi >> 8) & 0xff; 361 | input_block.octets[11] = spi & 0xff; 362 | input_block.octets[12] = 0x00; 363 | input_block.octets[13] = 0x00; 364 | 365 | if (spi & PSP_SPI_KEY_SELECTOR_BIT) 366 | key = (const void *)pkt_ctx->psp_cfg.master_key1.octets; 367 | else 368 | key = (const void *)pkt_ctx->psp_cfg.master_key0.octets; 369 | key_len = (size_t)AES_256_KEY_OCTETS; 370 | 371 | ctx = CMAC_CTX_new(); 372 | if (ctx == NULL) { 373 | fprintf(stderr, "CMAC_CTX_new() failed\n"); 374 | goto err_exit; 375 | } 376 | 377 | if (!CMAC_Init(ctx, key, key_len, EVP_aes_256_cbc(), NULL)) { 378 | fprintf(stderr, "CMAC_Init() failed\n"); 379 | goto err_exit; 380 | } 381 | 382 | if (!CMAC_Update(ctx, (const uint8_t *)input_block.octets, input_block_len)) { 383 | fprintf(stderr, "CMAC_Update() failed\n"); 384 | goto err_exit; 385 | } 386 | 387 | if (!CMAC_Final(ctx, derived_key, &final_len)) { 388 | fprintf(stderr, "CMAC_Final() failed\n"); 389 | goto err_exit; 390 | } 391 | 392 | CMAC_CTX_free(ctx); 393 | return SUCCESS_RC; 394 | 395 | err_exit: 396 | if (ctx != NULL) CMAC_CTX_free(ctx); 397 | return ERR_RC; 398 | } 399 | 400 | /* 401 | * derive psp encryption key 402 | * 403 | * returns: 404 | * SUCCESS_RC: derived key is returned in packet context structure 405 | * ERR_RC: error deriving key 406 | */ 407 | static rc_t derive_psp_key(struct pkt_context *pkt_ctx) { 408 | rc_t rc; 409 | 410 | rc = derive_psp_key_128(pkt_ctx, (uint8_t)1, pkt_ctx->key.octets); 411 | if ((rc != SUCCESS_RC) || (pkt_ctx->psp_cfg.crypto_alg == AES_GCM_128)) 412 | return rc; 413 | return derive_psp_key_128( 414 | pkt_ctx, (uint8_t)2, 415 | &pkt_ctx->key.octets[PSP_KEY_DERIVATION_BLOCK_OCTETS]); 416 | } 417 | 418 | /* 419 | * perform psp encryption 420 | * 421 | * the code for this function is based off an example on the 422 | * OpenSSL website (see https://wiki.openssl.org/images/0/08/Evp-gcm-encrypt.c) 423 | * 424 | * parms: 425 | * pkt_ctx: ptr to context info for packet 426 | * psp: ptr to psp header of packet, 427 | * aes_cgm iv is spi concatenated with psp iv, 428 | * this is also start of additional authentication data 429 | * cleartext_len: length of cleartext to be encrypted in octets 430 | * cleartext: ptr to cleartext to encrypt 431 | * aad_len: length of additional authentication data 432 | * ciphertext: ptr to location where encrypted data is to be returned 433 | * icv: ptr to location where integrity check value is to be returned 434 | * 435 | * returns: 436 | * PKT_ENCRYPTED 437 | * PKT_ERR 438 | * */ 439 | static pkt_rc_t psp_encrypt(struct pkt_context *pkt_ctx, struct psp_hdr *psp, 440 | uint32_t cleartext_len, uint8_t *cleartext, 441 | uint32_t aad_len, uint8_t *ciphertext, 442 | struct psp_icv *icv) { 443 | int rc, len; 444 | uint8_t *aad = (uint8_t *)psp; 445 | struct aes_gcm_iv gcm_iv; 446 | EVP_CIPHER_CTX *ctx = NULL; 447 | 448 | memcpy(gcm_iv.octets, &psp->spi, PSP_SPI_OCTETS); 449 | memcpy(&gcm_iv.octets[PSP_SPI_OCTETS], &psp->iv, PSP_IV_OCTETS); 450 | 451 | /* create and initialize the cipher context */ 452 | ctx = EVP_CIPHER_CTX_new(); 453 | if (ctx == NULL) { 454 | fprintf(stderr, "EVP_CIPHER_CTX_new() failed\n"); 455 | goto err_exit; 456 | } 457 | 458 | /* initialize the encryption operation */ 459 | if (pkt_ctx->psp_cfg.crypto_alg == AES_GCM_128) 460 | rc = EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL); 461 | else 462 | rc = EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL); 463 | if (rc != 1) { 464 | fprintf(stderr, "EVP_EncryptInit_ex() failed\n"); 465 | goto err_exit; 466 | } 467 | 468 | /* initialize key and iv */ 469 | if (EVP_EncryptInit_ex(ctx, NULL, NULL, pkt_ctx->key.octets, gcm_iv.octets) != 470 | 1) { 471 | fprintf(stderr, "EVP_EncryptInit_ex() failed\n"); 472 | goto err_exit; 473 | } 474 | 475 | /* provide additional authentication data */ 476 | if (EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len) != 1) { 477 | fprintf(stderr, "EVP_EncryptUpdate() failed\n"); 478 | goto err_exit; 479 | } 480 | 481 | /* do encryption */ 482 | if (EVP_EncryptUpdate(ctx, ciphertext, &len, cleartext, cleartext_len) != 1) { 483 | fprintf(stderr, "EVP_EncryptUpdate() failed\n"); 484 | goto err_exit; 485 | } 486 | 487 | /* finalize encryption */ 488 | if (EVP_EncryptFinal_ex(ctx, ciphertext + len, &len) != 1) { 489 | fprintf(stderr, "EVP_EncryptFinal_ex() failed\n"); 490 | goto err_exit; 491 | } 492 | 493 | /* get the icv */ 494 | if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, PSP_ICV_OCTETS, 495 | icv->octets) != 1) { 496 | fprintf(stderr, "EVP_CIPHER_CTX_ctrl() failed\n"); 497 | goto err_exit; 498 | } 499 | 500 | EVP_CIPHER_CTX_free(ctx); 501 | return PKT_ENCRYPTED; 502 | 503 | err_exit: 504 | if (ctx != NULL) EVP_CIPHER_CTX_free(ctx); 505 | return PKT_ERR; 506 | } 507 | 508 | /* perform transport mode psp encapsulation */ 509 | static pkt_rc_t transport_encap(struct pkt_context *pkt_ctx) { 510 | struct eth_hdr *eth; 511 | struct ipv4_hdr *ipv4, *out_ipv4; 512 | struct ipv6_hdr *ipv6, *out_ipv6; 513 | struct udp_hdr *psp_udp; 514 | struct psp_hdr *psp; 515 | struct psp_icv *out_icv; 516 | uint8_t *ip_proto, *in_pkt, *out_pkt, *out_l4, *buf, *in_encrypt, 517 | *out_encrypt, psp_ver; 518 | uint16_t etype, ip_len, *in_l4, sport, dport; 519 | uint32_t pkt_len, max_len, eth_hdr_len, ip_hdr_len, ip_payload_len, 520 | udp_hdr_len, vc_octets, psp_encap_octets, base_psp_hdr_len, psp_hdr_len, 521 | psp_payload_len, crypt_off, crypt_off_after_ext, encrypt_len, aad_len; 522 | uint64_t *vc; 523 | pkt_rc_t pkt_rc; 524 | 525 | in_pkt = pkt_ctx->in_pkt; 526 | eth = (struct eth_hdr *)in_pkt; 527 | eth_hdr_len = pkt_ctx->eth_hdr_len; 528 | pkt_len = pkt_ctx->in_pcap_pkt_hdr->len; 529 | max_len = pkt_ctx->max_pkt_octets - PSP_TRANSPORT_ENCAP_OCTETS; 530 | 531 | if (pkt_len > max_len) { 532 | fprintf(stderr, "invalid packet, too big, %u bytes\n", pkt_len); 533 | return PKT_ERR; 534 | } 535 | 536 | etype = ntohs(eth->etype); 537 | if (etype == IPV4_ETYPE) { 538 | ipv4 = (struct ipv4_hdr *)(in_pkt + eth_hdr_len); 539 | ip_proto = &ipv4->proto; 540 | ip_hdr_len = (ipv4->ver_ihl & IPV4_IHL_MASK) * IPV4_IHL_UNITS; 541 | psp_payload_len = pkt_len - (eth_hdr_len + ip_hdr_len); 542 | } else { 543 | ipv6 = (struct ipv6_hdr *)(in_pkt + eth_hdr_len); 544 | ip_proto = &ipv6->proto; 545 | switch (*ip_proto) { 546 | case IP_PROTO_UDP: 547 | case IP_PROTO_TCP: 548 | ip_hdr_len = sizeof(struct ipv6_hdr); 549 | psp_payload_len = pkt_len - (eth_hdr_len + ip_hdr_len); 550 | break; 551 | default: 552 | return PKT_SKIPPED; 553 | } 554 | } 555 | ip_payload_len = pkt_len - (eth_hdr_len + ip_hdr_len); 556 | 557 | crypt_off = pkt_ctx->psp_cfg.transport_crypt_off * PSP_CRYPT_OFFSET_UNITS; 558 | if (crypt_off > psp_payload_len) { 559 | fprintf(stderr, "skipping packet, crypt offset too big\n"); 560 | return PKT_SKIPPED; 561 | } 562 | 563 | /* 564 | * build the psp-encapsulated packet 565 | * - copy the eth and ip headers of input packet 566 | * - insert the psp udp header 567 | * - insert the psp header 568 | * - copy crypt_off bytes from input packet starting at l4 header 569 | * - compute icv and insert encrypted data 570 | * - insert icv as psp trailer 571 | */ 572 | out_pkt = pkt_ctx->out_pkt; 573 | memcpy(out_pkt, eth, eth_hdr_len + ip_hdr_len); 574 | 575 | if (pkt_ctx->psp_cfg.include_vc) 576 | vc_octets = PSP_HDR_VC_OCTETS; 577 | else 578 | vc_octets = 0; 579 | 580 | if (crypt_off > vc_octets) 581 | crypt_off_after_ext = crypt_off - vc_octets; 582 | else 583 | crypt_off_after_ext = 0; 584 | 585 | base_psp_hdr_len = sizeof(struct psp_hdr); 586 | psp_hdr_len = base_psp_hdr_len + vc_octets; 587 | psp_encap_octets = PSP_TRANSPORT_ENCAP_OCTETS + vc_octets; 588 | 589 | if (etype == IPV4_ETYPE) { 590 | ip_len = ntohs(ipv4->len); 591 | out_ipv4 = (struct ipv4_hdr *)(out_pkt + eth_hdr_len); 592 | out_ipv4->len = htons(ip_len + psp_encap_octets); 593 | out_ipv4->proto = IP_PROTO_UDP; 594 | out_ipv4->csum = 0; 595 | out_ipv4->csum = ipv4_hdr_csum(out_ipv4); 596 | } else { 597 | ip_len = ntohs(ipv6->plen); 598 | out_ipv6 = (struct ipv6_hdr *)(out_pkt + eth_hdr_len); 599 | out_ipv6->plen = htons(ip_len + psp_encap_octets); 600 | out_ipv6->proto = IP_PROTO_UDP; 601 | } 602 | 603 | psp_udp = (struct udp_hdr *)(out_pkt + eth_hdr_len + ip_hdr_len); 604 | in_l4 = (uint16_t *)(in_pkt + eth_hdr_len + ip_hdr_len); 605 | switch (*ip_proto) { 606 | case IP_PROTO_UDP: 607 | case IP_PROTO_TCP: 608 | /* set psp udp sport to simple hash of */ 609 | /* port numbers from inner packet */ 610 | sport = ntohs(in_l4[0]); 611 | dport = ntohs(in_l4[1]); 612 | psp_udp->sport = htons(sport ^ dport); 613 | break; 614 | default: 615 | psp_udp->sport = htons(UDP_PORT_PSP); 616 | break; 617 | } 618 | psp_udp->dport = htons(UDP_PORT_PSP); 619 | psp_udp->len = htons(psp_payload_len + psp_encap_octets); 620 | psp_udp->csum = 0; 621 | udp_hdr_len = sizeof(struct udp_hdr); 622 | 623 | psp = (struct psp_hdr *)(((uint8_t *)psp_udp) + udp_hdr_len); 624 | psp->next_hdr = *ip_proto; 625 | if (pkt_ctx->psp_cfg.crypto_alg == AES_GCM_128) 626 | psp_ver = PSP_VER0; 627 | else 628 | psp_ver = PSP_VER1; 629 | if (pkt_ctx->psp_cfg.include_vc) { 630 | psp->hdr_ext_len = PSP_HDR_EXT_LEN_WITH_VC; 631 | psp->s_d_ver_v_1 = 632 | (psp_ver << PSP_HDR_VER_SHIFT) | PSP_HDR_FLAG_V | PSP_HDR_ALWAYS_1; 633 | vc = (uint64_t *)(((uint8_t *)psp) + base_psp_hdr_len); 634 | *vc = 0; 635 | } else { 636 | psp->hdr_ext_len = PSP_HDR_EXT_LEN_MIN; 637 | psp->s_d_ver_v_1 = (psp_ver << PSP_HDR_VER_SHIFT) | PSP_HDR_ALWAYS_1; 638 | } 639 | psp->crypt_off = pkt_ctx->psp_cfg.transport_crypt_off; 640 | psp->spi = htonl(pkt_ctx->psp_cfg.spi); 641 | psp->iv = get_psp_iv(pkt_ctx); 642 | 643 | out_l4 = ((uint8_t *)psp) + psp_hdr_len; 644 | memcpy(out_l4, in_l4, crypt_off_after_ext); 645 | 646 | /* build buffer for icv/encryption computation */ 647 | buf = pkt_ctx->scratch_buf; 648 | memcpy(buf, psp, psp_hdr_len); 649 | memcpy(buf + psp_hdr_len, in_l4, ip_payload_len); 650 | 651 | /* compute icv and do encryption */ 652 | in_encrypt = buf + base_psp_hdr_len + crypt_off; 653 | out_encrypt = ((uint8_t *)psp) + base_psp_hdr_len + crypt_off; 654 | encrypt_len = vc_octets + ip_payload_len - crypt_off; 655 | aad_len = base_psp_hdr_len + crypt_off; 656 | out_icv = (struct psp_icv *)(out_encrypt + encrypt_len); 657 | pkt_rc = psp_encrypt(pkt_ctx, psp, encrypt_len, in_encrypt, aad_len, 658 | out_encrypt, out_icv); 659 | if (pkt_rc != PKT_ENCRYPTED) return pkt_rc; 660 | 661 | /* force corruption error if requested */ 662 | if (force_corruption == true) 663 | psp->crypt_off |= PSP_CRYPT_OFFSET_RESERVED_BIT7; 664 | 665 | /* set pcap packet header fields for output packet */ 666 | pkt_len += psp_encap_octets; 667 | pkt_ctx->out_pcap_pkt_hdr.caplen = pkt_len; 668 | pkt_ctx->out_pcap_pkt_hdr.len = pkt_len; 669 | pkt_ctx->out_pcap_pkt_hdr.ts = pkt_ctx->in_pcap_pkt_hdr->ts; 670 | 671 | return PKT_ENCRYPTED; 672 | } 673 | 674 | /* perform tunnel mode psp encapsulation */ 675 | static pkt_rc_t tunnel_encap(struct pkt_context *pkt_ctx) { 676 | struct eth_hdr *eth; 677 | struct ipv4_hdr *ipv4, *tunnel_ipv4; 678 | struct ipv6_hdr *ipv6, *tunnel_ipv6; 679 | struct udp_hdr *psp_udp; 680 | struct psp_hdr *psp; 681 | struct psp_icv *icv; 682 | uint8_t *ip_proto, *in_pkt, *out_pkt, *in_l3, *out_l3, *buf, *in_encrypt, 683 | *out_encrypt, psp_next_hdr, psp_ver; 684 | uint16_t etype, ip_len, *in_l4, sport, dport; 685 | uint32_t pkt_len, psp_encap_octets, max_len, eth_hdr_len, ip_hdr_len, 686 | udp_hdr_len, base_psp_hdr_len, vc_octets, psp_hdr_len, psp_payload_len, 687 | crypt_off, crypt_off_after_ext, encrypt_len, aad_len; 688 | uint64_t *vc; 689 | pkt_rc_t pkt_rc; 690 | 691 | in_pkt = pkt_ctx->in_pkt; 692 | eth = (struct eth_hdr *)in_pkt; 693 | eth_hdr_len = pkt_ctx->eth_hdr_len; 694 | etype = ntohs(eth->etype); 695 | pkt_len = pkt_ctx->in_pcap_pkt_hdr->len; 696 | psp_payload_len = pkt_len - eth_hdr_len; 697 | 698 | if (pkt_ctx->psp_cfg.include_vc) 699 | vc_octets = PSP_HDR_VC_OCTETS; 700 | else 701 | vc_octets = 0; 702 | 703 | if (etype == IPV4_ETYPE) { 704 | ipv4 = (struct ipv4_hdr *)(((uint8_t *)eth) + eth_hdr_len); 705 | ip_proto = &ipv4->proto; 706 | ip_hdr_len = (ipv4->ver_ihl & IPV4_IHL_MASK) * IPV4_IHL_UNITS; 707 | ip_len = ntohs(ipv4->len); 708 | psp_encap_octets = PSP_V4_TUNNEL_ENCAP_OCTETS + vc_octets; 709 | psp_next_hdr = IP_PROTO_IPV4; 710 | crypt_off = pkt_ctx->psp_cfg.ipv4_tunnel_crypt_off * PSP_CRYPT_OFFSET_UNITS; 711 | } else { 712 | ipv6 = (struct ipv6_hdr *)(((uint8_t *)eth) + eth_hdr_len); 713 | ip_proto = &ipv6->proto; 714 | ip_hdr_len = sizeof(struct ipv6_hdr); 715 | ip_len = ntohs(ipv6->plen); 716 | psp_encap_octets = PSP_V6_TUNNEL_ENCAP_OCTETS + vc_octets; 717 | psp_next_hdr = IP_PROTO_IPV6; 718 | crypt_off = 719 | pkt_ctx->psp_cfg.ipv6_tunnel_crypt_off * PSP_CRYPT_OFFSET_UNITS; 720 | } 721 | 722 | max_len = pkt_ctx->max_pkt_octets - psp_encap_octets; 723 | 724 | if (pkt_len > max_len) { 725 | fprintf(stderr, "invalid packet, too big, %u bytes\n", pkt_len); 726 | return PKT_ERR; 727 | } 728 | 729 | if (crypt_off > psp_payload_len) { 730 | fprintf(stderr, "skipping packet, crypt offset too big\n"); 731 | return PKT_SKIPPED; 732 | } 733 | 734 | /* 735 | * build the psp-encapsulated packet 736 | * - copy the eth header of input packet 737 | * - insert ip header based on ip header of input packet 738 | * - insert the psp udp header 739 | * - insert the psp header 740 | * - copy data from input packet starting at l3 header 741 | * - compute icv and encrypt data 742 | * - insert icv as the psp trailer 743 | */ 744 | out_pkt = pkt_ctx->out_pkt; 745 | memcpy(out_pkt, eth, eth_hdr_len); 746 | 747 | if (crypt_off > vc_octets) 748 | crypt_off_after_ext = crypt_off - vc_octets; 749 | else 750 | crypt_off_after_ext = 0; 751 | 752 | base_psp_hdr_len = sizeof(struct psp_hdr); 753 | psp_hdr_len = base_psp_hdr_len + vc_octets; 754 | 755 | if (etype == IPV4_ETYPE) { 756 | tunnel_ipv4 = (struct ipv4_hdr *)(out_pkt + eth_hdr_len); 757 | memcpy(tunnel_ipv4, ipv4, sizeof(struct ipv4_hdr)); 758 | tunnel_ipv4->ver_ihl = IPV4_VER_IHL; 759 | tunnel_ipv4->len = htons(ip_len + psp_encap_octets); 760 | tunnel_ipv4->proto = IP_PROTO_UDP; 761 | tunnel_ipv4->csum = 0; 762 | tunnel_ipv4->csum = ipv4_hdr_csum(tunnel_ipv4); 763 | } else { 764 | tunnel_ipv6 = (struct ipv6_hdr *)(out_pkt + eth_hdr_len); 765 | memcpy(tunnel_ipv6, ipv6, sizeof(struct ipv6_hdr)); 766 | tunnel_ipv6->plen = htons(ip_len + psp_encap_octets); 767 | tunnel_ipv6->proto = IP_PROTO_UDP; 768 | } 769 | 770 | psp_udp = (struct udp_hdr *)(out_pkt + eth_hdr_len + ip_hdr_len); 771 | in_l4 = (uint16_t *)(in_pkt + eth_hdr_len + ip_hdr_len); 772 | switch (*ip_proto) { 773 | case IP_PROTO_UDP: 774 | case IP_PROTO_TCP: 775 | /* set psp udp sport to simple hash of */ 776 | /* port numbers from inner packet */ 777 | sport = ntohs(in_l4[0]); 778 | dport = ntohs(in_l4[1]); 779 | psp_udp->sport = htons(sport ^ dport); 780 | break; 781 | default: 782 | psp_udp->sport = htons(UDP_PORT_PSP); 783 | break; 784 | } 785 | psp_udp->dport = htons(UDP_PORT_PSP); 786 | psp_udp->len = 787 | htons(psp_payload_len + PSP_TRANSPORT_ENCAP_OCTETS + vc_octets); 788 | psp_udp->csum = 0; 789 | udp_hdr_len = sizeof(struct udp_hdr); 790 | 791 | psp = (struct psp_hdr *)(((uint8_t *)psp_udp) + udp_hdr_len); 792 | psp->next_hdr = psp_next_hdr; 793 | if (pkt_ctx->psp_cfg.crypto_alg == AES_GCM_128) 794 | psp_ver = PSP_VER0; 795 | else 796 | psp_ver = PSP_VER1; 797 | if (pkt_ctx->psp_cfg.include_vc) { 798 | psp->hdr_ext_len = PSP_HDR_EXT_LEN_WITH_VC; 799 | psp->s_d_ver_v_1 = 800 | (psp_ver << PSP_HDR_VER_SHIFT) | PSP_HDR_FLAG_V | PSP_HDR_ALWAYS_1; 801 | vc = (uint64_t *)(((uint8_t *)psp) + base_psp_hdr_len); 802 | *vc = 0; 803 | psp_hdr_len = base_psp_hdr_len + PSP_HDR_VC_OCTETS; 804 | } else { 805 | psp->hdr_ext_len = PSP_HDR_EXT_LEN_MIN; 806 | psp->s_d_ver_v_1 = (psp_ver << PSP_HDR_VER_SHIFT) | PSP_HDR_ALWAYS_1; 807 | psp_hdr_len = base_psp_hdr_len; 808 | } 809 | psp->crypt_off = crypt_off / PSP_CRYPT_OFFSET_UNITS; 810 | psp->spi = htonl(pkt_ctx->psp_cfg.spi); 811 | psp->iv = get_psp_iv(pkt_ctx); 812 | 813 | in_l3 = (((uint8_t *)eth) + eth_hdr_len); 814 | out_l3 = ((uint8_t *)psp) + psp_hdr_len; 815 | memcpy(out_l3, in_l3, crypt_off_after_ext); 816 | 817 | /* build buffer for icv/encryption computation */ 818 | buf = pkt_ctx->scratch_buf; 819 | memcpy(buf, psp, psp_hdr_len); 820 | memcpy(buf + psp_hdr_len, in_l3, psp_payload_len); 821 | 822 | /* compute icv and do encryption */ 823 | in_encrypt = buf + base_psp_hdr_len + crypt_off; 824 | out_encrypt = ((uint8_t *)psp) + base_psp_hdr_len + crypt_off; 825 | encrypt_len = vc_octets + psp_payload_len - crypt_off; 826 | aad_len = base_psp_hdr_len + crypt_off; 827 | icv = (struct psp_icv *)(out_encrypt + encrypt_len); 828 | pkt_rc = psp_encrypt(pkt_ctx, psp, encrypt_len, in_encrypt, aad_len, 829 | out_encrypt, icv); 830 | if (pkt_rc != PKT_ENCRYPTED) return pkt_rc; 831 | 832 | /* force corruption error if requested */ 833 | if (force_corruption == true) 834 | psp->crypt_off |= PSP_CRYPT_OFFSET_RESERVED_BIT7; 835 | 836 | /* set pcap packet header fields for output packet */ 837 | pkt_len += psp_encap_octets; 838 | pkt_ctx->out_pcap_pkt_hdr.caplen = pkt_len; 839 | pkt_ctx->out_pcap_pkt_hdr.len = pkt_len; 840 | pkt_ctx->out_pcap_pkt_hdr.ts = pkt_ctx->in_pcap_pkt_hdr->ts; 841 | 842 | return PKT_ENCRYPTED; 843 | } 844 | 845 | /* process packet read from input pcap file */ 846 | static pkt_rc_t process_in_pkt(struct pkt_context *pkt_ctx) { 847 | struct eth_hdr *eth; 848 | uint16_t etype; 849 | 850 | if (pkt_ctx->in_pcap_pkt_hdr->caplen != pkt_ctx->in_pcap_pkt_hdr->len) { 851 | fprintf(stderr, "partial packet captures not supported\n"); 852 | return PKT_ERR; 853 | } 854 | 855 | eth = (struct eth_hdr *)pkt_ctx->in_pkt; 856 | etype = ntohs(eth->etype); 857 | switch (etype) { 858 | case IPV4_ETYPE: 859 | case IPV6_ETYPE: 860 | pkt_ctx->eth_hdr_len = sizeof(struct eth_hdr); 861 | break; 862 | default: 863 | fprintf(stderr, "skipping non-IP packet, etype = 0x%x\n", etype); 864 | return PKT_SKIPPED; 865 | } 866 | 867 | if (pkt_ctx->psp_cfg.psp_encap == PSP_TRANSPORT) 868 | return transport_encap(pkt_ctx); 869 | return tunnel_encap(pkt_ctx); 870 | } 871 | 872 | int main(int argc, char *argv[]) { 873 | int i, opt, n = 0, skipped = 0, rc = EXIT_SUCCESS, pcap_rc; 874 | pkt_rc_t pkt_rc; 875 | pcap_t *in_pd = NULL, *out_pd = NULL; 876 | pcap_dumper_t *pdumper = NULL; 877 | char *in_pcap_file = DEFAULT_CLEARTEXT_PCAP_FILE, 878 | *out_pcap_file = DEFAULT_ENCRYPT_PCAP_FILE, 879 | *cfg_file = DEFAULT_ENCRYPT_CFG_FILE; 880 | struct stat stat_buf; 881 | struct pkt_context pkt_ctx; 882 | 883 | pkt_ctx.max_pkt_octets = ETH_JUMBO_MAX_OCTETS; 884 | pkt_ctx.out_pkt = NULL; 885 | pkt_ctx.next_iv = PSP_INITIAL_IV; 886 | pkt_ctx.scratch_buf = NULL; 887 | 888 | /* handle command line args */ 889 | while ((opt = getopt(argc, argv, "c:i:o:ve")) != -1) { 890 | switch (opt) { 891 | case 'c': 892 | cfg_file = optarg; 893 | break; 894 | case 'i': 895 | in_pcap_file = optarg; 896 | break; 897 | case 'o': 898 | out_pcap_file = optarg; 899 | break; 900 | case 'v': 901 | verbose = true; 902 | break; 903 | case 'e': 904 | force_corruption = true; 905 | break; 906 | default: 907 | fprintf(stderr, 908 | "Usage: %s [-c cfg_file] [-i in_file] " 909 | "[-o out_file] [-e]\n", 910 | argv[0]); 911 | goto err_exit; 912 | break; 913 | } 914 | } 915 | 916 | if (verbose) { 917 | printf("starting %s\n", argv[0]); 918 | fflush(stdout); 919 | } 920 | 921 | /* read psp config file */ 922 | if (get_psp_cfg(cfg_file, &pkt_ctx) != SUCCESS_RC) goto err_exit; 923 | 924 | /* derive psp encryption key */ 925 | if (derive_psp_key(&pkt_ctx) != SUCCESS_RC) goto err_exit; 926 | 927 | if (verbose) { 928 | printf("Derived Key:\n "); 929 | for (i = 0; i < PSP_KEY_DERIVATION_BLOCK_OCTETS; i++) 930 | printf("%02hhx ", pkt_ctx.key.octets[i]); 931 | if (pkt_ctx.psp_cfg.crypto_alg == AES_GCM_256) { 932 | for (i = 0; i < PSP_KEY_DERIVATION_BLOCK_OCTETS; i++) 933 | printf("%02hhx ", 934 | pkt_ctx.key.octets[PSP_KEY_DERIVATION_BLOCK_OCTETS + i]); 935 | } 936 | printf("\n"); 937 | fflush(stdout); 938 | } 939 | 940 | /* open output pcap file */ 941 | out_pd = pcap_open_dead(DLT_EN10MB, pkt_ctx.max_pkt_octets); 942 | if (out_pd == NULL) { 943 | fprintf(stderr, "pcap_open_dead() failed\n"); 944 | goto err_exit; 945 | } 946 | 947 | pdumper = pcap_dump_open(out_pd, out_pcap_file); 948 | if (pdumper == NULL) { 949 | fprintf(stderr, "pcap_dump_open() failed\n"); 950 | goto err_exit; 951 | } 952 | 953 | /* open input pcap file */ 954 | if (stat(in_pcap_file, &stat_buf) != 0) { 955 | fprintf(stderr, "stat() failed for %s\n", in_pcap_file); 956 | goto err_exit; 957 | } 958 | in_pd = pcap_open_offline(in_pcap_file, NULL); 959 | if (in_pd == NULL) { 960 | fprintf(stderr, "pcap_open_offline() failed\n"); 961 | goto err_exit; 962 | } 963 | 964 | /* allocate packet buffers */ 965 | pkt_ctx.out_pkt = calloc(1, pkt_ctx.max_pkt_octets); 966 | if (pkt_ctx.out_pkt == NULL) { 967 | fprintf(stderr, "calloc() failed\n"); 968 | goto err_exit; 969 | } 970 | 971 | pkt_ctx.scratch_buf = calloc(1, pkt_ctx.max_pkt_octets); 972 | if (pkt_ctx.scratch_buf == NULL) { 973 | fprintf(stderr, "calloc() failed\n"); 974 | goto err_exit; 975 | } 976 | 977 | /* process packets from input pcap file */ 978 | while (1) { 979 | pcap_rc = pcap_next_ex(in_pd, &pkt_ctx.in_pcap_pkt_hdr, 980 | (const u_char **)&pkt_ctx.in_pkt); 981 | if (pcap_rc == 1) { 982 | /* packet read without error from pcap file */ 983 | pkt_rc = process_in_pkt(&pkt_ctx); 984 | if (pkt_rc == PKT_ERR) { 985 | goto err_exit; 986 | } else if (pkt_rc == PKT_SKIPPED) { 987 | skipped++; 988 | } else { 989 | /* write encrypted packet to output pcap file */ 990 | pcap_dump((u_char *)pdumper, &pkt_ctx.out_pcap_pkt_hdr, 991 | (u_char *)pkt_ctx.out_pkt); 992 | n++; 993 | } 994 | } else if (pcap_rc == PCAP_ERROR_BREAK) { 995 | /* no more packets to read */ 996 | break; 997 | } else { 998 | pcap_perror(in_pd, "pcap_next_ex() failed"); 999 | goto err_exit; 1000 | } 1001 | } 1002 | 1003 | printf("encrypted %d packets in %s, skipped %d packets\n", n, out_pcap_file, 1004 | skipped); 1005 | goto exit; 1006 | 1007 | err_exit: 1008 | fflush(stdout); 1009 | fprintf(stderr, "psp encryption failed\n"); 1010 | fflush(stderr); 1011 | rc = EXIT_FAILURE; 1012 | 1013 | exit: 1014 | free(pkt_ctx.scratch_buf); 1015 | free(pkt_ctx.out_pkt); 1016 | if (pdumper != NULL) pcap_dump_close(pdumper); 1017 | if (out_pd != NULL) pcap_close(out_pd); 1018 | if (in_pd != NULL) pcap_close(in_pd); 1019 | 1020 | exit(rc); 1021 | } 1022 | -------------------------------------------------------------------------------- /test/all_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | pass=0 18 | fail=0 19 | 20 | run_test () 21 | { 22 | $1 23 | if [ $? -ne 0 ]; then 24 | ((fail++)) 25 | else 26 | ((pass++)) 27 | fi 28 | echo "" 29 | } 30 | 31 | run_test ./v4_transport_crypt_off_128.sh 32 | run_test ./v4_transport_no_crypt_off_128.sh 33 | run_test ./v4_transport_crypt_off_256.sh 34 | run_test ./v4_transport_no_crypt_off_256.sh 35 | run_test ./v4_tunnel_crypt_off_128.sh 36 | run_test ./v4_tunnel_no_crypt_off_128.sh 37 | run_test ./v4_tunnel_crypt_off_256.sh 38 | run_test ./v4_tunnel_no_crypt_off_256.sh 39 | run_test ./v6_transport_crypt_off_128.sh 40 | run_test ./v6_transport_no_crypt_off_128.sh 41 | run_test ./v6_transport_crypt_off_256.sh 42 | run_test ./v6_transport_no_crypt_off_256.sh 43 | run_test ./v6_tunnel_crypt_off_128.sh 44 | run_test ./v6_tunnel_no_crypt_off_128.sh 45 | run_test ./v6_tunnel_crypt_off_256.sh 46 | run_test ./v6_tunnel_no_crypt_off_256.sh 47 | run_test ./v4_transport_crypt_off_128_empty.sh 48 | run_test ./v6_tunnel_crypt_off_256_empty.sh 49 | run_test ./v4_transport_crypt_off_128_vc.sh 50 | run_test ./v4_transport_no_crypt_off_128_vc.sh 51 | run_test ./v6_tunnel_crypt_off_256_vc.sh 52 | run_test ./v6_tunnel_no_crypt_off_256_vc.sh 53 | run_test ./v4_transport_crypt_off_128_err.sh 54 | run_test ./v6_tunnel_crypt_off_256_err.sh 55 | echo "$pass tests PASSED, $fail tests FAILED" 56 | 57 | -------------------------------------------------------------------------------- /test/v4_transport_crypt_off_128.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_transport_crypt_off_128.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v4_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v4_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v4_encrypt_transport_crypt_off_128.pcap" 22 | DECRYPT_PCAP="../pcap/v4_decrypt_transport_crypt_off_128.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v4_decrypt_transport_crypt_off_128_pcap.txt" 24 | DIFF="./v4_transport_crypt_off_128.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v4_transport_crypt_off_128_empty.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_transport_crypt_off_128_empty.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v4_cleartext_empty.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v4_cleartext_empty_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v4_encrypt_transport_crypt_off_128_empty.pcap" 22 | DECRYPT_PCAP="../pcap/v4_decrypt_transport_crypt_off_128_empty.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v4_decrypt_transport_crypt_off_128_empty_pcap.txt" 24 | DIFF="./v4_transport_crypt_off_128_empty.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v4_transport_crypt_off_128_err.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_transport_crypt_off_128.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v4_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v4_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v4_encrypt_transport_crypt_off_128.pcap" 22 | DECRYPT_PCAP="../pcap/v4_decrypt_transport_crypt_off_128.pcap" 23 | 24 | echo "STARTING: $0" 25 | 26 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 27 | 28 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP -e 29 | if [ $? -ne 0 ] 30 | then 31 | echo "FAILED: $0" 32 | exit 1 33 | fi 34 | 35 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 36 | if [ $? -eq 0 ] 37 | then 38 | echo "FAILED: $0" 39 | exit 1 40 | fi 41 | 42 | echo "PASSED: $0" 43 | -------------------------------------------------------------------------------- /test/v4_transport_crypt_off_128_vc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_transport_crypt_off_128_vc.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v4_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v4_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v4_encrypt_transport_crypt_off_128_vc.pcap" 22 | DECRYPT_PCAP="../pcap/v4_decrypt_transport_crypt_off_128_vc.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v4_decrypt_transport_crypt_off_128_vc_pcap.txt" 24 | DIFF="./v4_transport_crypt_off_128_vc.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v4_transport_crypt_off_256.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_transport_crypt_off_256.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v4_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v4_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v4_encrypt_transport_crypt_off_256.pcap" 22 | DECRYPT_PCAP="../pcap/v4_decrypt_transport_crypt_off_256.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v4_decrypt_transport_crypt_off_256_pcap.txt" 24 | DIFF="./v4_transport_crypt_off_256.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | else 62 | rm -f $DIFF 63 | echo "PASSED: $0" 64 | fi 65 | -------------------------------------------------------------------------------- /test/v4_transport_no_crypt_off_128.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_transport_no_crypt_off_128.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v4_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v4_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v4_encrypt_transport_no_crypt_off_128.pcap" 22 | DECRYPT_PCAP="../pcap/v4_decrypt_transport_no_crypt_off_128.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v4_decrypt_transport_no_crypt_off_128_pcap.txt" 24 | DIFF="./v4_transport_no_crypt_off_128.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v4_transport_no_crypt_off_128_vc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_transport_no_crypt_off_128_vc.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v4_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v4_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v4_encrypt_transport_no_crypt_off_128_vc.pcap" 22 | DECRYPT_PCAP="../pcap/v4_decrypt_transport_no_crypt_off_128_vc.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v4_decrypt_transport_no_crypt_off_128_vc_pcap.txt" 24 | DIFF="./v4_transport_no_crypt_off_128_vc.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v4_transport_no_crypt_off_256.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_transport_no_crypt_off_256.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v4_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v4_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v4_encrypt_transport_no_crypt_off_256.pcap" 22 | DECRYPT_PCAP="../pcap/v4_decrypt_transport_no_crypt_off_256.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v4_decrypt_transport_no_crypt_off_256_pcap.txt" 24 | DIFF="./v4_transport_no_crypt_off_256.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | else 62 | rm -f $DIFF 63 | echo "PASSED: $0" 64 | fi 65 | -------------------------------------------------------------------------------- /test/v4_tunnel_crypt_off_128.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_tunnel_crypt_off_128.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v4_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v4_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v4_encrypt_tunnel_crypt_off_128.pcap" 22 | DECRYPT_PCAP="../pcap/v4_decrypt_tunnel_crypt_off_128.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v4_decrypt_tunnel_crypt_off_128_pcap.txt" 24 | DIFF="./v4_tunnel_crypt_off_128.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v4_tunnel_crypt_off_256.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_tunnel_crypt_off_256.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v4_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v4_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v4_encrypt_tunnel_crypt_off_256.pcap" 22 | DECRYPT_PCAP="../pcap/v4_decrypt_tunnel_crypt_off_256.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v4_decrypt_tunnel_crypt_off_256_pcap.txt" 24 | DIFF="./v4_tunnel_crypt_off_256.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v4_tunnel_no_crypt_off_128.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_tunnel_no_crypt_off_128.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v4_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v4_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v4_encrypt_tunnel_no_crypt_off_128.pcap" 22 | DECRYPT_PCAP="../pcap/v4_decrypt_tunnel_no_crypt_off_128.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v4_decrypt_tunnel_no_crypt_off_128_pcap.txt" 24 | DIFF="./v4_tunnel_no_crypt_off_128.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v4_tunnel_no_crypt_off_256.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_tunnel_no_crypt_off_256.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v4_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v4_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v4_encrypt_tunnel_no_crypt_off_256.pcap" 22 | DECRYPT_PCAP="../pcap/v4_decrypt_tunnel_no_crypt_off_256.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v4_decrypt_tunnel_no_crypt_off_256_pcap.txt" 24 | DIFF="./v4_tunnel_no_crypt_off_256.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v6_transport_crypt_off_128.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_transport_crypt_off_128.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v6_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v6_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v6_encrypt_transport_crypt_off_128.pcap" 22 | DECRYPT_PCAP="../pcap/v6_decrypt_transport_crypt_off_128.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v6_decrypt_transport_crypt_off_128_pcap.txt" 24 | DIFF="./v6_transport_crypt_off_128.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v6_transport_crypt_off_256.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_transport_crypt_off_256.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v6_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v6_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v6_encrypt_transport_crypt_off_256.pcap" 22 | DECRYPT_PCAP="../pcap/v6_decrypt_transport_crypt_off_256.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v6_decrypt_transport_crypt_off_256_pcap.txt" 24 | DIFF="./v6_transport_crypt_off_256.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | else 62 | rm -f $DIFF 63 | echo "PASSED: $0" 64 | fi 65 | -------------------------------------------------------------------------------- /test/v6_transport_no_crypt_off_128.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_transport_no_crypt_off_128.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v6_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v6_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v6_encrypt_transport_no_crypt_off_128.pcap" 22 | DECRYPT_PCAP="../pcap/v6_decrypt_transport_no_crypt_off_128.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v6_decrypt_transport_no_crypt_off_128_pcap.txt" 24 | DIFF="./v6_transport_no_crypt_off_128.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v6_transport_no_crypt_off_256.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_transport_no_crypt_off_256.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v6_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v6_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v6_encrypt_transport_no_crypt_off_256.pcap" 22 | DECRYPT_PCAP="../pcap/v6_decrypt_transport_no_crypt_off_256.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v6_decrypt_transport_no_crypt_off_256_pcap.txt" 24 | DIFF="./v6_transport_no_crypt_off_256.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | else 62 | rm -f $DIFF 63 | echo "PASSED: $0" 64 | fi 65 | -------------------------------------------------------------------------------- /test/v6_tunnel_crypt_off_128.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_tunnel_crypt_off_128.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v6_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v6_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v6_encrypt_tunnel_crypt_off_128.pcap" 22 | DECRYPT_PCAP="../pcap/v6_decrypt_tunnel_crypt_off_128.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v6_decrypt_tunnel_crypt_off_128_pcap.txt" 24 | DIFF="./v6_tunnel_crypt_off_128.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v6_tunnel_crypt_off_256.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_tunnel_crypt_off_256.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v6_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v6_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v6_encrypt_tunnel_crypt_off_256.pcap" 22 | DECRYPT_PCAP="../pcap/v6_decrypt_tunnel_crypt_off_256.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v6_decrypt_tunnel_crypt_off_256_pcap.txt" 24 | DIFF="./v6_tunnel_crypt_off_256.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v6_tunnel_crypt_off_256_empty.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_tunnel_crypt_off_256_empty.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v6_cleartext_empty.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v6_cleartext_empty_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v6_encrypt_tunnel_crypt_off_256_empty.pcap" 22 | DECRYPT_PCAP="../pcap/v6_decrypt_tunnel_crypt_off_256_empty.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v6_decrypt_tunnel_crypt_off_256_empty_pcap.txt" 24 | DIFF="./v6_tunnel_crypt_off_256_empty.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v6_tunnel_crypt_off_256_err.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_tunnel_crypt_off_256.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v6_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v6_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v6_encrypt_tunnel_crypt_off_256.pcap" 22 | DECRYPT_PCAP="../pcap/v6_decrypt_tunnel_crypt_off_256.pcap" 23 | 24 | echo "STARTING: $0" 25 | 26 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 27 | 28 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP -e 29 | if [ $? -ne 0 ] 30 | then 31 | echo "FAILED: $0" 32 | exit 1 33 | fi 34 | 35 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 36 | if [ $? -eq 0 ] 37 | then 38 | echo "FAILED: $0" 39 | exit 1 40 | fi 41 | 42 | echo "PASSED: $0" 43 | -------------------------------------------------------------------------------- /test/v6_tunnel_crypt_off_256_vc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_tunnel_crypt_off_256_vc.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v6_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v6_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v6_encrypt_tunnel_crypt_off_256_vc.pcap" 22 | DECRYPT_PCAP="../pcap/v6_decrypt_tunnel_crypt_off_256_vc.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v6_decrypt_tunnel_crypt_off_256_vc_pcap.txt" 24 | DIFF="./v6_tunnel_crypt_off_256_vc.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v6_tunnel_no_crypt_off_128.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_tunnel_no_crypt_off_128.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v6_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v6_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v6_encrypt_tunnel_no_crypt_off_128.pcap" 22 | DECRYPT_PCAP="../pcap/v6_decrypt_tunnel_no_crypt_off_128.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v6_decrypt_tunnel_no_crypt_off_128_pcap.txt" 24 | DIFF="./v6_tunnel_no_crypt_off_128.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v6_tunnel_no_crypt_off_256.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_tunnel_no_crypt_off_256.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v6_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v6_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v6_encrypt_tunnel_no_crypt_off_256.pcap" 22 | DECRYPT_PCAP="../pcap/v6_decrypt_tunnel_no_crypt_off_256.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v6_decrypt_tunnel_no_crypt_off_256_pcap.txt" 24 | DIFF="./v6_tunnel_no_crypt_off_256.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /test/v6_tunnel_no_crypt_off_256_vc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2022 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | ENCRYPT_CFG="../cfg/encrypt_tunnel_no_crypt_off_256_vc.cfg" 18 | DECRYPT_CFG="../cfg/decrypt.cfg" 19 | CLEARTEXT_PCAP="../pcap/v6_cleartext.pcap" 20 | CLEARTEXT_PCAP_TXT="../pcap/v6_cleartext_pcap.txt" 21 | ENCRYPT_PCAP="../pcap/v6_encrypt_tunnel_no_crypt_off_256_vc.pcap" 22 | DECRYPT_PCAP="../pcap/v6_decrypt_tunnel_no_crypt_off_256_vc.pcap" 23 | DECRYPT_PCAP_TXT="../pcap/v6_decrypt_tunnel_no_crypt_off_256_vc_pcap.txt" 24 | DIFF="./v6_tunnel_no_crypt_off_256_vc.diff" 25 | 26 | echo "STARTING: $0" 27 | 28 | rm -f $ENCRYPT_PCAP $DECRYPT_PCAP $DECRYPT_PCAP_TXT $DIFF 29 | 30 | ../src/psp_encrypt -c $ENCRYPT_CFG -i $CLEARTEXT_PCAP -o $ENCRYPT_PCAP 31 | if [ $? -ne 0 ] 32 | then 33 | echo "FAILED: $0" 34 | exit 1 35 | fi 36 | 37 | ../src/psp_decrypt -c $DECRYPT_CFG -i $ENCRYPT_PCAP -o $DECRYPT_PCAP 38 | if [ $? -ne 0 ] 39 | then 40 | echo "FAILED: $0" 41 | exit 1 42 | fi 43 | 44 | tcpdump -qnts 0 -xx -r $DECRYPT_PCAP > $DECRYPT_PCAP_TXT 45 | if [ $? -ne 0 ] 46 | then 47 | echo "FAILED: $0" 48 | exit 1 49 | fi 50 | 51 | diff $CLEARTEXT_PCAP_TXT $DECRYPT_PCAP_TXT > $DIFF 52 | if [ $? -ne 0 ] 53 | then 54 | echo "FAILED: $0" 55 | exit 1 56 | fi 57 | 58 | if [ -s $DIFF ] 59 | then 60 | echo "FAILED: $0" 61 | exit 1 62 | else 63 | rm -f $DIFF 64 | echo "PASSED: $0" 65 | fi 66 | -------------------------------------------------------------------------------- /wireshark/psp.lua: -------------------------------------------------------------------------------- 1 | -- Wireshark plugin to dissect PSP protocol and display on Wireshark and tshark 2 | -- tools. 3 | -- 4 | -- Usage: 5 | -- wireshark \ 6 | -- -X lua_script:net/hostdatapath/tools/wireshark/plugins/psp.lua \ 7 | -- 8 | -- 9 | -- tshark \ 10 | -- -X lua_script:net/hostdatapath/tools/wireshark/plugins/psp.lua \ 11 | -- -r 12 | -- 1 0.000000 10.157.132.25 -> 10.157.132.26 PSP 1526 NxtHdr: IPv4 SPI: 0x101 SecToken: 0x87654321 VirtKey: 0x8000000a 13 | -- 2 0.000000 10.157.132.25 -> 10.157.132.26 PSP 154 NxtHdr: IPv4 SPI: 0x101 SecToken: 0x87654321 VirtKey: 0x8000000a 14 | -- 3 1.000050 10.157.132.25 -> 10.157.132.26 PSP 1526 NxtHdr: IPv4 SPI: 0x101 SecToken: 0x87654321 VirtKey: 0x8000000a 15 | -- 4 1.000050 10.157.132.25 -> 10.157.132.26 PSP 154 NxtHdr: IPv4 SPI: 0x101 SecToken: 0x87654321 VirtKey: 0x8000000a 16 | -- 17 | -- Reference: 18 | -- 1. https://wiki.wireshark.org/Lua 19 | -- 2. https://wiki.wireshark.org/LuaAPI 20 | -- 3. https://www.wireshark.org/docs/wsdg_html_chunked/index.html 21 | 22 | -- Create PSP fields to display in the PSP protocol tree. 23 | -- Next Header 24 | local next_header_values = { 25 | [4] = "IPv4", 26 | [41] = "IPv6", 27 | [17] = "UDP", 28 | [6] = "TCP", 29 | [132] = "SCTP", 30 | } 31 | next_header_pf = ProtoField.uint8( 32 | "psp.nexthdr", "Next Header", base.DEC, next_header_values, nil, 33 | "IPPROTO value describing the payload of PSP") 34 | 35 | -- Header Extension Length 36 | hdrextlen_pf = ProtoField.uint8( 37 | "psp.hdrextlen", "Header Extension Length", base.DEC, nil, nil, 38 | "Header length in units of 8 bytes excluding the first 8 bytes") 39 | 40 | -- Crypt Offset and Reserved field 41 | cryptoffset_byte_pf = ProtoField.string( 42 | "psp.cryptoffset_byte", "Crypt Offset") 43 | cryptoffset_pf = ProtoField.uint8("psp.cryptoffset", "Crypt Offset", base.DEC, 44 | nil, 0x3f, "Number of 4-byte words not encrypted after IV") 45 | reserved0_pf = ProtoField.uint8( 46 | "psp.reserved0", "Reserved", base.DEC, nil, 0xc0) 47 | 48 | -- Version and flags 49 | version_byte_pf = ProtoField.string("psp.version_byte", "Version") 50 | version_pf = ProtoField.uint8( 51 | "psp.version", "Version", base.DEC, nil, 0x3c, "PSP version") 52 | reserved1_pf = ProtoField.uint8( 53 | "psp.reserved1", "Reserved", base.DEC, nil, 0xc0) 54 | is_virt_pf = ProtoField.bool( 55 | "psp.is_virt", "V bit", 8, nil, 0x2, 56 | "Bit indicating if virtualization cookie is present") 57 | always_one_pf = ProtoField.bool("psp.one_bit", "One bit", 8, nil, 0x1) 58 | 59 | -- Security Parameters Index 60 | spi_pf = ProtoField.uint32("psp.spi", "Security Parameters Index", base.HEX_DEC, 61 | nil, nil, "Index to identify security association (SA)") 62 | 63 | -- Initialization Value 64 | iv_pf = ProtoField.uint64("psp.iv", "Initialization Vector", base.HEX_DEC) 65 | 66 | -- Virtualization Cookie 67 | vc_pf = ProtoField.uint64("psp.vc", "Virtualization Cookie", base.HEX_DEC) 68 | vc_key_pf = ProtoField.uint32( 69 | "psp.virtkey", "Virtualization Key", base.HEX_DEC) 70 | vc_token_pf = ProtoField.uint32("psp.sectoken", "Security Token", base.HEX_DEC) 71 | 72 | -- Payload 73 | payload_pf = ProtoField.bytes("psp.payload", "Payload") 74 | 75 | -- ICV 76 | icv_pf = ProtoField.bytes("psp.icv", "Integrity Checksum Value") 77 | 78 | 79 | -- Define PSP protocol and its fields. 80 | psp_proto = Proto("psp", "PSP Protocol") 81 | psp_proto.fields = { 82 | next_header_pf, hdrextlen_pf, spi_pf, iv_pf, cryptoffset_byte_pf, 83 | cryptoffset_pf, reserved0_pf, version_byte_pf, version_pf, reserved1_pf, 84 | is_virt_pf, always_one_pf, vc_pf, vc_key_pf, vc_token_pf, payload_pf, 85 | icv_pf 86 | } 87 | 88 | -- Define PSP preferences. 89 | psp_proto.prefs.encrypted_payload = Pref.bool( 90 | "Encrypted PSP packet", true, 91 | "Whether PSP packet is encrypted. If the packet is encrypted, " .. 92 | "PSP.ICV is present and PSP payload is not decoded.") 93 | 94 | ip_proto_table = DissectorTable.get("ip.proto") 95 | 96 | -- Create a function to dissect PSP protocol. 97 | function psp_proto.dissector(buffer, pinfo, tree) 98 | local function to_hex(value) 99 | return string.format("0x%x", value) 100 | end 101 | local next_header_buf = buffer(0, 1) 102 | local hdrextlen_buf = buffer(1, 1) 103 | local cryptoffset_buf = buffer(2, 1) 104 | local version_buf = buffer(3, 1) 105 | local spi_buf = buffer(4, 4) 106 | local iv_buf = buffer(8, 8) 107 | local is_virt = bit.band(version_buf:uint(), 0x2) 108 | local vc_buf = nil 109 | local sectoken_buf = nil 110 | local virtkey_buf = nil 111 | if is_virt > 0 then 112 | vc_buf = buffer(16, 8) 113 | sectoken_buf = buffer(16, 4) 114 | virtkey_buf = buffer(20, 4) 115 | end 116 | 117 | -- Construct summary. 118 | pinfo.cols.protocol:set("PSP") 119 | pinfo.cols.info:clear() 120 | local next_header = next_header_buf:uint() 121 | if next_header_values[next_header] == nil then 122 | next_header_str = "Unknown" 123 | else 124 | next_header_str = next_header_values[next_header] 125 | end 126 | local spi_str = to_hex(spi_buf:uint()) 127 | local summary = "PSP Protocol, NxtHdr: " .. next_header_str .. 128 | ", SPI: " .. spi_str 129 | pinfo.cols.info:set("NxtHdr: " .. next_header_str .. " SPI: " .. spi_str) 130 | if is_virt > 0 then 131 | local sectoken_str = to_hex(sectoken_buf:uint()) 132 | local virtkey_str = to_hex(virtkey_buf:uint()) 133 | summary = summary .. ", SecToken: " .. sectoken_str .. ", VirtKey: " .. 134 | virtkey_str 135 | pinfo.cols.info:append(" SecToken: " .. sectoken_str .. " VirtKey: " .. 136 | virtkey_str) 137 | end 138 | 139 | -- Construct PSP tree. 140 | local psp_tree = tree:add(psp_proto, buffer(), summary) 141 | psp_tree:add(next_header_pf, next_header_buf) 142 | 143 | local hdrextlen = hdrextlen_buf:uint() 144 | local hdrextlen_bytes = hdrextlen * 8 145 | local hdrextlen_item = psp_tree:add(hdrextlen_pf, hdrextlen_buf, hdrextlen) 146 | hdrextlen_item:append_text(" (" .. hdrextlen_bytes .. " bytes)") 147 | 148 | local cryptoffset = bit.band(cryptoffset_buf:uint(), 0x3f) 149 | local cryptoffset_bytes = cryptoffset * 4 150 | local cryptoffset_tree = psp_tree:add( 151 | cryptoffset_byte_pf, cryptoffset_buf, 152 | cryptoffset .. " (" .. cryptoffset_bytes .. " bytes)") 153 | cryptoffset_tree:add(cryptoffset_pf, cryptoffset_buf) 154 | cryptoffset_tree:add(reserved0_pf, cryptoffset_buf) 155 | 156 | local version = bit.rshift(bit.band(version_buf:uint(), 0x3c), 2) 157 | local version_tree = psp_tree:add(version_byte_pf, version_buf, version) 158 | version_tree:add(version_pf, version_buf, version) 159 | version_tree:add(reserved1_pf, version_buf) 160 | version_tree:add(is_virt_pf, version_buf) 161 | version_tree:add(always_one_pf, version_buf) 162 | 163 | psp_tree:add(spi_pf, spi_buf) 164 | psp_tree:add(iv_pf, iv_buf) 165 | 166 | -- Conditionally show virtualization cookie related items. 167 | if is_virt > 0 then 168 | local vc_tree = psp_tree:add(vc_pf, vc_buf) 169 | vc_tree:add(vc_key_pf, virtkey_buf) 170 | vc_tree:add(vc_token_pf, sectoken_buf) 171 | end 172 | 173 | local payload_offset = 8 + hdrextlen_bytes 174 | local payload_length = buffer:len() - payload_offset 175 | local icv_length = 16 176 | if psp_proto.prefs.encrypted_payload then 177 | payload_length = payload_length - icv_length 178 | end 179 | local payload_buf = buffer(payload_offset, payload_length) 180 | local payload_tree = psp_tree:add(payload_pf, payload_buf) 181 | if not psp_proto.prefs.encrypted_payload then 182 | local payload_dissector = ip_proto_table:get_dissector(next_header) 183 | payload_dissector:call(payload_buf:tvb(), pinfo, payload_tree) 184 | end 185 | 186 | if psp_proto.prefs.encrypted_payload then 187 | psp_tree:add(icv_pf, buffer(payload_offset + payload_length, icv_length)) 188 | end 189 | end 190 | 191 | -- Register PSP protocol to handle UDP port 1000. 192 | udp_table = DissectorTable.get("udp.port") 193 | udp_table:add(1000, psp_proto) 194 | --------------------------------------------------------------------------------