├── .gitignore
├── LICENSE
├── README.md
├── TESTING.md
├── psxtract.sln
└── src
├── cdrom.cpp
├── cdrom.h
├── crypto.cpp
├── crypto.h
├── libkirk
├── AES.c
├── AES.h
├── DES.c
├── DES.h
├── SHA1.c
├── SHA1.h
├── amctrl.c
├── amctrl.h
├── bn.c
├── ec.c
├── kirk_engine.c
└── kirk_engine.h
├── lz.cpp
├── lz.h
├── psxtract.cpp
├── psxtract.h
├── psxtract.vcxproj
├── psxtract.vcxproj.filters
├── psxtract.vcxproj.user
├── utils.cpp
└── utils.h
/.gitignore:
--------------------------------------------------------------------------------
1 | .vs/
2 | bin/
3 | src/Debug/
4 | src/Release/
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | psxtract-2
2 | ==========
3 |
4 | Tool to decrypt and convert PSOne Classics from PSP/PS3.
5 | Originally written by **Hykem**.
6 |
7 | This tool allows you to decrypt a PSOne Classics EBOOT.PBP on your PC.
8 | It features a modified version of libkirk's source code to support DES
9 | encryption/decryption and the AMCTRL functions.
10 | Also features isofix code for ensuring finalized ISO matches real discs.
11 | And uses at3tool for ATRAC3 decoding of CDDA audio tracks.
12 |
13 |
14 | Notes
15 | -------
16 |
17 | Output of running psxtract.exe EBOOT.PBP is two files - CDROM.BIN and
18 | CDROM.CUE in the current directory. You should know what to do with those.
19 |
20 | Using the "-c" option on the command line, psxtract will clean up any
21 | temporary files it generates while it runs (of which there are many).
22 | This flag is kept for backwards compatibility with old psxtract that used
23 | it to force CDROM creation. Current version always creates a BIN/CUE pair
24 | but we keep the flag for nostalgia.
25 |
26 | at3tool.exe and its accompanying dll are required to be in the same
27 | directory for ATRAC3 audio decoding of CDDA tracks.
28 |
29 | You may supply a KEYS.BIN file to the tool, but this is not necessary.
30 | Using the internal files' hashes, psxtract can calculate the key by itself.
31 |
32 | Game file manual decryption is also supported (DOCUMENT.DAT).
33 |
34 | Linux code has diverged significantly and has been removed. If you want to use
35 | this tool on Linux/OSX try it with Wine, just make sure to set WINEPREFIX approprirately.
36 | Otherwise spawning external processes needed to decode AT3 files will fail. Hint:
37 |
38 |
39 | ```$ WINEPREFIX=~/.wine/drive_c wine /path/to/psxtract.exe -c /path/to/EBOOT.PBP```
40 |
41 | For more details about the algorithms involved in the extraction process
42 | please check the following sources:
43 | - PBP unpacking:
44 | https://github.com/pspdev/pspsdk/blob/master/tools/unpack-pbp.c
45 |
46 | - PGD decryption:
47 | http://www.emunewz.net/forum/showthread.php?tid=3834 (initial research)
48 | https://code.google.com/p/jpcsp/source/browse/trunk/src/jpcsp/crypto/PGD.java (JPCSP)
49 | https://github.com/tpunix/kirk_engine/blob/master/npdrm/dnas.c (tpunix)
50 |
51 | - AMCTRL functions:
52 | https://code.google.com/p/jpcsp/source/browse/trunk/src/jpcsp/crypto/AMCTRL.java (JPCSP)
53 | https://github.com/tpunix/kirk_engine/blob/master/kirk/amctrl.c (tpunix)
54 |
55 | - CD-ROM ECC/EDC:
56 | https://github.com/DeadlySystem/isofix (Daniel Huguenin)
57 |
58 |
59 | Working games and compatibility
60 | -------------------------------
61 |
62 | Nearly all PSN eboots should be supported. Some known problems are mentioned in the bug tracker:
63 |
64 | https://github.com/has207/psxtract-2/issues
65 |
66 | If you encounter issues with a particular game report it there, but in general the game should
67 | be fully playable even in those cases where we have md5 sum mismatches vs redump.org.
68 |
69 | Generally speaking BIN/CUE pair created by this tool SHOULD match information on redump.org,
70 | in other words all .BIN files should be the correct size and match md5 hashes
71 | of a real disc dump.
72 |
73 | However, if the game has CDDA audio audio tracks, i.e. 2 or more tracks per BIN, those audio
74 | track md5 sums will NOT match redump.org info. This is working as intended, we generate the
75 | audio tracks with the correct size and as close to original as possible. However, as we're dealing
76 | with a lossy compression to ATRAC3, the conversion back to raw audio necessarily results in md5 hash
77 | mismatches for the audio tracks.
78 |
79 | The easiest way to verify hashes is by importing the game into Duckstation and checking hashes from
80 | the game Properties menu.
81 |
82 | There is one additional known issue that is actually working as intended -- with Resident Evil 2 Dualshock Edition. The EBOOT for that game retains
83 | CUE entries and pointers to audio tracks, however these were not included in the EBOOT.
84 | The audio tracks present on the physical discs are empty so this is not a real loss, just an issue
85 | with the EBOOT itself, so there will be warnings when this EBOOT is extracted but the resulting
86 | BIN/CUE is fully playable.
87 |
88 |
89 | Credits
90 | -------
91 |
92 | Daniel Huguenin (implementation of ECC/EDC CD-ROM patching)
93 |
94 | Draan, Proxima and everyone involved in kirk-engine (libkirk source code)
95 |
96 | tpunix (C port and research of the PGD and AMCTRL algorithms)
97 |
98 | PSPSDK (PBP unpacking sample code)
99 |
100 | zecoxao (Unscrambling and decoding of audio tracks)
101 |
102 | Heel (ATRACT3 decoding for CDDA tracks)
103 |
--------------------------------------------------------------------------------
/TESTING.md:
--------------------------------------------------------------------------------
1 | Testing
2 | =======
3 |
4 | There are no tests included in the code so when making changes it is important to back test that
5 | we don't break existing functionality. Here are some code paths that should be tested with example eboots:
6 |
7 | - Single disc game, no audio (vast majority of titles)
8 | - Single disc game, CDDA audio (Gaia Seed is good candidate, small file size and CDDA track plays as the game starts, other titles: Advanced V.G.2, Capcom Generation Vol 5, Castlevania SOTN, Community POM, Cotton 100%, Mad Stalker, Panzer Bandit, Pocket Fighter, Silhouette Mirage, Tron Bonne, Vib-Ribbon))
9 | - Multi disc game, no audio (Armored Core: Master of Arena, Fear Effect 1 & 2, G-Police, MGS, Parasite Eve, Policenauts, Rival Schools, Strider 2)
10 | - Multi disc game, CDDA audio (AitD:New Nightmare, Langrisser IV&V, Legend of Dragoon(JP), Maboroshi Tsukiyo, Soukuu no Tsubasa Gotha World)
11 | - Multi disc game, CDDA audio missing in EBOOT (RE2 Dualshock Edition)
12 | - CDDA tracks with short pregaps (Tsuukai Slot Shooting, GTA)
13 | - CDDA tracks with long pregaps ('99 Koushien, A. IV Evolution Global, Bowling (US), Centipede (US/EU), Dai-4-Ji Super Robot Taisen S, Hanabi: Fantast, Jet Copter X, KoF '96, KoF Kyo, Koushien V, Motteke Tamago with Ganbare, Perfect Weapon, Touge Max Saisoku Drift Master, Vib-Ribbon, Yamasa Digi Guide Hyper Rush)
14 | - CDDA tracks with large pregap on first audio track only (Chou Aniki Kyuukyoku, Nyan to Wonderful, Slam Dragon, Yamasa Digi Guide New Pulsar R, Yamasa Digi Guide M771)
15 |
16 |
17 | In order to test:
18 |
19 | - run psxtract on the relevant eboot, don't specify -c to keep TEMP files
20 | - compare CUE file to data for the game on redump.org, redump assumes all tracks are separate BIN files whereas we generate a single BIN, so use CDMage to load real disc dump then Save it in a new directory to create single BIN and compare the CUE files directly
21 | - ensure all tracks are the correct length, look at D0X_TRACK_XX.BIN files in TEMP
22 | - ensure pregap values in the CUE match redump
23 | - ensure data track passes md5 check by adding the game in Duckstation (then properties/check hashes)
24 | - ensure audio looks correct by importing track from real disc and TEMP directory created during psxtract process into Audacity (File/Import/Raw Data - Signed 16-bit PCM, Little-endian, 2 Channel (stereo), 44100Hz)
25 |
--------------------------------------------------------------------------------
/psxtract.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "psxtract", "src\psxtract.vcxproj", "{B86E1508-26B6-465B-ABEC-A35E07E2A187}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Win32 = Debug|Win32
9 | Release|Win32 = Release|Win32
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {B86E1508-26B6-465B-ABEC-A35E07E2A187}.Debug|Win32.ActiveCfg = Debug|Win32
13 | {B86E1508-26B6-465B-ABEC-A35E07E2A187}.Debug|Win32.Build.0 = Debug|Win32
14 | {B86E1508-26B6-465B-ABEC-A35E07E2A187}.Release|Win32.ActiveCfg = Release|Win32
15 | {B86E1508-26B6-465B-ABEC-A35E07E2A187}.Release|Win32.Build.0 = Release|Win32
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/src/cdrom.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 Hykem
2 | // Licensed under the terms of the GNU GPL, version 3
3 | // http://www.gnu.org/licenses/gpl-3.0.txt
4 |
5 | // Created in 2014 by Daniel Huguenin. Please ask for permission before
6 | // re-using this program or parts of it and mention my name in your project.
7 | // You may redistribute this program in unaltered form as you deem fit.
8 |
9 | #include "cdrom.h"
10 |
11 | struct fixImageStatus fixImage(char* inputfilepath, char* outputfilepath, int num_sectors, enum EDCMode form2EDCMode, bool verbose)
12 | {
13 | //Initialize return value struct
14 | struct fixImageStatus status;
15 | status.errorcode = 0;
16 | status.mode0sectors = 0;
17 | status.mode1sectors = 0;
18 | status.mode2form1sectors = 0;
19 | status.mode2form2sectors = 0;
20 | status.form2bootsectorswithedc = 0;
21 | status.form2bootsectorswithoutedc = 0;
22 | status.warnings = NULL;
23 | status.warningscount = 0;
24 |
25 | //Sync pattern
26 | unsigned char sync[SYNC_SIZE] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
27 |
28 | //Open the input file
29 | FILE* inputfile;
30 | inputfile = fopen(inputfilepath, "rb");
31 | if(inputfile == NULL)
32 | {
33 | status.errorcode = ERROR_INPUT_IO_ERROR;
34 | return status;
35 | }
36 |
37 | //Open the output file
38 | FILE* outputfile;
39 | outputfile = fopen(outputfilepath, "wb");
40 | if(outputfile == NULL)
41 | {
42 | //Close the input file
43 | fclose(inputfile);
44 |
45 | status.errorcode = ERROR_OUTPUT_IO_ERROR;
46 | return status;
47 | }
48 |
49 | //Determine file size
50 | fseek(inputfile, 0, SEEK_END);
51 | int filesize = ftell(inputfile);
52 | if (filesize < num_sectors * SECTOR_SIZE)
53 | {
54 | fclose(inputfile);
55 | status.errorcode = ERROR_IMAGE_INCOMPLETE;
56 | return status;
57 | }
58 | fseek(inputfile, 0, SEEK_SET);
59 |
60 | if(form2EDCMode == INFER)
61 | {
62 | //If the EDC mode is to be inferred, do so by looking at the bootloader
63 |
64 | //Allocate memory to hold bootloader
65 | unsigned char* bootloader = (unsigned char*) malloc(BOOTLOADER_SIZE);
66 |
67 | //Read bootloader
68 | int bytesread = fread(bootloader, 1, BOOTLOADER_SIZE, inputfile);
69 | if(bytesread != BOOTLOADER_SIZE)
70 | {
71 | //Free memory
72 | free(bootloader);
73 |
74 | status.errorcode = ERROR_IMAGE_INCOMPLETE;
75 | fclose(inputfile);
76 | fclose(outputfile);
77 | return status;
78 | }
79 |
80 | //Inspect the EDC of the four form 2 sectors in the bootloader
81 | unsigned int form2sectorsinbootloader[] = {12, 13, 14, 15};
82 | for(int i = 0; i < sizeof(form2sectorsinbootloader) / sizeof(form2sectorsinbootloader[0]); ++i)
83 | {
84 | //Navigate to the current sector
85 | unsigned char* sector = bootloader + form2sectorsinbootloader[i] * SECTOR_SIZE;
86 |
87 | //Extract EDC
88 | unsigned int EDC = (sector[CDROMXA_FORM2_EDC_OFFSET + 0] << 0)
89 | | (sector[CDROMXA_FORM2_EDC_OFFSET + 1] << 8)
90 | | (sector[CDROMXA_FORM2_EDC_OFFSET + 2] << 16)
91 | | (sector[CDROMXA_FORM2_EDC_OFFSET + 3] << 24);
92 |
93 | //Check if EDC is set and increment corresponding counters
94 | if(EDC == 0x00000000)
95 | {
96 | ++status.form2bootsectorswithoutedc;
97 | }
98 | else
99 | {
100 | ++status.form2bootsectorswithedc;
101 | }
102 | }
103 |
104 | //Change the EDC mode appropriately
105 | if(status.form2bootsectorswithoutedc >= status.form2bootsectorswithedc)
106 | {
107 | form2EDCMode = ZERO;
108 | }
109 | else
110 | {
111 | form2EDCMode = COMPUTE;
112 | }
113 |
114 | //Free memory
115 | free(bootloader);
116 |
117 | //Reset input file position (the bootloader must be fixed as well)
118 | fseek(inputfile, 0, SEEK_SET);
119 | }
120 |
121 | //Iterate over all sectors in the input file, fix them, and write
122 | unsigned char minutes = 0x00;
123 | unsigned char seconds = 0x02;
124 | unsigned char blocks = 0x00;
125 | unsigned char* sector = (unsigned char*) malloc(SECTOR_SIZE);
126 | if(sector == NULL)
127 | {
128 | status.errorcode = ERROR_OUT_OF_MEMORY;
129 | fclose(inputfile);
130 | fclose(outputfile);
131 | return status;
132 | }
133 | printf("Processing %d sectors\n", num_sectors);
134 | status.totalsectors = 0;
135 | for(int i = 0; i < num_sectors * SECTOR_SIZE; i += SECTOR_SIZE)
136 | {
137 | //Read next sector
138 | int bytesread = fread(sector, 1, SECTOR_SIZE, inputfile);
139 | if(bytesread != SECTOR_SIZE)
140 | {
141 | //Free memory
142 | free(sector);
143 |
144 | //Close the input and output files
145 | fclose(inputfile);
146 | fclose(outputfile);
147 |
148 | status.errorcode = ERROR_IMAGE_INCOMPLETE;
149 | return status;
150 | }
151 |
152 | //Find mode
153 | unsigned char mode = sector[HEADER_OFFSET + 3];
154 |
155 | //Process sector based on mode
156 | if(mode == MODE_0)
157 | {
158 | //Check that the sector is really all-zero
159 | for(int j = HEADER_OFFSET + HEADER_SIZE; j < SECTOR_SIZE; ++j)
160 | {
161 | if(sector[j] != 0x00)
162 | {
163 | //Free memory
164 | free(sector);
165 |
166 | //Close the input and output files
167 | fclose(inputfile);
168 | fclose(outputfile);
169 |
170 | status.errorcode = ERROR_MODE0_IS_NOT_0;
171 | return status;
172 | }
173 | }
174 |
175 | //We have probably reached the beginning of the zero-padding - verify if that's the case
176 |
177 | //Make a backup of the current read position in the input file
178 | int inputfile_position_backup = ftell(inputfile);
179 |
180 | //Read the remainder of the input file and check that it is all-zero
181 | bool remainder_is_zero = true;
182 | unsigned char* temp = (unsigned char*) malloc(SECTOR_SIZE);
183 | if(temp == NULL)
184 | {
185 | //Free memory
186 | free(sector);
187 |
188 | //Close the input and output files
189 | fclose(inputfile);
190 | fclose(outputfile);
191 |
192 | status.errorcode = ERROR_OUT_OF_MEMORY;
193 | return status;
194 | }
195 |
196 | for(int j = i + SECTOR_SIZE; j < filesize && remainder_is_zero; j += SECTOR_SIZE)
197 | {
198 | //Read next sector
199 | int bytesread = fread(temp, 1, SECTOR_SIZE, inputfile);
200 | if(bytesread != SECTOR_SIZE)
201 | {
202 | //Free memory
203 | free(sector);
204 | free(temp);
205 |
206 | //Close the input and output files
207 | fclose(inputfile);
208 | fclose(outputfile);
209 |
210 | status.errorcode = ERROR_IMAGE_INCOMPLETE;
211 | return status;
212 | }
213 |
214 | //Check that the sector is all-zero
215 | for(int k = 0; k < SECTOR_SIZE; ++k)
216 | {
217 | if(temp[k] != 0x00)
218 | {
219 | remainder_is_zero = false;
220 | break;
221 | }
222 | }
223 | }
224 | free(temp);
225 |
226 | if(remainder_is_zero)
227 | {
228 | //We had indeed reached the beginning of the zero-padding. We are done here!
229 | fclose(inputfile);
230 | fclose(outputfile);
231 | return status;
232 | }
233 | else
234 | {
235 | //The mode 0 sector did NOT belong to the zero-padding - it should be added to the output file
236 |
237 | //Notify the user of this unexpected condition
238 | printf("Encountered a mode 0 sector at 0x%08X that is followed by more data. This is not expected to happen, but fixing will proceed.\n", i);
239 |
240 | //Restore input file position
241 | fseek(inputfile, inputfile_position_backup, SEEK_SET);
242 |
243 | //Write sync field
244 | memcpy(sector, sync, sizeof(sync));
245 |
246 | //Write header
247 | sector[HEADER_OFFSET + 0] = minutes;
248 | sector[HEADER_OFFSET + 1] = seconds;
249 | sector[HEADER_OFFSET + 2] = blocks;
250 | sector[HEADER_OFFSET + 3] = MODE_2;
251 |
252 | //Update sector mode count
253 | ++status.mode0sectors;
254 | }
255 | }
256 | else if(mode == MODE_1)
257 | {
258 | //Free memory
259 | free(sector);
260 |
261 | //Close the input and output files
262 | fclose(inputfile);
263 | fclose(outputfile);
264 |
265 | status.errorcode = ERROR_UNSUPPORTED_MODE;
266 | return status;
267 | }
268 | else if(mode == MODE_2)
269 | {
270 | //Write sync field
271 | memcpy(sector, sync, sizeof(sync));
272 |
273 | //Read subheader
274 | unsigned char filenumber = sector[CDROMXA_SUBHEADER_OFFSET + 0];
275 | unsigned char channelnumber = sector[CDROMXA_SUBHEADER_OFFSET + 1];
276 | unsigned char submode = sector[CDROMXA_SUBHEADER_OFFSET + 2];
277 | unsigned char datatype = sector[CDROMXA_SUBHEADER_OFFSET + 3];
278 | unsigned char filenumbercopy = sector[CDROMXA_SUBHEADER_OFFSET + 4];
279 | unsigned char channelnumbercopy = sector[CDROMXA_SUBHEADER_OFFSET + 5];
280 | unsigned char submodecopy = sector[CDROMXA_SUBHEADER_OFFSET + 6];
281 | unsigned char datatypecopy = sector[CDROMXA_SUBHEADER_OFFSET + 7];
282 |
283 | //Check that the two copies of the subheader data are equivalent
284 | if(filenumber != filenumbercopy)
285 | {
286 | addWarning(status, "Corrupt CD-ROM XA subheader will be copied to the output file. File number mismatch at %02X:%02X:%02X: 0x%02X vs 0x%02X", 255, minutes, seconds, blocks, filenumber, filenumbercopy);
287 | }
288 | if(channelnumber != channelnumbercopy)
289 | {
290 | addWarning(status, "Corrupt CD-ROM XA subheader will be copied to the output file. Channel number mismatch at %02X:%02X:%02X: 0x%02X vs 0x%02X", 255, minutes, seconds, blocks, channelnumber, channelnumbercopy);
291 | }
292 | if(submode != submodecopy)
293 | {
294 | addWarning(status, "Corrupt CD-ROM XA subheader will be copied to the output file. Submode mismatch at %02X:%02X:%02X: 0x%02X vs 0x%02X", 255, minutes, seconds, blocks, submode, submodecopy);
295 | }
296 | if(datatype != datatypecopy)
297 | {
298 | addWarning(status, "Corrupt CD-ROM XA subheader will be copied to the output file. CD-ROM XA subheader corrupt. Data type mismatch at %02X:%02X:%02X: 0x%02X vs 0x%02X", 255, minutes, seconds, blocks, datatype, datatypecopy);
299 | }
300 |
301 | //Determine CD ROM XA Mode 2 form
302 | bool isForm2 = (submode & 0x20) == 0x20;
303 |
304 | //Compute and write EDC
305 | if(isForm2)
306 | {
307 | //Write header
308 | sector[HEADER_OFFSET + 0] = minutes;
309 | sector[HEADER_OFFSET + 1] = seconds;
310 | sector[HEADER_OFFSET + 2] = blocks;
311 | sector[HEADER_OFFSET + 3] = mode;
312 |
313 | //Handle form 2 EDC
314 | unsigned int EDC; //For some strange reason, a declaration in case COMPUTE would require a ; in front.
315 | switch(form2EDCMode)
316 | {
317 | case KEEP:
318 | //Leave the original in tact. Nothing to do here.
319 | break;
320 |
321 | case COMPUTE:
322 | //Compute form 2 EDC
323 | EDC = 0x00000000;
324 | for(int i = CDROMXA_SUBHEADER_OFFSET; i < CDROMXA_FORM2_EDC_OFFSET; ++i)
325 | {
326 | EDC = EDC ^ sector[i];
327 | EDC = (EDC >> 8) ^ EDCTable[EDC & 0x000000FF];
328 | }
329 |
330 | //Write EDC
331 | sector[CDROMXA_FORM2_EDC_OFFSET + 0] = (EDC & 0x000000FF) >> 0;
332 | sector[CDROMXA_FORM2_EDC_OFFSET + 1] = (EDC & 0x0000FF00) >> 8;
333 | sector[CDROMXA_FORM2_EDC_OFFSET + 2] = (EDC & 0x00FF0000) >> 16;
334 | sector[CDROMXA_FORM2_EDC_OFFSET + 3] = (EDC & 0xFF000000) >> 24;
335 | break;
336 |
337 | case ZERO:
338 | //Write zeroed EDC
339 | sector[CDROMXA_FORM2_EDC_OFFSET + 0] = 0;
340 | sector[CDROMXA_FORM2_EDC_OFFSET + 1] = 0;
341 | sector[CDROMXA_FORM2_EDC_OFFSET + 2] = 0;
342 | sector[CDROMXA_FORM2_EDC_OFFSET + 3] = 0;
343 | break;
344 | }
345 |
346 | //Update sector mode count
347 | ++status.mode2form2sectors;
348 | }
349 | else
350 | {
351 | //Compute form 1 EDC
352 | unsigned int EDC = 0x00000000;
353 | for(int i = CDROMXA_SUBHEADER_OFFSET; i < CDROMXA_FORM1_EDC_OFFSET; ++i)
354 | {
355 | EDC = EDC ^ sector[i];
356 | EDC = (EDC >> 8) ^ EDCTable[EDC & 0x000000FF];
357 | }
358 |
359 | //Write EDC
360 | sector[CDROMXA_FORM1_EDC_OFFSET + 0] = (EDC & 0x000000FF) >> 0;
361 | sector[CDROMXA_FORM1_EDC_OFFSET + 1] = (EDC & 0x0000FF00) >> 8;
362 | sector[CDROMXA_FORM1_EDC_OFFSET + 2] = (EDC & 0x00FF0000) >> 16;
363 | sector[CDROMXA_FORM1_EDC_OFFSET + 3] = (EDC & 0xFF000000) >> 24;
364 |
365 | //Write error-correction data
366 |
367 | //Temporarily clear header
368 | sector[HEADER_OFFSET + 0] = 0x00;
369 | sector[HEADER_OFFSET + 1] = 0x00;
370 | sector[HEADER_OFFSET + 2] = 0x00;
371 | sector[HEADER_OFFSET + 3] = 0x00;
372 |
373 | //Calculate P parity
374 | {
375 | unsigned char* src = sector + HEADER_OFFSET;
376 | unsigned char* dst = sector + CDROMXA_FORM1_PARITY_P_OFFSET;
377 | for(int i = 0; i < 43; ++i)
378 | {
379 | unsigned short x = 0x0000;
380 | unsigned short y = 0x0000;
381 | for(int j = 19; j < 43; ++j)
382 | {
383 | x ^= RSPCTable[j][src[0]]; //LSB
384 | y ^= RSPCTable[j][src[1]]; //MSB
385 | src += 2 * 43;
386 | }
387 | dst[ 0] = x >> 8;
388 | dst[2 * 43 + 0] = x & 0xFF;
389 | dst[ 1] = y >> 8;
390 | dst[2 * 43 + 1] = y & 0xFF;
391 | dst += 2;
392 | src -= (43 - 19) * 2 * 43; //Restore src to the state before the inner loop
393 | src += 2;
394 | }
395 | }
396 |
397 | //Calculate Q parity
398 | {
399 | unsigned char* src = sector + HEADER_OFFSET;
400 | unsigned char* dst = sector + CDROMXA_FORM1_PARITY_Q_OFFSET;
401 | unsigned char* src_end = sector + CDROMXA_FORM1_PARITY_Q_OFFSET;
402 | for(int i = 0; i < 26; ++i)
403 | {
404 | unsigned char* src_backup = src;
405 | unsigned short x = 0x0000;
406 | unsigned short y = 0x0000;
407 | for(int j = 0; j < 43; ++j)
408 | {
409 | x ^= RSPCTable[j][src[0]]; //LSB
410 | y ^= RSPCTable[j][src[1]]; //MSB
411 | src += 2 * 44;
412 | if(src >= src_end)
413 | {
414 | src = src - (HEADER_SIZE + CDROMXA_SUBHEADER_SIZE + CDROMXA_FORM1_USER_DATA_SIZE + EDC_SIZE + CDROMXA_FORM1_PARITY_P_SIZE);
415 | }
416 | }
417 |
418 | dst[ 0] = x >> 8;
419 | dst[2 * 26 + 0] = x & 0xFF;
420 | dst[ 1] = y >> 8;
421 | dst[2 * 26 + 1] = y & 0xFF;
422 | dst += 2;
423 | src = src_backup;
424 | src += 2 * 43;
425 | }
426 | }
427 |
428 | //Restore header
429 | sector[HEADER_OFFSET + 0] = minutes;
430 | sector[HEADER_OFFSET + 1] = seconds;
431 | sector[HEADER_OFFSET + 2] = blocks;
432 | sector[HEADER_OFFSET + 3] = mode;
433 |
434 | //Update sector mode count
435 | ++status.mode2form1sectors;
436 | }
437 | ++status.totalsectors;
438 | }
439 | else
440 | {
441 | //Free memory
442 | free(sector);
443 |
444 | //Close the input and output files
445 | fclose(inputfile);
446 | fclose(outputfile);
447 |
448 | status.errorcode = ERROR_UNEXPECTED_MODE;
449 | return status;
450 | }
451 |
452 | //Write fixed sector to output file
453 | int byteswritten = fwrite(sector, 1, SECTOR_SIZE, outputfile);
454 | if(byteswritten != SECTOR_SIZE)
455 | {
456 | //Free memory
457 | free(sector);
458 |
459 | //Close the input and output files
460 | fclose(inputfile);
461 | fclose(outputfile);
462 |
463 | status.errorcode = ERROR_OUTPUT_IO_ERROR;
464 | return status;
465 | }
466 |
467 | //Update position
468 | ++blocks;
469 | if((blocks & 0x0F) == 0x0A)
470 | {
471 | //Increment from BCD x9 to (x+1)0
472 | blocks += 0x06;
473 | }
474 | else
475 | {
476 | if(blocks == 0x75) //Can be in the else branch because blocks & 0x0F == 0x0A => blocks != 0x75
477 | {
478 | blocks = 0x00;
479 | ++seconds;
480 | if((seconds & 0x0F) == 0x0A)
481 | {
482 | //Increment from BCD x9 to (x+1)0
483 | seconds += 0x06;
484 | if(seconds == 0x60) //Can be in the else branch because seconds & 0x0F == 0x0A => seconds != 0x60
485 | {
486 | seconds = 0x00;
487 | ++minutes;
488 | if((minutes & 0x0F) == 0x0A)
489 | {
490 | //Increment from BCD x9 to (x+1)0
491 | minutes += 0x06;
492 | }
493 | }
494 | }
495 | }
496 | }
497 | }
498 |
499 | //Free memory
500 | free(sector);
501 |
502 | //Close the input and output files
503 | fclose(inputfile);
504 | fclose(outputfile);
505 |
506 | //Signal successful operation and return status
507 | return status;
508 | }
509 |
510 | int make_cdrom(char* inputfile, char* outputfile, int num_sectors, bool verbose)
511 | {
512 | // Use the INFER method for EDC calculation (proved to be the more accurate approach).
513 | struct fixImageStatus status = fixImage(inputfile, outputfile, num_sectors, INFER, verbose);
514 | if (verbose)
515 | {
516 | printf("Number of mode 0 sectors: %i\n", status.mode0sectors);
517 | printf("Number of mode 1 sectors: Mode 1 sectors are not supported.\n");
518 | printf("Number of mode 2 form 1 sectors: %i\n", status.mode2form1sectors);
519 | printf("Number of mode 2 form 2 sectors: %i\n", status.mode2form2sectors);
520 | printf("Mode 2 form 2 boot sectors with EDC: %i\n", status.form2bootsectorswithedc);
521 | printf("Mode 2 form 2 boot sectors without EDC: %i\n", status.form2bootsectorswithoutedc);
522 | printf("Total sectors processed: %i\n", status.totalsectors);
523 | }
524 | switch(status.errorcode)
525 | {
526 | //Print success message
527 | case 0:
528 | printf("The image has been fixed!\n");
529 | break;
530 |
531 | //Print an error message
532 | case ERROR_OUT_OF_MEMORY:
533 | printf("Out of memory!\n");
534 | break;
535 |
536 | case ERROR_INPUT_IO_ERROR:
537 | printf("Could not open input file - terminating\n");
538 | break;
539 |
540 | case ERROR_OUTPUT_IO_ERROR:
541 | printf("Could not write to output file - terminating\n");
542 | break;
543 |
544 | case ERROR_IMAGE_INCOMPLETE:
545 | printf("Image ended prematurely! The image file you provided contains an incomplete sector.\n");
546 | break;
547 |
548 | case ERROR_UNEXPECTED_MODE:
549 | printf("The image has been fixed!\nProcess stopped early, this is likely due to non-standard pregap before audio tracks present.\n");
550 | break;
551 |
552 | case ERROR_UNSUPPORTED_MODE:
553 | printf("Mode 1 sector encountered. This program does not support such images.\n");
554 | break;
555 |
556 | case ERROR_MODE0_IS_NOT_0:
557 | printf("Encountered a mode 0 sector that contained non-null data. This image is corrupt!\n");
558 | break;
559 |
560 | default:
561 | printf("Encountered unknown error: %i\n", status.errorcode);
562 | break;
563 | }
564 |
565 | if(status.warningscount > 0)
566 | {
567 | printf("%d warnings occured during the process:\n", status.warningscount);
568 | for(int i = 0; i < status.warningscount; ++i)
569 | {
570 | printf(status.warnings[i]);
571 | if (i > MAX_WARNINGS)
572 | {
573 | printf("\n(%d warnings suppressed)\n", status.warningscount - i);
574 | break;
575 | }
576 | printf("\n");
577 | }
578 | }
579 |
580 | return status.totalsectors;
581 | }
582 |
--------------------------------------------------------------------------------
/src/crypto.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 Hykem
2 | // Licensed under the terms of the GNU GPL, version 3
3 | // http://www.gnu.org/licenses/gpl-3.0.txt
4 |
5 | /*
6 | Copyright (c) 2005 adresd
7 | Copyright (c) 2005 Marcus R. Brown
8 | Copyright (c) 2005 James Forshaw
9 | Copyright (c) 2005 John Kelley
10 | Copyright (c) 2005 Jesper Svennevid
11 | All rights reserved.
12 |
13 | Redistribution and use in source and binary forms, with or without
14 | modification, are permitted provided that the following conditions
15 | are met:
16 | 1. Redistributions of source code must retain the above copyright
17 | notice, this list of conditions and the following disclaimer.
18 | 2. Redistributions in binary form must reproduce the above copyright
19 | notice, this list of conditions and the following disclaimer in the
20 | documentation and/or other materials provided with the distribution.
21 | 3. The names of the authors may not be used to endorse or promote products
22 | derived from this software without specific prior written permission.
23 |
24 | THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
25 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 | */
35 |
36 | // Unpack PBP comes from "PSPSDK - PSPDEV Open Source Project" (check above disclaimer).
37 | // Decrypt PGD is based on "pgdecrypt" by tpunix.
38 |
39 | #define _CRT_SECURE_NO_WARNINGS
40 |
41 | #include "crypto.h"
42 |
43 | int decrypt_pgd(unsigned char* pgd_data, int pgd_size, int flag, unsigned char* key)
44 | {
45 | int result;
46 | PGD_HEADER PGD[sizeof(PGD_HEADER)];
47 | MAC_KEY mkey;
48 | CIPHER_KEY ckey;
49 | unsigned char*fkey;
50 |
51 | // Read in the PGD header parameters.
52 | memset(PGD, 0, sizeof(PGD_HEADER));
53 |
54 | PGD->buf = pgd_data;
55 | PGD->key_index = *(u32*)(pgd_data + 4);
56 | PGD->drm_type = *(u32*)(pgd_data + 8);
57 |
58 | // Set the hashing, crypto and open modes.
59 | if (PGD->drm_type == 1)
60 | {
61 | PGD->mac_type = 1;
62 | flag |= 4;
63 |
64 | if(PGD->key_index > 1)
65 | {
66 | PGD->mac_type = 3;
67 | flag |= 8;
68 | }
69 | PGD->cipher_type = 1;
70 | }
71 | else
72 | {
73 | PGD->mac_type = 2;
74 | PGD->cipher_type = 2;
75 | }
76 | PGD->open_flag = flag;
77 |
78 | // Get the fixed DNAS key.
79 | fkey = NULL;
80 | if((flag & 0x2) == 0x2)
81 | fkey = dnas_key1A90;
82 | if((flag & 0x1) == 0x1)
83 | fkey = dnas_key1AA0;
84 |
85 | if (fkey == NULL)
86 | {
87 | printf("PGD: Invalid DNAS flag! %08x\n", flag);
88 | return -1;
89 | }
90 |
91 | // Test MAC hash at 0x80 (DNAS hash).
92 | sceDrmBBMacInit(&mkey, PGD->mac_type);
93 | sceDrmBBMacUpdate(&mkey, pgd_data, 0x80);
94 | result = sceDrmBBMacFinal2(&mkey, pgd_data + 0x80, fkey);
95 |
96 | if (result)
97 | {
98 | printf("PGD: Invalid 0x80 MAC hash!\n");
99 | return -1;
100 | }
101 |
102 | // Test MAC hash at 0x70 (key hash).
103 | sceDrmBBMacInit(&mkey, PGD->mac_type);
104 | sceDrmBBMacUpdate(&mkey, pgd_data, 0x70);
105 |
106 | // If a key was provided, check it against MAC 0x70.
107 | if (!isEmpty(key, 0x10))
108 | {
109 | result = sceDrmBBMacFinal2(&mkey, pgd_data + 0x70, key);
110 | if (result)
111 | {
112 | printf("PGD: Invalid 0x70 MAC hash!\n");
113 | return -1;
114 | }
115 | else
116 | {
117 | memcpy(PGD->vkey, key, 16);
118 | }
119 | }
120 | else
121 | {
122 | // Generate the key from MAC 0x70.
123 | bbmac_getkey(&mkey, pgd_data + 0x70, PGD->vkey);
124 | }
125 |
126 | // Decrypt the PGD header block (0x30 bytes).
127 | sceDrmBBCipherInit(&ckey, PGD->cipher_type, 2, pgd_data + 0x10, PGD->vkey, 0);
128 | sceDrmBBCipherUpdate(&ckey, pgd_data + 0x30, 0x30);
129 | sceDrmBBCipherFinal(&ckey);
130 |
131 | // Get the decryption parameters from the decrypted header.
132 | PGD->data_size = *(u32*)(pgd_data + 0x44);
133 | PGD->block_size = *(u32*)(pgd_data + 0x48);
134 | PGD->data_offset = *(u32*)(pgd_data + 0x4c);
135 |
136 | // Additional size variables.
137 | PGD->align_size = (PGD->data_size + 15) &~ 15;
138 | PGD->table_offset = PGD->data_offset + PGD->align_size;
139 | PGD->block_nr = (PGD->align_size + PGD->block_size - 1) &~ (PGD->block_size - 1);
140 | PGD->block_nr = PGD->block_nr / PGD->block_size;
141 |
142 | if ((PGD->align_size + PGD->block_nr * 16) > pgd_size)
143 | {
144 | printf("PGD: Invalid data size!\n");
145 | return -1;
146 | }
147 |
148 | // Test MAC hash at 0x60 (table hash).
149 | sceDrmBBMacInit(&mkey, PGD->mac_type);
150 | sceDrmBBMacUpdate(&mkey, pgd_data + PGD->table_offset, PGD->block_nr * 16);
151 | result = sceDrmBBMacFinal2(&mkey, pgd_data + 0x60, PGD->vkey);
152 |
153 | if(result)
154 | {
155 | printf("PGD: Invalid 0x60 MAC hash!\n");
156 | return -1;
157 | }
158 |
159 | // Decrypt the data.
160 | sceDrmBBCipherInit(&ckey, PGD->cipher_type, 2, pgd_data + 0x30, PGD->vkey, 0);
161 | sceDrmBBCipherUpdate(&ckey, pgd_data + 0x90, PGD->align_size);
162 | sceDrmBBCipherFinal(&ckey);
163 |
164 | return PGD->data_size;
165 | }
166 |
167 | int decrypt_doc(unsigned char* data, int size)
168 | {
169 | data += 0x10; // Skip dummy PGD header.
170 | size -= 0x10; // Adjust size.
171 |
172 | unsigned char *out = new unsigned char[size];
173 |
174 | // Perform DES CBC decryption.
175 | des_context ctx;
176 | des_setkey_dec(&ctx, des_key);
177 | des_crypt_cbc(&ctx, DES_DECRYPT, size, des_iv, data, out);
178 |
179 | // Check for "DOC" header in the decrypted data.
180 | if ((out[0] == 0x44) &&
181 | (out[1] == 0x4F) &&
182 | (out[2] == 0x43) &&
183 | (out[3] == 0x20))
184 | {
185 | // Copy back the decrypted data.
186 | memcpy(data - 0x10, out, size);
187 | delete[] out;
188 | return 0;
189 | }
190 | else
191 | {
192 | delete[] out;
193 | return -1;
194 | }
195 | }
196 |
197 | int unpack_pbp(FILE *infile)
198 | {
199 | long long maxbuffer = 32 * 1024 * 1024;
200 | PBP_HEADER header;
201 | int loop0;
202 | long long total_size;
203 |
204 | // Get the size of the PBP
205 | _fseeki64(infile, 0, SEEK_END);
206 | total_size = _ftelli64(infile);
207 | _fseeki64(infile, 0, SEEK_SET);
208 |
209 | if (total_size < 0) {
210 | printf("UNPACK_PBP ERROR: Could not get the input file size.\n");
211 | return -1;
212 | }
213 |
214 | // Read in the header
215 | if (fread(&header, sizeof(PBP_HEADER), 1, infile) < 0) {
216 | printf("UNPACK_PBP ERROR: Could not read the input file header.\n");
217 | return -1;
218 | }
219 |
220 | // Check the signature
221 | for (loop0 = 0; loop0 < sizeof(pbp_sig); loop0++) {
222 | if (header.signature[loop0] != pbp_sig[loop0]) {
223 | printf("UNPACK_PBP ERROR: Input file is not a PBP file.\n");
224 | return -1;
225 | }
226 | }
227 |
228 | // For each file in the PBP
229 | for (loop0 = 0; loop0 < 8; loop0++) {
230 | void *buffer;
231 | long long size;
232 |
233 | // Get the size of this file
234 | if (loop0 == 7) {
235 | size = total_size - header.offset[loop0];
236 | } else {
237 | size = header.offset[loop0 + 1] - header.offset[loop0];
238 | }
239 |
240 | // Print out the file details
241 | printf("[%d] %10lld bytes | %s\n", loop0, size, pbp_filenames[loop0]);
242 |
243 | // Skip the file if empty
244 | if (!size) continue;
245 |
246 | // Seek to the proper position in the file
247 | if (_fseeki64(infile, header.offset[loop0], SEEK_SET) != 0) {
248 | printf("UNPACK_PBP ERROR: Could not seek in the input file.\n");
249 | return -1;
250 | }
251 |
252 | // Open the output file
253 | FILE *outfile = fopen(pbp_filenames[loop0], "wb");
254 | if (outfile == NULL) {
255 | printf("UNPACK_PBP ERROR: Could not open the output file. (%s)\n", pbp_filenames[loop0]);
256 | return -1;
257 | }
258 |
259 | do {
260 | long long readsize;
261 |
262 | // Make sure we don't exceed the maximum buffer size
263 | if (size > maxbuffer) {
264 | readsize = maxbuffer;
265 | } else {
266 | readsize = size;
267 | }
268 | size -= readsize;
269 |
270 | // Create the read buffer
271 | buffer = malloc(readsize);
272 | if (buffer == NULL) {
273 | printf("UNPACK_PBP ERROR: Could not allocate the section data buffer. (%d)\n", readsize);
274 | return -1;
275 | }
276 |
277 | // Read in the data from the PBP
278 | if (fread(buffer, readsize, 1, infile) < 0) {
279 | printf("UNPACK_PBP ERROR: Could not read in the section data.\n");
280 | return -1;
281 | }
282 |
283 | // Write the contents of the buffer to the output file
284 | if (fwrite(buffer, readsize, 1, outfile) < 0) {
285 | printf("UNPACK_PBP ERROR: Could not write out the section data.\n");
286 | return -1;
287 | }
288 |
289 | // Clean up the buffer
290 | free(buffer);
291 |
292 | // Repeat if we haven't finished writing the file
293 | } while (size);
294 |
295 | // Close the output file
296 | if (fclose(outfile) < 0) {
297 | printf("UNPACK_PBP ERROR: Could not close the output file.\n");
298 | return -1;
299 | }
300 |
301 | }
302 |
303 | // Close the PBP
304 | if (fclose(infile) < 0) {
305 | printf("UNPACK_PBP ERROR: Could not close the input file.\n");
306 | return -1;
307 | }
308 |
309 | // Exit successful
310 | return 0;
311 | }
--------------------------------------------------------------------------------
/src/crypto.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 Hykem
2 | // Licensed under the terms of the GNU GPL, version 3
3 | // http://www.gnu.org/licenses/gpl-3.0.txt
4 |
5 | /*
6 | Copyright (c) 2005 adresd
7 | Copyright (c) 2005 Marcus R. Brown
8 | Copyright (c) 2005 James Forshaw
9 | Copyright (c) 2005 John Kelley
10 | Copyright (c) 2005 Jesper Svennevid
11 | All rights reserved.
12 |
13 | Redistribution and use in source and binary forms, with or without
14 | modification, are permitted provided that the following conditions
15 | are met:
16 | 1. Redistributions of source code must retain the above copyright
17 | notice, this list of conditions and the following disclaimer.
18 | 2. Redistributions in binary form must reproduce the above copyright
19 | notice, this list of conditions and the following disclaimer in the
20 | documentation and/or other materials provided with the distribution.
21 | 3. The names of the authors may not be used to endorse or promote products
22 | derived from this software without specific prior written permission.
23 |
24 | THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
25 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 | */
35 |
36 | // Unpack PBP comes from "PSPSDK - PSPDEV Open Source Project" (check above disclaimer).
37 | // Decrypt PGD is based on "pgdecrypt" by tpunix.
38 |
39 | #define _CRT_SECURE_NO_WARNINGS
40 |
41 | #include
42 | #include
43 | #include
44 |
45 | extern "C" {
46 | #include "libkirk/kirk_engine.h"
47 | #include "libkirk/amctrl.h"
48 | #include "libkirk/DES.h"
49 | }
50 |
51 | #include "utils.h"
52 |
53 | static unsigned char des_key[0x8] = {0x39, 0xF7, 0xEF, 0xA1, 0x6C, 0xCE, 0x5F, 0x4C};
54 | static unsigned char des_iv[0x8] = {0xA8, 0x19, 0xC4, 0xF5, 0xE1, 0x54, 0xE3, 0x0B};
55 |
56 | static unsigned char dnas_key1A90[] = {0xED, 0xE2, 0x5D, 0x2D, 0xBB, 0xF8, 0x12, 0xE5, 0x3C, 0x5C, 0x59, 0x32, 0xFA, 0xE3, 0xE2, 0x43};
57 | static unsigned char dnas_key1AA0[] = {0x27, 0x74, 0xFB, 0xEB, 0xA4, 0xA0, 0x01, 0xD7, 0x02, 0x56, 0x9E, 0x33, 0x8C, 0x19, 0x57, 0x83};
58 |
59 | static unsigned char pops_key[] = {0x2E, 0x41, 0x17, 0xA5, 0x32, 0xE6, 0xC4, 0x73, 0x71, 0x7B, 0x0F, 0x7A, 0x6E, 0xC0, 0xAA, 0xA5};
60 |
61 | // Structure to describe the header of a PGD file.
62 | typedef struct {
63 | unsigned char vkey[16];
64 |
65 | int open_flag;
66 | int key_index;
67 | int drm_type;
68 | int mac_type;
69 | int cipher_type;
70 |
71 | int data_size;
72 | int align_size;
73 | int block_size;
74 | int block_nr;
75 | int data_offset;
76 | int table_offset;
77 |
78 | unsigned char *buf;
79 | } PGD_HEADER;
80 |
81 | // Structure to describe the header of a PBP file.
82 | typedef struct {
83 | char signature[4];
84 | int version;
85 | int offset[8];
86 | } PBP_HEADER;
87 |
88 | // Correct PBP signature.
89 | static char pbp_sig[4] = {
90 | 0x00,
91 | 0x50, // P
92 | 0x42, // B
93 | 0x50 // P
94 | };
95 |
96 | // Names of files included in a PBP.
97 | static char *pbp_filenames[8] = {
98 | "PARAM.SFO",
99 | "ICON0.PNG",
100 | "ICON1.PMF",
101 | "PIC0.PNG",
102 | "PIC1.PNG",
103 | "SND0.AT3",
104 | "DATA.PSP",
105 | "DATA.PSAR"
106 | };
107 |
108 | int decrypt_pgd(unsigned char* pgd_data, int pgd_size, int flag, unsigned char* key);
109 | int decrypt_doc(unsigned char* data, int size);
110 | int unpack_pbp(FILE *infile);
--------------------------------------------------------------------------------
/src/libkirk/AES.h:
--------------------------------------------------------------------------------
1 | #ifndef __RIJNDAEL_H
2 | #define __RIJNDAEL_H
3 |
4 | #include "kirk_engine.h"
5 |
6 | #define AES_KEY_LEN_128 (128)
7 | #define AES_KEY_LEN_192 (192)
8 | #define AES_KEY_LEN_256 (256)
9 |
10 | #define AES_BUFFER_SIZE (16)
11 |
12 | #define AES_MAXKEYBITS (256)
13 | #define AES_MAXKEYBYTES (AES_MAXKEYBITS/8)
14 | /* for 256-bit keys, fewer for less */
15 | #define AES_MAXROUNDS 14
16 | #define pwuAESContextBuffer rijndael_ctx
17 |
18 | /* The structure for key information */
19 | typedef struct
20 | {
21 | int enc_only; /* context contains only encrypt schedule */
22 | int Nr; /* key-length-dependent number of rounds */
23 | u32 ek[4*(AES_MAXROUNDS + 1)]; /* encrypt key schedule */
24 | u32 dk[4*(AES_MAXROUNDS + 1)]; /* decrypt key schedule */
25 | } rijndael_ctx;
26 |
27 | typedef struct
28 | {
29 | int enc_only; /* context contains only encrypt schedule */
30 | int Nr; /* key-length-dependent number of rounds */
31 | u32 ek[4*(AES_MAXROUNDS + 1)]; /* encrypt key schedule */
32 | u32 dk[4*(AES_MAXROUNDS + 1)]; /* decrypt key schedule */
33 | } AES_ctx;
34 |
35 | int rijndael_set_key(rijndael_ctx *, const u8 *, int);
36 | int rijndael_set_key_enc_only(rijndael_ctx *, const u8 *, int);
37 | void rijndael_decrypt(rijndael_ctx *, const u8 *, u8 *);
38 | void rijndael_encrypt(rijndael_ctx *, const u8 *, u8 *);
39 |
40 | int AES_set_key(AES_ctx *ctx, const u8 *key, int bits);
41 | void AES_encrypt(AES_ctx *ctx, const u8 *src, u8 *dst);
42 | void AES_decrypt(AES_ctx *ctx, const u8 *src, u8 *dst);
43 | void AES_cbc_encrypt(AES_ctx *ctx, u8 *src, u8 *dst, int size);
44 | void AES_cbc_decrypt(AES_ctx *ctx, u8 *src, u8 *dst, int size);
45 | void AES_CMAC(AES_ctx *ctx, unsigned char *input, int length, unsigned char *mac);
46 |
47 | int rijndaelKeySetupEnc(unsigned int [], const unsigned char [], int);
48 | int rijndaelKeySetupDec(unsigned int [], const unsigned char [], int);
49 | void rijndaelEncrypt(const unsigned int [], int, const unsigned char [],
50 | unsigned char []);
51 |
52 | #endif /* __RIJNDAEL_H */
53 |
--------------------------------------------------------------------------------
/src/libkirk/DES.c:
--------------------------------------------------------------------------------
1 | /*
2 | * FIPS-46-3 compliant Triple-DES implementation
3 | *
4 | * Copyright (C) 2006-2013, Brainspark B.V.
5 | *
6 | * This file is part of PolarSSL (http://www.polarssl.org)
7 | * Lead Maintainer: Paul Bakker
8 | *
9 | * All rights reserved.
10 | *
11 | * This program is free software; you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation; either version 2 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * This program is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License along
22 | * with this program; if not, write to the Free Software Foundation, Inc.,
23 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 | */
25 | /*
26 | * DES, on which TDES is based, was originally designed by Horst Feistel
27 | * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS).
28 | *
29 | * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
30 | */
31 |
32 | #include "DES.h"
33 |
34 | #if !defined(POLARSSL_DES_ALT)
35 |
36 | /*
37 | * 32-bit integer manipulation macros (big endian)
38 | */
39 | #ifndef GET_UINT32_BE
40 | #define GET_UINT32_BE(n,b,i) \
41 | { \
42 | (n) = ( (uint32_t) (b)[(i) ] << 24 ) \
43 | | ( (uint32_t) (b)[(i) + 1] << 16 ) \
44 | | ( (uint32_t) (b)[(i) + 2] << 8 ) \
45 | | ( (uint32_t) (b)[(i) + 3] ); \
46 | }
47 | #endif
48 |
49 | #ifndef PUT_UINT32_BE
50 | #define PUT_UINT32_BE(n,b,i) \
51 | { \
52 | (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
53 | (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
54 | (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
55 | (b)[(i) + 3] = (unsigned char) ( (n) ); \
56 | }
57 | #endif
58 |
59 | /*
60 | * Expanded DES S-boxes
61 | */
62 | static const uint32_t SB1[64] =
63 | {
64 | 0x01010400, 0x00000000, 0x00010000, 0x01010404,
65 | 0x01010004, 0x00010404, 0x00000004, 0x00010000,
66 | 0x00000400, 0x01010400, 0x01010404, 0x00000400,
67 | 0x01000404, 0x01010004, 0x01000000, 0x00000004,
68 | 0x00000404, 0x01000400, 0x01000400, 0x00010400,
69 | 0x00010400, 0x01010000, 0x01010000, 0x01000404,
70 | 0x00010004, 0x01000004, 0x01000004, 0x00010004,
71 | 0x00000000, 0x00000404, 0x00010404, 0x01000000,
72 | 0x00010000, 0x01010404, 0x00000004, 0x01010000,
73 | 0x01010400, 0x01000000, 0x01000000, 0x00000400,
74 | 0x01010004, 0x00010000, 0x00010400, 0x01000004,
75 | 0x00000400, 0x00000004, 0x01000404, 0x00010404,
76 | 0x01010404, 0x00010004, 0x01010000, 0x01000404,
77 | 0x01000004, 0x00000404, 0x00010404, 0x01010400,
78 | 0x00000404, 0x01000400, 0x01000400, 0x00000000,
79 | 0x00010004, 0x00010400, 0x00000000, 0x01010004
80 | };
81 |
82 | static const uint32_t SB2[64] =
83 | {
84 | 0x80108020, 0x80008000, 0x00008000, 0x00108020,
85 | 0x00100000, 0x00000020, 0x80100020, 0x80008020,
86 | 0x80000020, 0x80108020, 0x80108000, 0x80000000,
87 | 0x80008000, 0x00100000, 0x00000020, 0x80100020,
88 | 0x00108000, 0x00100020, 0x80008020, 0x00000000,
89 | 0x80000000, 0x00008000, 0x00108020, 0x80100000,
90 | 0x00100020, 0x80000020, 0x00000000, 0x00108000,
91 | 0x00008020, 0x80108000, 0x80100000, 0x00008020,
92 | 0x00000000, 0x00108020, 0x80100020, 0x00100000,
93 | 0x80008020, 0x80100000, 0x80108000, 0x00008000,
94 | 0x80100000, 0x80008000, 0x00000020, 0x80108020,
95 | 0x00108020, 0x00000020, 0x00008000, 0x80000000,
96 | 0x00008020, 0x80108000, 0x00100000, 0x80000020,
97 | 0x00100020, 0x80008020, 0x80000020, 0x00100020,
98 | 0x00108000, 0x00000000, 0x80008000, 0x00008020,
99 | 0x80000000, 0x80100020, 0x80108020, 0x00108000
100 | };
101 |
102 | static const uint32_t SB3[64] =
103 | {
104 | 0x00000208, 0x08020200, 0x00000000, 0x08020008,
105 | 0x08000200, 0x00000000, 0x00020208, 0x08000200,
106 | 0x00020008, 0x08000008, 0x08000008, 0x00020000,
107 | 0x08020208, 0x00020008, 0x08020000, 0x00000208,
108 | 0x08000000, 0x00000008, 0x08020200, 0x00000200,
109 | 0x00020200, 0x08020000, 0x08020008, 0x00020208,
110 | 0x08000208, 0x00020200, 0x00020000, 0x08000208,
111 | 0x00000008, 0x08020208, 0x00000200, 0x08000000,
112 | 0x08020200, 0x08000000, 0x00020008, 0x00000208,
113 | 0x00020000, 0x08020200, 0x08000200, 0x00000000,
114 | 0x00000200, 0x00020008, 0x08020208, 0x08000200,
115 | 0x08000008, 0x00000200, 0x00000000, 0x08020008,
116 | 0x08000208, 0x00020000, 0x08000000, 0x08020208,
117 | 0x00000008, 0x00020208, 0x00020200, 0x08000008,
118 | 0x08020000, 0x08000208, 0x00000208, 0x08020000,
119 | 0x00020208, 0x00000008, 0x08020008, 0x00020200
120 | };
121 |
122 | static const uint32_t SB4[64] =
123 | {
124 | 0x00802001, 0x00002081, 0x00002081, 0x00000080,
125 | 0x00802080, 0x00800081, 0x00800001, 0x00002001,
126 | 0x00000000, 0x00802000, 0x00802000, 0x00802081,
127 | 0x00000081, 0x00000000, 0x00800080, 0x00800001,
128 | 0x00000001, 0x00002000, 0x00800000, 0x00802001,
129 | 0x00000080, 0x00800000, 0x00002001, 0x00002080,
130 | 0x00800081, 0x00000001, 0x00002080, 0x00800080,
131 | 0x00002000, 0x00802080, 0x00802081, 0x00000081,
132 | 0x00800080, 0x00800001, 0x00802000, 0x00802081,
133 | 0x00000081, 0x00000000, 0x00000000, 0x00802000,
134 | 0x00002080, 0x00800080, 0x00800081, 0x00000001,
135 | 0x00802001, 0x00002081, 0x00002081, 0x00000080,
136 | 0x00802081, 0x00000081, 0x00000001, 0x00002000,
137 | 0x00800001, 0x00002001, 0x00802080, 0x00800081,
138 | 0x00002001, 0x00002080, 0x00800000, 0x00802001,
139 | 0x00000080, 0x00800000, 0x00002000, 0x00802080
140 | };
141 |
142 | static const uint32_t SB5[64] =
143 | {
144 | 0x00000100, 0x02080100, 0x02080000, 0x42000100,
145 | 0x00080000, 0x00000100, 0x40000000, 0x02080000,
146 | 0x40080100, 0x00080000, 0x02000100, 0x40080100,
147 | 0x42000100, 0x42080000, 0x00080100, 0x40000000,
148 | 0x02000000, 0x40080000, 0x40080000, 0x00000000,
149 | 0x40000100, 0x42080100, 0x42080100, 0x02000100,
150 | 0x42080000, 0x40000100, 0x00000000, 0x42000000,
151 | 0x02080100, 0x02000000, 0x42000000, 0x00080100,
152 | 0x00080000, 0x42000100, 0x00000100, 0x02000000,
153 | 0x40000000, 0x02080000, 0x42000100, 0x40080100,
154 | 0x02000100, 0x40000000, 0x42080000, 0x02080100,
155 | 0x40080100, 0x00000100, 0x02000000, 0x42080000,
156 | 0x42080100, 0x00080100, 0x42000000, 0x42080100,
157 | 0x02080000, 0x00000000, 0x40080000, 0x42000000,
158 | 0x00080100, 0x02000100, 0x40000100, 0x00080000,
159 | 0x00000000, 0x40080000, 0x02080100, 0x40000100
160 | };
161 |
162 | static const uint32_t SB6[64] =
163 | {
164 | 0x20000010, 0x20400000, 0x00004000, 0x20404010,
165 | 0x20400000, 0x00000010, 0x20404010, 0x00400000,
166 | 0x20004000, 0x00404010, 0x00400000, 0x20000010,
167 | 0x00400010, 0x20004000, 0x20000000, 0x00004010,
168 | 0x00000000, 0x00400010, 0x20004010, 0x00004000,
169 | 0x00404000, 0x20004010, 0x00000010, 0x20400010,
170 | 0x20400010, 0x00000000, 0x00404010, 0x20404000,
171 | 0x00004010, 0x00404000, 0x20404000, 0x20000000,
172 | 0x20004000, 0x00000010, 0x20400010, 0x00404000,
173 | 0x20404010, 0x00400000, 0x00004010, 0x20000010,
174 | 0x00400000, 0x20004000, 0x20000000, 0x00004010,
175 | 0x20000010, 0x20404010, 0x00404000, 0x20400000,
176 | 0x00404010, 0x20404000, 0x00000000, 0x20400010,
177 | 0x00000010, 0x00004000, 0x20400000, 0x00404010,
178 | 0x00004000, 0x00400010, 0x20004010, 0x00000000,
179 | 0x20404000, 0x20000000, 0x00400010, 0x20004010
180 | };
181 |
182 | static const uint32_t SB7[64] =
183 | {
184 | 0x00200000, 0x04200002, 0x04000802, 0x00000000,
185 | 0x00000800, 0x04000802, 0x00200802, 0x04200800,
186 | 0x04200802, 0x00200000, 0x00000000, 0x04000002,
187 | 0x00000002, 0x04000000, 0x04200002, 0x00000802,
188 | 0x04000800, 0x00200802, 0x00200002, 0x04000800,
189 | 0x04000002, 0x04200000, 0x04200800, 0x00200002,
190 | 0x04200000, 0x00000800, 0x00000802, 0x04200802,
191 | 0x00200800, 0x00000002, 0x04000000, 0x00200800,
192 | 0x04000000, 0x00200800, 0x00200000, 0x04000802,
193 | 0x04000802, 0x04200002, 0x04200002, 0x00000002,
194 | 0x00200002, 0x04000000, 0x04000800, 0x00200000,
195 | 0x04200800, 0x00000802, 0x00200802, 0x04200800,
196 | 0x00000802, 0x04000002, 0x04200802, 0x04200000,
197 | 0x00200800, 0x00000000, 0x00000002, 0x04200802,
198 | 0x00000000, 0x00200802, 0x04200000, 0x00000800,
199 | 0x04000002, 0x04000800, 0x00000800, 0x00200002
200 | };
201 |
202 | static const uint32_t SB8[64] =
203 | {
204 | 0x10001040, 0x00001000, 0x00040000, 0x10041040,
205 | 0x10000000, 0x10001040, 0x00000040, 0x10000000,
206 | 0x00040040, 0x10040000, 0x10041040, 0x00041000,
207 | 0x10041000, 0x00041040, 0x00001000, 0x00000040,
208 | 0x10040000, 0x10000040, 0x10001000, 0x00001040,
209 | 0x00041000, 0x00040040, 0x10040040, 0x10041000,
210 | 0x00001040, 0x00000000, 0x00000000, 0x10040040,
211 | 0x10000040, 0x10001000, 0x00041040, 0x00040000,
212 | 0x00041040, 0x00040000, 0x10041000, 0x00001000,
213 | 0x00000040, 0x10040040, 0x00001000, 0x00041040,
214 | 0x10001000, 0x00000040, 0x10000040, 0x10040000,
215 | 0x10040040, 0x10000000, 0x00040000, 0x10001040,
216 | 0x00000000, 0x10041040, 0x00040040, 0x10000040,
217 | 0x10040000, 0x10001000, 0x10001040, 0x00000000,
218 | 0x10041040, 0x00041000, 0x00041000, 0x00001040,
219 | 0x00001040, 0x00040040, 0x10000000, 0x10041000
220 | };
221 |
222 | /*
223 | * PC1: left and right halves bit-swap
224 | */
225 | static const uint32_t LHs[16] =
226 | {
227 | 0x00000000, 0x00000001, 0x00000100, 0x00000101,
228 | 0x00010000, 0x00010001, 0x00010100, 0x00010101,
229 | 0x01000000, 0x01000001, 0x01000100, 0x01000101,
230 | 0x01010000, 0x01010001, 0x01010100, 0x01010101
231 | };
232 |
233 | static const uint32_t RHs[16] =
234 | {
235 | 0x00000000, 0x01000000, 0x00010000, 0x01010000,
236 | 0x00000100, 0x01000100, 0x00010100, 0x01010100,
237 | 0x00000001, 0x01000001, 0x00010001, 0x01010001,
238 | 0x00000101, 0x01000101, 0x00010101, 0x01010101,
239 | };
240 |
241 | /*
242 | * Initial Permutation macro
243 | */
244 | #define DES_IP(X,Y) \
245 | { \
246 | T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
247 | T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
248 | T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
249 | T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
250 | Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \
251 | T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \
252 | X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \
253 | }
254 |
255 | /*
256 | * Final Permutation macro
257 | */
258 | #define DES_FP(X,Y) \
259 | { \
260 | X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \
261 | T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \
262 | Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \
263 | T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \
264 | T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \
265 | T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \
266 | T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \
267 | }
268 |
269 | /*
270 | * DES round macro
271 | */
272 | #define DES_ROUND(X,Y) \
273 | { \
274 | T = *SK++ ^ X; \
275 | Y ^= SB8[ (T ) & 0x3F ] ^ \
276 | SB6[ (T >> 8) & 0x3F ] ^ \
277 | SB4[ (T >> 16) & 0x3F ] ^ \
278 | SB2[ (T >> 24) & 0x3F ]; \
279 | \
280 | T = *SK++ ^ ((X << 28) | (X >> 4)); \
281 | Y ^= SB7[ (T ) & 0x3F ] ^ \
282 | SB5[ (T >> 8) & 0x3F ] ^ \
283 | SB3[ (T >> 16) & 0x3F ] ^ \
284 | SB1[ (T >> 24) & 0x3F ]; \
285 | }
286 |
287 | #define SWAP(a,b) { uint32_t t = a; a = b; b = t; t = 0; }
288 |
289 | static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8,
290 | 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44,
291 | 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81,
292 | 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112,
293 | 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140,
294 | 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168,
295 | 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196,
296 | 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224,
297 | 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253,
298 | 254 };
299 |
300 | void des_key_set_parity( unsigned char key[DES_KEY_SIZE] )
301 | {
302 | int i;
303 |
304 | for( i = 0; i < DES_KEY_SIZE; i++ )
305 | key[i] = odd_parity_table[key[i] / 2];
306 | }
307 |
308 | /*
309 | * Check the given key's parity, returns 1 on failure, 0 on SUCCESS
310 | */
311 | int des_key_check_key_parity( const unsigned char key[DES_KEY_SIZE] )
312 | {
313 | int i;
314 |
315 | for( i = 0; i < DES_KEY_SIZE; i++ )
316 | if ( key[i] != odd_parity_table[key[i] / 2] )
317 | return( 1 );
318 |
319 | return( 0 );
320 | }
321 |
322 | /*
323 | * Table of weak and semi-weak keys
324 | *
325 | * Source: http://en.wikipedia.org/wiki/Weak_key
326 | *
327 | * Weak:
328 | * Alternating ones + zeros (0x0101010101010101)
329 | * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE)
330 | * '0xE0E0E0E0F1F1F1F1'
331 | * '0x1F1F1F1F0E0E0E0E'
332 | *
333 | * Semi-weak:
334 | * 0x011F011F010E010E and 0x1F011F010E010E01
335 | * 0x01E001E001F101F1 and 0xE001E001F101F101
336 | * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01
337 | * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E
338 | * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E
339 | * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1
340 | *
341 | */
342 |
343 | #define WEAK_KEY_COUNT 16
344 |
345 | static const unsigned char weak_key_table[WEAK_KEY_COUNT][DES_KEY_SIZE] =
346 | {
347 | { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
348 | { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE },
349 | { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E },
350 | { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 },
351 |
352 | { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E },
353 | { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 },
354 | { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 },
355 | { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 },
356 | { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE },
357 | { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 },
358 | { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 },
359 | { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E },
360 | { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE },
361 | { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E },
362 | { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE },
363 | { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 }
364 | };
365 |
366 | int des_key_check_weak( const unsigned char key[DES_KEY_SIZE] )
367 | {
368 | int i;
369 |
370 | for( i = 0; i < WEAK_KEY_COUNT; i++ )
371 | if( memcmp( weak_key_table[i], key, DES_KEY_SIZE) == 0)
372 | return( 1 );
373 |
374 | return( 0 );
375 | }
376 |
377 | static void des_setkey( uint32_t SK[32], const unsigned char key[DES_KEY_SIZE] )
378 | {
379 | int i;
380 | uint32_t X, Y, T;
381 |
382 | GET_UINT32_BE( X, key, 0 );
383 | GET_UINT32_BE( Y, key, 4 );
384 |
385 | /*
386 | * Permuted Choice 1
387 | */
388 | T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4);
389 | T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T );
390 |
391 | X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2)
392 | | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] )
393 | | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6)
394 | | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4);
395 |
396 | Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2)
397 | | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] )
398 | | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6)
399 | | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4);
400 |
401 | X &= 0x0FFFFFFF;
402 | Y &= 0x0FFFFFFF;
403 |
404 | /*
405 | * calculate subkeys
406 | */
407 | for( i = 0; i < 16; i++ )
408 | {
409 | if( i < 2 || i == 8 || i == 15 )
410 | {
411 | X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF;
412 | Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF;
413 | }
414 | else
415 | {
416 | X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF;
417 | Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF;
418 | }
419 |
420 | *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000)
421 | | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000)
422 | | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000)
423 | | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000)
424 | | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000)
425 | | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000)
426 | | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400)
427 | | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100)
428 | | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010)
429 | | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004)
430 | | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001);
431 |
432 | *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000)
433 | | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000)
434 | | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000)
435 | | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000)
436 | | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000)
437 | | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000)
438 | | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000)
439 | | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400)
440 | | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100)
441 | | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011)
442 | | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002);
443 | }
444 | }
445 |
446 | /*
447 | * DES key schedule (56-bit, encryption)
448 | */
449 | int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] )
450 | {
451 | des_setkey( ctx->sk, key );
452 |
453 | return( 0 );
454 | }
455 |
456 | /*
457 | * DES key schedule (56-bit, decryption)
458 | */
459 | int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] )
460 | {
461 | int i;
462 |
463 | des_setkey( ctx->sk, key );
464 |
465 | for( i = 0; i < 16; i += 2 )
466 | {
467 | SWAP( ctx->sk[i ], ctx->sk[30 - i] );
468 | SWAP( ctx->sk[i + 1], ctx->sk[31 - i] );
469 | }
470 |
471 | return( 0 );
472 | }
473 |
474 | static void des3_set2key( uint32_t esk[96],
475 | uint32_t dsk[96],
476 | const unsigned char key[DES_KEY_SIZE*2] )
477 | {
478 | int i;
479 |
480 | des_setkey( esk, key );
481 | des_setkey( dsk + 32, key + 8 );
482 |
483 | for( i = 0; i < 32; i += 2 )
484 | {
485 | dsk[i ] = esk[30 - i];
486 | dsk[i + 1] = esk[31 - i];
487 |
488 | esk[i + 32] = dsk[62 - i];
489 | esk[i + 33] = dsk[63 - i];
490 |
491 | esk[i + 64] = esk[i ];
492 | esk[i + 65] = esk[i + 1];
493 |
494 | dsk[i + 64] = dsk[i ];
495 | dsk[i + 65] = dsk[i + 1];
496 | }
497 | }
498 |
499 | /*
500 | * Triple-DES key schedule (112-bit, encryption)
501 | */
502 | int des3_set2key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] )
503 | {
504 | uint32_t sk[96];
505 |
506 | des3_set2key( ctx->sk, sk, key );
507 | memset( sk, 0, sizeof( sk ) );
508 |
509 | return( 0 );
510 | }
511 |
512 | /*
513 | * Triple-DES key schedule (112-bit, decryption)
514 | */
515 | int des3_set2key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] )
516 | {
517 | uint32_t sk[96];
518 |
519 | des3_set2key( sk, ctx->sk, key );
520 | memset( sk, 0, sizeof( sk ) );
521 |
522 | return( 0 );
523 | }
524 |
525 | static void des3_set3key( uint32_t esk[96],
526 | uint32_t dsk[96],
527 | const unsigned char key[24] )
528 | {
529 | int i;
530 |
531 | des_setkey( esk, key );
532 | des_setkey( dsk + 32, key + 8 );
533 | des_setkey( esk + 64, key + 16 );
534 |
535 | for( i = 0; i < 32; i += 2 )
536 | {
537 | dsk[i ] = esk[94 - i];
538 | dsk[i + 1] = esk[95 - i];
539 |
540 | esk[i + 32] = dsk[62 - i];
541 | esk[i + 33] = dsk[63 - i];
542 |
543 | dsk[i + 64] = esk[30 - i];
544 | dsk[i + 65] = esk[31 - i];
545 | }
546 | }
547 |
548 | /*
549 | * Triple-DES key schedule (168-bit, encryption)
550 | */
551 | int des3_set3key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] )
552 | {
553 | uint32_t sk[96];
554 |
555 | des3_set3key( ctx->sk, sk, key );
556 | memset( sk, 0, sizeof( sk ) );
557 |
558 | return( 0 );
559 | }
560 |
561 | /*
562 | * Triple-DES key schedule (168-bit, decryption)
563 | */
564 | int des3_set3key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] )
565 | {
566 | uint32_t sk[96];
567 |
568 | des3_set3key( sk, ctx->sk, key );
569 | memset( sk, 0, sizeof( sk ) );
570 |
571 | return( 0 );
572 | }
573 |
574 | /*
575 | * DES-ECB block encryption/decryption
576 | */
577 | int des_crypt_ecb( des_context *ctx,
578 | const unsigned char input[8],
579 | unsigned char output[8] )
580 | {
581 | int i;
582 | uint32_t X, Y, T, *SK;
583 |
584 | SK = ctx->sk;
585 |
586 | GET_UINT32_BE( X, input, 0 );
587 | GET_UINT32_BE( Y, input, 4 );
588 |
589 | DES_IP( X, Y );
590 |
591 | for( i = 0; i < 8; i++ )
592 | {
593 | DES_ROUND( Y, X );
594 | DES_ROUND( X, Y );
595 | }
596 |
597 | DES_FP( Y, X );
598 |
599 | PUT_UINT32_BE( Y, output, 0 );
600 | PUT_UINT32_BE( X, output, 4 );
601 |
602 | return( 0 );
603 | }
604 |
605 | /*
606 | * DES-CBC buffer encryption/decryption
607 | */
608 | int des_crypt_cbc( des_context *ctx,
609 | int mode,
610 | size_t length,
611 | unsigned char iv[8],
612 | const unsigned char *input,
613 | unsigned char *output )
614 | {
615 | int i;
616 | unsigned char temp[8];
617 |
618 | if( length % 8 )
619 | return( POLARSSL_ERR_DES_INVALID_INPUT_LENGTH );
620 |
621 | if( mode == DES_ENCRYPT )
622 | {
623 | while( length > 0 )
624 | {
625 | for( i = 0; i < 8; i++ )
626 | output[i] = (unsigned char)( input[i] ^ iv[i] );
627 |
628 | des_crypt_ecb( ctx, output, output );
629 | memcpy( iv, output, 8 );
630 |
631 | input += 8;
632 | output += 8;
633 | length -= 8;
634 | }
635 | }
636 | else /* DES_DECRYPT */
637 | {
638 | while( length > 0 )
639 | {
640 | memcpy( temp, input, 8 );
641 | des_crypt_ecb( ctx, input, output );
642 |
643 | for( i = 0; i < 8; i++ )
644 | output[i] = (unsigned char)( output[i] ^ iv[i] );
645 |
646 | memcpy( iv, temp, 8 );
647 |
648 | input += 8;
649 | output += 8;
650 | length -= 8;
651 | }
652 | }
653 |
654 | return( 0 );
655 | }
656 | #endif /* POLARSSL_CIPHER_MODE_CBC */
657 |
658 | /*
659 | * 3DES-ECB block encryption/decryption
660 | */
661 | int des3_crypt_ecb( des3_context *ctx,
662 | const unsigned char input[8],
663 | unsigned char output[8] )
664 | {
665 | int i;
666 | uint32_t X, Y, T, *SK;
667 |
668 | SK = ctx->sk;
669 |
670 | GET_UINT32_BE( X, input, 0 );
671 | GET_UINT32_BE( Y, input, 4 );
672 |
673 | DES_IP( X, Y );
674 |
675 | for( i = 0; i < 8; i++ )
676 | {
677 | DES_ROUND( Y, X );
678 | DES_ROUND( X, Y );
679 | }
680 |
681 | for( i = 0; i < 8; i++ )
682 | {
683 | DES_ROUND( X, Y );
684 | DES_ROUND( Y, X );
685 | }
686 |
687 | for( i = 0; i < 8; i++ )
688 | {
689 | DES_ROUND( Y, X );
690 | DES_ROUND( X, Y );
691 | }
692 |
693 | DES_FP( Y, X );
694 |
695 | PUT_UINT32_BE( Y, output, 0 );
696 | PUT_UINT32_BE( X, output, 4 );
697 |
698 | return( 0 );
699 | }
700 |
701 | /*
702 | * 3DES-CBC buffer encryption/decryption
703 | */
704 | int des3_crypt_cbc( des3_context *ctx,
705 | int mode,
706 | size_t length,
707 | unsigned char iv[8],
708 | const unsigned char *input,
709 | unsigned char *output )
710 | {
711 | int i;
712 | unsigned char temp[8];
713 |
714 | if( length % 8 )
715 | return( POLARSSL_ERR_DES_INVALID_INPUT_LENGTH );
716 |
717 | if( mode == DES_ENCRYPT )
718 | {
719 | while( length > 0 )
720 | {
721 | for( i = 0; i < 8; i++ )
722 | output[i] = (unsigned char)( input[i] ^ iv[i] );
723 |
724 | des3_crypt_ecb( ctx, output, output );
725 | memcpy( iv, output, 8 );
726 |
727 | input += 8;
728 | output += 8;
729 | length -= 8;
730 | }
731 | }
732 | else /* DES_DECRYPT */
733 | {
734 | while( length > 0 )
735 | {
736 | memcpy( temp, input, 8 );
737 | des3_crypt_ecb( ctx, input, output );
738 |
739 | for( i = 0; i < 8; i++ )
740 | output[i] = (unsigned char)( output[i] ^ iv[i] );
741 |
742 | memcpy( iv, temp, 8 );
743 |
744 | input += 8;
745 | output += 8;
746 | length -= 8;
747 | }
748 | }
749 |
750 | return( 0 );
751 | }
752 |
753 | #if defined(POLARSSL_SELF_TEST)
754 |
755 | #include
756 |
757 | /*
758 | * DES and 3DES test vectors from:
759 | *
760 | * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip
761 | */
762 | static const unsigned char des3_test_keys[24] =
763 | {
764 | 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
765 | 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
766 | 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23
767 | };
768 |
769 | static const unsigned char des3_test_iv[8] =
770 | {
771 | 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
772 | };
773 |
774 | static const unsigned char des3_test_buf[8] =
775 | {
776 | 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74
777 | };
778 |
779 | static const unsigned char des3_test_ecb_dec[3][8] =
780 | {
781 | { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D },
782 | { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB },
783 | { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A }
784 | };
785 |
786 | static const unsigned char des3_test_ecb_enc[3][8] =
787 | {
788 | { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B },
789 | { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 },
790 | { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 }
791 | };
792 |
793 | static const unsigned char des3_test_cbc_dec[3][8] =
794 | {
795 | { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 },
796 | { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 },
797 | { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C }
798 | };
799 |
800 | static const unsigned char des3_test_cbc_enc[3][8] =
801 | {
802 | { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 },
803 | { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D },
804 | { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 }
805 | };
806 |
807 | /*
808 | * Checkup routine
809 | */
810 | int des_self_test( int verbose )
811 | {
812 | int i, j, u, v;
813 | des_context ctx;
814 | des3_context ctx3;
815 | unsigned char key[24];
816 | unsigned char buf[8];
817 | #if defined(POLARSSL_CIPHER_MODE_CBC)
818 | unsigned char prv[8];
819 | unsigned char iv[8];
820 | #endif
821 |
822 | memset( key, 0, 24 );
823 |
824 | /*
825 | * ECB mode
826 | */
827 | for( i = 0; i < 6; i++ )
828 | {
829 | u = i >> 1;
830 | v = i & 1;
831 |
832 | if( verbose != 0 )
833 | printf( " DES%c-ECB-%3d (%s): ",
834 | ( u == 0 ) ? ' ' : '3', 56 + u * 56,
835 | ( v == DES_DECRYPT ) ? "dec" : "enc" );
836 |
837 | memcpy( buf, des3_test_buf, 8 );
838 |
839 | switch( i )
840 | {
841 | case 0:
842 | des_setkey_dec( &ctx, des3_test_keys );
843 | break;
844 |
845 | case 1:
846 | des_setkey_enc( &ctx, des3_test_keys );
847 | break;
848 |
849 | case 2:
850 | des3_set2key_dec( &ctx3, des3_test_keys );
851 | break;
852 |
853 | case 3:
854 | des3_set2key_enc( &ctx3, des3_test_keys );
855 | break;
856 |
857 | case 4:
858 | des3_set3key_dec( &ctx3, des3_test_keys );
859 | break;
860 |
861 | case 5:
862 | des3_set3key_enc( &ctx3, des3_test_keys );
863 | break;
864 |
865 | default:
866 | return( 1 );
867 | }
868 |
869 | for( j = 0; j < 10000; j++ )
870 | {
871 | if( u == 0 )
872 | des_crypt_ecb( &ctx, buf, buf );
873 | else
874 | des3_crypt_ecb( &ctx3, buf, buf );
875 | }
876 |
877 | if( ( v == DES_DECRYPT &&
878 | memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) ||
879 | ( v != DES_DECRYPT &&
880 | memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) )
881 | {
882 | if( verbose != 0 )
883 | printf( "failed\n" );
884 |
885 | return( 1 );
886 | }
887 |
888 | if( verbose != 0 )
889 | printf( "passed\n" );
890 | }
891 |
892 | if( verbose != 0 )
893 | printf( "\n" );
894 |
895 | #if defined(POLARSSL_CIPHER_MODE_CBC)
896 | /*
897 | * CBC mode
898 | */
899 | for( i = 0; i < 6; i++ )
900 | {
901 | u = i >> 1;
902 | v = i & 1;
903 |
904 | if( verbose != 0 )
905 | printf( " DES%c-CBC-%3d (%s): ",
906 | ( u == 0 ) ? ' ' : '3', 56 + u * 56,
907 | ( v == DES_DECRYPT ) ? "dec" : "enc" );
908 |
909 | memcpy( iv, des3_test_iv, 8 );
910 | memcpy( prv, des3_test_iv, 8 );
911 | memcpy( buf, des3_test_buf, 8 );
912 |
913 | switch( i )
914 | {
915 | case 0:
916 | des_setkey_dec( &ctx, des3_test_keys );
917 | break;
918 |
919 | case 1:
920 | des_setkey_enc( &ctx, des3_test_keys );
921 | break;
922 |
923 | case 2:
924 | des3_set2key_dec( &ctx3, des3_test_keys );
925 | break;
926 |
927 | case 3:
928 | des3_set2key_enc( &ctx3, des3_test_keys );
929 | break;
930 |
931 | case 4:
932 | des3_set3key_dec( &ctx3, des3_test_keys );
933 | break;
934 |
935 | case 5:
936 | des3_set3key_enc( &ctx3, des3_test_keys );
937 | break;
938 |
939 | default:
940 | return( 1 );
941 | }
942 |
943 | if( v == DES_DECRYPT )
944 | {
945 | for( j = 0; j < 10000; j++ )
946 | {
947 | if( u == 0 )
948 | des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
949 | else
950 | des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
951 | }
952 | }
953 | else
954 | {
955 | for( j = 0; j < 10000; j++ )
956 | {
957 | unsigned char tmp[8];
958 |
959 | if( u == 0 )
960 | des_crypt_cbc( &ctx, v, 8, iv, buf, buf );
961 | else
962 | des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf );
963 |
964 | memcpy( tmp, prv, 8 );
965 | memcpy( prv, buf, 8 );
966 | memcpy( buf, tmp, 8 );
967 | }
968 |
969 | memcpy( buf, prv, 8 );
970 | }
971 |
972 | if( ( v == DES_DECRYPT &&
973 | memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) ||
974 | ( v != DES_DECRYPT &&
975 | memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) )
976 | {
977 | if( verbose != 0 )
978 | printf( "failed\n" );
979 |
980 | return( 1 );
981 | }
982 |
983 | if( verbose != 0 )
984 | printf( "passed\n" );
985 | }
986 | #endif /* POLARSSL_CIPHER_MODE_CBC */
987 |
988 | if( verbose != 0 )
989 | printf( "\n" );
990 |
991 | return( 0 );
992 | }
993 |
994 | #endif
--------------------------------------------------------------------------------
/src/libkirk/DES.h:
--------------------------------------------------------------------------------
1 | /**
2 | * \file des.h
3 | *
4 | * \brief DES block cipher
5 | *
6 | * Copyright (C) 2006-2013, Brainspark B.V.
7 | *
8 | * This file is part of PolarSSL (http://www.polarssl.org)
9 | * Lead Maintainer: Paul Bakker
10 | *
11 | * All rights reserved.
12 | *
13 | * This program is free software; you can redistribute it and/or modify
14 | * it under the terms of the GNU General Public License as published by
15 | * the Free Software Foundation; either version 2 of the License, or
16 | * (at your option) any later version.
17 | *
18 | * This program is distributed in the hope that it will be useful,
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 | * GNU General Public License for more details.
22 | *
23 | * You should have received a copy of the GNU General Public License along
24 | * with this program; if not, write to the Free Software Foundation, Inc.,
25 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 | */
27 | #ifndef POLARSSL_DES_H
28 | #define POLARSSL_DES_H
29 |
30 | #include
31 |
32 | #if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
33 | #include
34 | typedef UINT32 uint32_t;
35 | #else
36 | #include
37 | #endif
38 |
39 | #define DES_ENCRYPT 1
40 | #define DES_DECRYPT 0
41 |
42 | #define POLARSSL_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */
43 |
44 | #define DES_KEY_SIZE 8
45 |
46 | #if !defined(POLARSSL_DES_ALT)
47 | // Regular implementation
48 | //
49 |
50 | #ifdef __cplusplus
51 | extern "C" {
52 | #endif
53 |
54 | /**
55 | * \brief DES context structure
56 | */
57 | typedef struct
58 | {
59 | int mode; /*!< encrypt/decrypt */
60 | uint32_t sk[32]; /*!< DES subkeys */
61 | }
62 | des_context;
63 |
64 | /**
65 | * \brief Triple-DES context structure
66 | */
67 | typedef struct
68 | {
69 | int mode; /*!< encrypt/decrypt */
70 | uint32_t sk[96]; /*!< 3DES subkeys */
71 | }
72 | des3_context;
73 |
74 | /**
75 | * \brief Set key parity on the given key to odd.
76 | *
77 | * DES keys are 56 bits long, but each byte is padded with
78 | * a parity bit to allow verification.
79 | *
80 | * \param key 8-byte secret key
81 | */
82 | void des_key_set_parity( unsigned char key[DES_KEY_SIZE] );
83 |
84 | /**
85 | * \brief Check that key parity on the given key is odd.
86 | *
87 | * DES keys are 56 bits long, but each byte is padded with
88 | * a parity bit to allow verification.
89 | *
90 | * \param key 8-byte secret key
91 | *
92 | * \return 0 is parity was ok, 1 if parity was not correct.
93 | */
94 | int des_key_check_key_parity( const unsigned char key[DES_KEY_SIZE] );
95 |
96 | /**
97 | * \brief Check that key is not a weak or semi-weak DES key
98 | *
99 | * \param key 8-byte secret key
100 | *
101 | * \return 0 if no weak key was found, 1 if a weak key was identified.
102 | */
103 | int des_key_check_weak( const unsigned char key[DES_KEY_SIZE] );
104 |
105 | /**
106 | * \brief DES key schedule (56-bit, encryption)
107 | *
108 | * \param ctx DES context to be initialized
109 | * \param key 8-byte secret key
110 | *
111 | * \return 0
112 | */
113 | int des_setkey_enc( des_context *ctx, const unsigned char key[DES_KEY_SIZE] );
114 |
115 | /**
116 | * \brief DES key schedule (56-bit, decryption)
117 | *
118 | * \param ctx DES context to be initialized
119 | * \param key 8-byte secret key
120 | *
121 | * \return 0
122 | */
123 | int des_setkey_dec( des_context *ctx, const unsigned char key[DES_KEY_SIZE] );
124 |
125 | /**
126 | * \brief Triple-DES key schedule (112-bit, encryption)
127 | *
128 | * \param ctx 3DES context to be initialized
129 | * \param key 16-byte secret key
130 | *
131 | * \return 0
132 | */
133 | int des3_set2key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] );
134 |
135 | /**
136 | * \brief Triple-DES key schedule (112-bit, decryption)
137 | *
138 | * \param ctx 3DES context to be initialized
139 | * \param key 16-byte secret key
140 | *
141 | * \return 0
142 | */
143 | int des3_set2key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 2] );
144 |
145 | /**
146 | * \brief Triple-DES key schedule (168-bit, encryption)
147 | *
148 | * \param ctx 3DES context to be initialized
149 | * \param key 24-byte secret key
150 | *
151 | * \return 0
152 | */
153 | int des3_set3key_enc( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] );
154 |
155 | /**
156 | * \brief Triple-DES key schedule (168-bit, decryption)
157 | *
158 | * \param ctx 3DES context to be initialized
159 | * \param key 24-byte secret key
160 | *
161 | * \return 0
162 | */
163 | int des3_set3key_dec( des3_context *ctx, const unsigned char key[DES_KEY_SIZE * 3] );
164 |
165 | /**
166 | * \brief DES-ECB block encryption/decryption
167 | *
168 | * \param ctx DES context
169 | * \param input 64-bit input block
170 | * \param output 64-bit output block
171 | *
172 | * \return 0 if successful
173 | */
174 | int des_crypt_ecb( des_context *ctx,
175 | const unsigned char input[8],
176 | unsigned char output[8] );
177 |
178 | /**
179 | * \brief DES-CBC buffer encryption/decryption
180 | *
181 | * \param ctx DES context
182 | * \param mode DES_ENCRYPT or DES_DECRYPT
183 | * \param length length of the input data
184 | * \param iv initialization vector (updated after use)
185 | * \param input buffer holding the input data
186 | * \param output buffer holding the output data
187 | */
188 | int des_crypt_cbc( des_context *ctx,
189 | int mode,
190 | size_t length,
191 | unsigned char iv[8],
192 | const unsigned char *input,
193 | unsigned char *output );
194 |
195 | /**
196 | * \brief 3DES-ECB block encryption/decryption
197 | *
198 | * \param ctx 3DES context
199 | * \param input 64-bit input block
200 | * \param output 64-bit output block
201 | *
202 | * \return 0 if successful
203 | */
204 | int des3_crypt_ecb( des3_context *ctx,
205 | const unsigned char input[8],
206 | unsigned char output[8] );
207 |
208 | /**
209 | * \brief 3DES-CBC buffer encryption/decryption
210 | *
211 | * \param ctx 3DES context
212 | * \param mode DES_ENCRYPT or DES_DECRYPT
213 | * \param length length of the input data
214 | * \param iv initialization vector (updated after use)
215 | * \param input buffer holding the input data
216 | * \param output buffer holding the output data
217 | *
218 | * \return 0 if successful, or POLARSSL_ERR_DES_INVALID_INPUT_LENGTH
219 | */
220 | int des3_crypt_cbc( des3_context *ctx,
221 | int mode,
222 | size_t length,
223 | unsigned char iv[8],
224 | const unsigned char *input,
225 | unsigned char *output );
226 |
227 | #ifdef __cplusplus
228 | }
229 | #endif
230 |
231 | #else /* POLARSSL_DES_ALT */
232 | #include "des_alt.h"
233 | #endif /* POLARSSL_DES_ALT */
234 |
235 | #ifdef __cplusplus
236 | extern "C" {
237 | #endif
238 |
239 | /**
240 | * \brief Checkup routine
241 | *
242 | * \return 0 if successful, or 1 if the test failed
243 | */
244 | int des_self_test( int verbose );
245 |
246 | #ifdef __cplusplus
247 | }
248 | #endif
249 |
250 | #endif /* des.h */
--------------------------------------------------------------------------------
/src/libkirk/SHA1.c:
--------------------------------------------------------------------------------
1 | /* sha1.c : Implementation of the Secure Hash Algorithm */
2 |
3 | /* SHA: NIST's Secure Hash Algorithm */
4 |
5 | /* This version written November 2000 by David Ireland of
6 | DI Management Services Pty Limited
7 |
8 | Adapted from code in the Python Cryptography Toolkit,
9 | version 1.0.0 by A.M. Kuchling 1995.
10 | */
11 |
12 | /* AM Kuchling's posting:-
13 | Based on SHA code originally posted to sci.crypt by Peter Gutmann
14 | in message <30ajo5$oe8@ccu2.auckland.ac.nz>.
15 | Modified to test for endianness on creation of SHA objects by AMK.
16 | Also, the original specification of SHA was found to have a weakness
17 | by NSA/NIST. This code implements the fixed version of SHA.
18 | */
19 |
20 | /* Here's the first paragraph of Peter Gutmann's posting:
21 |
22 | The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
23 | SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
24 | what's changed in the new version. The fix is a simple change which involves
25 | adding a single rotate in the initial expansion function. It is unknown
26 | whether this is an optimal solution to the problem which was discovered in the
27 | SHA or whether it's simply a bandaid which fixes the problem with a minimum of
28 | effort (for example the reengineering of a great many Capstone chips).
29 | */
30 |
31 | /* h files included here to make this just one file ... */
32 |
33 | /* global.h */
34 |
35 |
36 |
37 | /* sha.c */
38 | #include "SHA1.h"
39 |
40 | #include
41 | #include
42 |
43 | static void SHAtoByte(BYTE *output, UINT4 *input, unsigned int len);
44 |
45 | /* The SHS block size and message digest sizes, in bytes */
46 |
47 | #define SHS_DATASIZE 64
48 | #define SHS_DIGESTSIZE 20
49 |
50 |
51 | /* The SHS f()-functions. The f1 and f3 functions can be optimized to
52 | save one boolean operation each - thanks to Rich Schroeppel,
53 | rcs@cs.arizona.edu for discovering this */
54 |
55 | /*#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) // Rounds 0-19 */
56 | #define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */
57 | #define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
58 | /*#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) // Rounds 40-59 */
59 | #define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */
60 | #define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
61 |
62 | /* The SHS Mysterious Constants */
63 |
64 | #define K1 0x5A827999L /* Rounds 0-19 */
65 | #define K2 0x6ED9EBA1L /* Rounds 20-39 */
66 | #define K3 0x8F1BBCDCL /* Rounds 40-59 */
67 | #define K4 0xCA62C1D6L /* Rounds 60-79 */
68 |
69 | /* SHS initial values */
70 |
71 | #define h0init 0x67452301L
72 | #define h1init 0xEFCDAB89L
73 | #define h2init 0x98BADCFEL
74 | #define h3init 0x10325476L
75 | #define h4init 0xC3D2E1F0L
76 |
77 | /* Note that it may be necessary to add parentheses to these macros if they
78 | are to be called with expressions as arguments */
79 | /* 32-bit rotate left - kludged with shifts */
80 |
81 | #define ROTL(n,X) ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
82 |
83 | /* The initial expanding function. The hash function is defined over an
84 | 80-UINT2 expanded input array W, where the first 16 are copies of the input
85 | data, and the remaining 64 are defined by
86 |
87 | W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
88 |
89 | This implementation generates these values on the fly in a circular
90 | buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
91 | optimization.
92 |
93 | The updated SHS changes the expanding function by adding a rotate of 1
94 | bit. Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
95 | for this information */
96 |
97 | #define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
98 | W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
99 |
100 |
101 | /* The prototype SHS sub-round. The fundamental sub-round is:
102 |
103 | a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
104 | b' = a;
105 | c' = ROTL( 30, b );
106 | d' = c;
107 | e' = d;
108 |
109 | but this is implemented by unrolling the loop 5 times and renaming the
110 | variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
111 | This code is then replicated 20 times for each of the 4 functions, using
112 | the next 20 values from the W[] array each time */
113 |
114 | #define subRound(a, b, c, d, e, f, k, data) \
115 | ( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
116 |
117 | /* Initialize the SHS values */
118 |
119 | void SHAInit(SHA_CTX *shsInfo)
120 | {
121 | endianTest(&shsInfo->Endianness);
122 | /* Set the h-vars to their initial values */
123 | shsInfo->digest[ 0 ] = h0init;
124 | shsInfo->digest[ 1 ] = h1init;
125 | shsInfo->digest[ 2 ] = h2init;
126 | shsInfo->digest[ 3 ] = h3init;
127 | shsInfo->digest[ 4 ] = h4init;
128 |
129 | /* Initialise bit count */
130 | shsInfo->countLo = shsInfo->countHi = 0;
131 | }
132 |
133 |
134 | /* Perform the SHS transformation. Note that this code, like MD5, seems to
135 | break some optimizing compilers due to the complexity of the expressions
136 | and the size of the basic block. It may be necessary to split it into
137 | sections, e.g. based on the four subrounds
138 |
139 | Note that this corrupts the shsInfo->data area */
140 |
141 | static void SHSTransform( digest, data )
142 | UINT4 *digest, *data ;
143 | {
144 | UINT4 A, B, C, D, E; /* Local vars */
145 | UINT4 eData[ 16 ]; /* Expanded data */
146 |
147 | /* Set up first buffer and local data buffer */
148 | A = digest[ 0 ];
149 | B = digest[ 1 ];
150 | C = digest[ 2 ];
151 | D = digest[ 3 ];
152 | E = digest[ 4 ];
153 | memcpy( (POINTER)eData, (POINTER)data, SHS_DATASIZE );
154 |
155 | /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
156 | subRound( A, B, C, D, E, f1, K1, eData[ 0 ] );
157 | subRound( E, A, B, C, D, f1, K1, eData[ 1 ] );
158 | subRound( D, E, A, B, C, f1, K1, eData[ 2 ] );
159 | subRound( C, D, E, A, B, f1, K1, eData[ 3 ] );
160 | subRound( B, C, D, E, A, f1, K1, eData[ 4 ] );
161 | subRound( A, B, C, D, E, f1, K1, eData[ 5 ] );
162 | subRound( E, A, B, C, D, f1, K1, eData[ 6 ] );
163 | subRound( D, E, A, B, C, f1, K1, eData[ 7 ] );
164 | subRound( C, D, E, A, B, f1, K1, eData[ 8 ] );
165 | subRound( B, C, D, E, A, f1, K1, eData[ 9 ] );
166 | subRound( A, B, C, D, E, f1, K1, eData[ 10 ] );
167 | subRound( E, A, B, C, D, f1, K1, eData[ 11 ] );
168 | subRound( D, E, A, B, C, f1, K1, eData[ 12 ] );
169 | subRound( C, D, E, A, B, f1, K1, eData[ 13 ] );
170 | subRound( B, C, D, E, A, f1, K1, eData[ 14 ] );
171 | subRound( A, B, C, D, E, f1, K1, eData[ 15 ] );
172 | subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) );
173 | subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) );
174 | subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) );
175 | subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) );
176 |
177 | subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) );
178 | subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) );
179 | subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) );
180 | subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) );
181 | subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) );
182 | subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) );
183 | subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) );
184 | subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) );
185 | subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) );
186 | subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) );
187 | subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) );
188 | subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) );
189 | subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) );
190 | subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) );
191 | subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) );
192 | subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) );
193 | subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) );
194 | subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) );
195 | subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) );
196 | subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) );
197 |
198 | subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) );
199 | subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) );
200 | subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) );
201 | subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) );
202 | subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) );
203 | subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) );
204 | subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) );
205 | subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) );
206 | subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) );
207 | subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) );
208 | subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) );
209 | subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) );
210 | subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) );
211 | subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) );
212 | subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) );
213 | subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) );
214 | subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) );
215 | subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) );
216 | subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) );
217 | subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) );
218 |
219 | subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) );
220 | subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) );
221 | subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) );
222 | subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) );
223 | subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) );
224 | subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) );
225 | subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) );
226 | subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) );
227 | subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) );
228 | subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) );
229 | subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) );
230 | subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) );
231 | subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) );
232 | subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) );
233 | subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) );
234 | subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) );
235 | subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) );
236 | subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) );
237 | subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) );
238 | subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) );
239 |
240 | /* Build message digest */
241 | digest[ 0 ] += A;
242 | digest[ 1 ] += B;
243 | digest[ 2 ] += C;
244 | digest[ 3 ] += D;
245 | digest[ 4 ] += E;
246 | }
247 |
248 | /* When run on a little-endian CPU we need to perform byte reversal on an
249 | array of long words. */
250 |
251 | static void longReverse(UINT4 *buffer, int byteCount, int Endianness )
252 | {
253 | UINT4 value;
254 |
255 | if (Endianness==TRUE) return;
256 | byteCount /= sizeof( UINT4 );
257 | while( byteCount-- )
258 | {
259 | value = *buffer;
260 | value = ( ( value & 0xFF00FF00L ) >> 8 ) | \
261 | ( ( value & 0x00FF00FFL ) << 8 );
262 | *buffer++ = ( value << 16 ) | ( value >> 16 );
263 | }
264 | }
265 |
266 | /* Update SHS for a block of data */
267 |
268 | void SHAUpdate(SHA_CTX *shsInfo, BYTE *buffer, int count)
269 | {
270 | UINT4 tmp;
271 | int dataCount;
272 |
273 | /* Update bitcount */
274 | tmp = shsInfo->countLo;
275 | if ( ( shsInfo->countLo = tmp + ( ( UINT4 ) count << 3 ) ) < tmp )
276 | shsInfo->countHi++; /* Carry from low to high */
277 | shsInfo->countHi += count >> 29;
278 |
279 | /* Get count of bytes already in data */
280 | dataCount = ( int ) ( tmp >> 3 ) & 0x3F;
281 |
282 | /* Handle any leading odd-sized chunks */
283 | if( dataCount )
284 | {
285 | BYTE *p = ( BYTE * ) shsInfo->data + dataCount;
286 |
287 | dataCount = SHS_DATASIZE - dataCount;
288 | if( count < dataCount )
289 | {
290 | memcpy( p, buffer, count );
291 | return;
292 | }
293 | memcpy( p, buffer, dataCount );
294 | longReverse( shsInfo->data, SHS_DATASIZE, shsInfo->Endianness);
295 | SHSTransform( shsInfo->digest, shsInfo->data );
296 | buffer += dataCount;
297 | count -= dataCount;
298 | }
299 |
300 | /* Process data in SHS_DATASIZE chunks */
301 | while( count >= SHS_DATASIZE )
302 | {
303 | memcpy( (POINTER)shsInfo->data, (POINTER)buffer, SHS_DATASIZE );
304 | longReverse( shsInfo->data, SHS_DATASIZE, shsInfo->Endianness );
305 | SHSTransform( shsInfo->digest, shsInfo->data );
306 | buffer += SHS_DATASIZE;
307 | count -= SHS_DATASIZE;
308 | }
309 |
310 | /* Handle any remaining bytes of data. */
311 | memcpy( (POINTER)shsInfo->data, (POINTER)buffer, count );
312 | }
313 |
314 | /* Final wrapup - pad to SHS_DATASIZE-byte boundary with the bit pattern
315 | 1 0* (64-bit count of bits processed, MSB-first) */
316 |
317 | void SHAFinal(BYTE *output, SHA_CTX *shsInfo)
318 | {
319 | int count;
320 | BYTE *dataPtr;
321 |
322 | /* Compute number of bytes mod 64 */
323 | count = ( int ) shsInfo->countLo;
324 | count = ( count >> 3 ) & 0x3F;
325 |
326 | /* Set the first char of padding to 0x80. This is safe since there is
327 | always at least one byte free */
328 | dataPtr = ( BYTE * ) shsInfo->data + count;
329 | *dataPtr++ = 0x80;
330 |
331 | /* Bytes of padding needed to make 64 bytes */
332 | count = SHS_DATASIZE - 1 - count;
333 |
334 | /* Pad out to 56 mod 64 */
335 | if( count < 8 )
336 | {
337 | /* Two lots of padding: Pad the first block to 64 bytes */
338 | memset( dataPtr, 0, count );
339 | longReverse( shsInfo->data, SHS_DATASIZE, shsInfo->Endianness );
340 | SHSTransform( shsInfo->digest, shsInfo->data );
341 |
342 | /* Now fill the next block with 56 bytes */
343 | memset( (POINTER)shsInfo->data, 0, SHS_DATASIZE - 8 );
344 | }
345 | else
346 | /* Pad block to 56 bytes */
347 | memset( dataPtr, 0, count - 8 );
348 |
349 | /* Append length in bits and transform */
350 | shsInfo->data[ 14 ] = shsInfo->countHi;
351 | shsInfo->data[ 15 ] = shsInfo->countLo;
352 |
353 | longReverse( shsInfo->data, SHS_DATASIZE - 8, shsInfo->Endianness );
354 | SHSTransform( shsInfo->digest, shsInfo->data );
355 |
356 | /* Output to an array of bytes */
357 | SHAtoByte(output, shsInfo->digest, SHS_DIGESTSIZE);
358 |
359 | /* Zeroise sensitive stuff */
360 | memset((POINTER)shsInfo, 0, sizeof(shsInfo));
361 | }
362 |
363 | static void SHAtoByte(BYTE *output, UINT4 *input, unsigned int len)
364 | { /* Output SHA digest in byte array */
365 | unsigned int i, j;
366 |
367 | for(i = 0, j = 0; j < len; i++, j += 4)
368 | {
369 | output[j+3] = (BYTE)( input[i] & 0xff);
370 | output[j+2] = (BYTE)((input[i] >> 8 ) & 0xff);
371 | output[j+1] = (BYTE)((input[i] >> 16) & 0xff);
372 | output[j ] = (BYTE)((input[i] >> 24) & 0xff);
373 | }
374 | }
375 |
376 |
377 |
378 |
379 | /* endian.c */
380 |
381 | void endianTest(int *endian_ness)
382 | {
383 | if((*(unsigned short *) ("#S") >> 8) == '#')
384 | {
385 | /* printf("Big endian = no change\n"); */
386 | *endian_ness = !(0);
387 | }
388 | else
389 | {
390 | /* printf("Little endian = swap\n"); */
391 | *endian_ness = 0;
392 | }
393 | }
394 |
--------------------------------------------------------------------------------
/src/libkirk/SHA1.h:
--------------------------------------------------------------------------------
1 | #ifndef _GLOBAL_H_
2 | #define _GLOBAL_H_ 1
3 |
4 | /* POINTER defines a generic pointer type */
5 | typedef unsigned char *POINTER;
6 |
7 | /* UINT4 defines a four byte word */
8 | typedef unsigned int UINT4;
9 |
10 | /* BYTE defines a unsigned character */
11 | typedef unsigned char BYTE;
12 |
13 | #ifndef TRUE
14 | #define FALSE 0
15 | #define TRUE ( !FALSE )
16 | #endif /* TRUE */
17 |
18 | #endif /* end _GLOBAL_H_ */
19 |
20 | /* sha.h */
21 |
22 | #ifndef _SHA_H_
23 | #define _SHA_H_ 1
24 |
25 | /* #include "global.h" */
26 |
27 | /* The structure for storing SHS info */
28 |
29 | typedef struct
30 | {
31 | UINT4 digest[ 5 ]; /* Message digest */
32 | UINT4 countLo, countHi; /* 64-bit bit count */
33 | UINT4 data[ 16 ]; /* SHS data buffer */
34 | int Endianness;
35 | } SHA_CTX;
36 |
37 | /* Message digest functions */
38 |
39 | void SHAInit(SHA_CTX *);
40 | void SHAUpdate(SHA_CTX *, BYTE *buffer, int count);
41 | void SHAFinal(BYTE *output, SHA_CTX *);
42 |
43 | #endif /* end _SHA_H_ */
44 |
45 | /* endian.h */
46 |
47 | #ifndef _ENDIAN_H_
48 | #define _ENDIAN_H_ 1
49 |
50 | void endianTest(int *endianness);
51 |
52 | #endif /* end _ENDIAN_H_ */
53 |
--------------------------------------------------------------------------------
/src/libkirk/amctrl.c:
--------------------------------------------------------------------------------
1 | /*
2 | * amctrl.c -- Reverse engineering of amctrl.prx
3 | * written by tpu.
4 | */
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | #include "kirk_engine.h"
11 | #include "amctrl.h"
12 |
13 | static u8 loc_1CD4[16] = {0xE3, 0x50, 0xED, 0x1D, 0x91, 0x0A, 0x1F, 0xD0, 0x29, 0xBB, 0x1C, 0x3E, 0xF3, 0x40, 0x77, 0xFB};
14 | static u8 loc_1CE4[16] = {0x13, 0x5F, 0xA4, 0x7C, 0xAB, 0x39, 0x5B, 0xA4, 0x76, 0xB8, 0xCC, 0xA9, 0x8F, 0x3A, 0x04, 0x45};
15 | static u8 loc_1CF4[16] = {0x67, 0x8D, 0x7F, 0xA3, 0x2A, 0x9C, 0xA0, 0xD1, 0x50, 0x8A, 0xD8, 0x38, 0x5E, 0x4B, 0x01, 0x7E};
16 |
17 | static u8 kirk_buf[0x0814];
18 |
19 | static int kirk4(u8 *buf, int size, int type)
20 | {
21 | int retv;
22 | u32 *header = (u32*)buf;
23 |
24 | header[0] = 4;
25 | header[1] = 0;
26 | header[2] = 0;
27 | header[3] = type;
28 | header[4] = size;
29 |
30 | retv = sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 4);
31 |
32 | if(retv)
33 | return 0x80510311;
34 |
35 | return 0;
36 | }
37 |
38 | static int kirk7(u8 *buf, int size, int type)
39 | {
40 | int retv;
41 | u32 *header = (u32*)buf;
42 |
43 | header[0] = 5;
44 | header[1] = 0;
45 | header[2] = 0;
46 | header[3] = type;
47 | header[4] = size;
48 |
49 | retv = sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 7);
50 | if(retv)
51 | return 0x80510311;
52 |
53 | return 0;
54 | }
55 |
56 | static int kirk5(u8 *buf, int size)
57 | {
58 | int retv;
59 | u32 *header = (u32*)buf;
60 |
61 | header[0] = 4;
62 | header[1] = 0;
63 | header[2] = 0;
64 | header[3] = 0x0100;
65 | header[4] = size;
66 |
67 | retv = sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 5);
68 | if(retv)
69 | return 0x80510312;
70 |
71 | return 0;
72 | }
73 |
74 | static int kirk8(u8 *buf, int size)
75 | {
76 | int retv;
77 | u32 *header = (u32*)buf;
78 |
79 | header[0] = 5;
80 | header[1] = 0;
81 | header[2] = 0;
82 | header[3] = 0x0100;
83 | header[4] = size;
84 |
85 | retv = sceUtilsBufferCopyWithRange(buf, size+0x14, buf, size, 8);
86 | if(retv)
87 | return 0x80510312;
88 |
89 | return 0;
90 | }
91 |
92 | static int kirk14(u8 *buf)
93 | {
94 | int retv;
95 |
96 | retv = sceUtilsBufferCopyWithRange(buf, 0x14, 0, 0, 14);
97 | if(retv)
98 | return 0x80510315;
99 |
100 | return 0;
101 | }
102 |
103 | static int sub_158(u8 *buf, int size, u8 *key, int key_type)
104 | {
105 | int i, retv;
106 |
107 | for(i=0; i<16; i++){
108 | buf[0x14+i] ^= key[i];
109 | }
110 |
111 | retv = kirk4(buf, size, key_type);
112 | if(retv)
113 | return retv;
114 |
115 | memcpy(key, buf+size+4, 16);
116 |
117 | return 0;
118 | }
119 |
120 | static int sub_1F8(u8 *buf, int size, u8 *key, int key_type)
121 | {
122 | int i, retv;
123 | u8 tmp[16];
124 |
125 | memcpy(tmp, buf+size+0x14-16, 16);
126 |
127 | retv = kirk7(buf, size, key_type);
128 | if(retv)
129 | return retv;
130 |
131 | for(i=0; i<16; i++){
132 | buf[i] ^= key[i];
133 | }
134 |
135 | memcpy(key, tmp, 16);
136 |
137 | return 0;
138 | }
139 |
140 | static int sub_428(u8 *kbuf, u8 *dbuf, int size, CIPHER_KEY *ckey)
141 | {
142 | int i, retv;
143 | u8 tmp1[16], tmp2[16];
144 |
145 | memcpy(kbuf+0x14, ckey->key, 16);
146 |
147 | for(i=0; i<16; i++){
148 | kbuf[0x14+i] ^= loc_1CF4[i];
149 | }
150 |
151 | if(ckey->type==2)
152 | retv = kirk8(kbuf, 16);
153 | else
154 | retv = kirk7(kbuf, 16, 0x39);
155 | if(retv)
156 | return retv;
157 |
158 | for(i=0; i<16; i++){
159 | kbuf[i] ^= loc_1CE4[i];
160 | }
161 |
162 | memcpy(tmp2, kbuf, 0x10);
163 |
164 | if(ckey->seed==1){
165 | memset(tmp1, 0, 0x10);
166 | }else{
167 | memcpy(tmp1, tmp2, 0x10);
168 | *(u32*)(tmp1+0x0c) = ckey->seed-1;
169 | }
170 |
171 | for(i=0; iseed;
174 | ckey->seed += 1;
175 | }
176 |
177 | retv = sub_1F8(kbuf, size, tmp1, 0x63);
178 | if(retv)
179 | return retv;
180 |
181 | for(i=0; itype = type;
191 | mkey->pad_size = 0;
192 |
193 | memset(mkey->key, 0, 16);
194 | memset(mkey->pad, 0, 16);
195 |
196 | return 0;
197 | }
198 |
199 | int sceDrmBBMacUpdate(MAC_KEY *mkey, u8 *buf, int size)
200 | {
201 | int retv = 0, ksize, p, type;
202 | u8 *kbuf;
203 |
204 | if(mkey->pad_size>16){
205 | retv = 0x80510302;
206 | goto _exit;
207 | }
208 |
209 | if(mkey->pad_size+size<=16){
210 | memcpy(mkey->pad+mkey->pad_size, buf, size);
211 | mkey->pad_size += size;
212 | retv = 0;
213 | }else{
214 | kbuf = kirk_buf+0x14;
215 | memcpy(kbuf, mkey->pad, mkey->pad_size);
216 |
217 | p = mkey->pad_size;
218 |
219 | mkey->pad_size += size;
220 | mkey->pad_size &= 0x0f;
221 | if(mkey->pad_size==0)
222 | mkey->pad_size = 16;
223 |
224 | size -= mkey->pad_size;
225 | memcpy(mkey->pad, buf+size, mkey->pad_size);
226 |
227 | type = (mkey->type==2)? 0x3A : 0x38;
228 |
229 | while(size){
230 | ksize = (size+p>=0x0800)? 0x0800 : size+p;
231 | memcpy(kbuf+p, buf, ksize-p);
232 | retv = sub_158(kirk_buf, ksize, mkey->key, type);
233 | if(retv)
234 | goto _exit;
235 | size -= (ksize-p);
236 | buf += ksize-p;
237 | p = 0;
238 | }
239 | }
240 |
241 | _exit:
242 | return retv;
243 |
244 | }
245 |
246 | int sceDrmBBMacFinal(MAC_KEY *mkey, u8 *buf, u8 *vkey)
247 | {
248 | int i, retv, code;
249 | u8 *kbuf, tmp[16], tmp1[16];
250 | u32 t0, v0, v1;
251 |
252 | if(mkey->pad_size>16)
253 | return 0x80510302;
254 |
255 | code = (mkey->type==2)? 0x3A : 0x38;
256 | kbuf = kirk_buf+0x14;
257 |
258 | memset(kbuf, 0, 16);
259 | retv = kirk4(kirk_buf, 16, code);
260 | if(retv)
261 | goto _exit;
262 | memcpy(tmp, kbuf, 16);
263 |
264 | t0 = (tmp[0]&0x80)? 0x87 : 0;
265 | for(i=0; i<15; i++){
266 | v1 = tmp[i+0];
267 | v0 = tmp[i+1];
268 | v1 <<= 1;
269 | v0 >>= 7;
270 | v0 |= v1;
271 | tmp[i+0] = v0;
272 | }
273 | v0 = tmp[15];
274 | v0 <<= 1;
275 | v0 ^= t0;
276 | tmp[15] = v0;
277 |
278 | if(mkey->pad_size<16){
279 | t0 = (tmp[0]&0x80)? 0x87 : 0;
280 | for(i=0; i<15; i++){
281 | v1 = tmp[i+0];
282 | v0 = tmp[i+1];
283 | v1 <<= 1;
284 | v0 >>= 7;
285 | v0 |= v1;
286 | tmp[i+0] = v0;
287 | }
288 | v0 = tmp[15];
289 | v0 <<= 1;
290 | v0 ^= t0;
291 | tmp[15] = v0;
292 |
293 | mkey->pad[mkey->pad_size] = 0x80;
294 | if(mkey->pad_size+1<16)
295 | memset(mkey->pad+mkey->pad_size+1, 0, 16-mkey->pad_size-1);
296 | }
297 |
298 | for(i=0; i<16; i++){
299 | mkey->pad[i] ^= tmp[i];
300 | }
301 |
302 | memcpy(kbuf, mkey->pad, 16);
303 | memcpy(tmp1, mkey->key, 16);
304 |
305 | retv = sub_158(kirk_buf, 0x10, tmp1, code);
306 | if(retv)
307 | return retv;
308 |
309 | for(i=0; i<0x10; i++){
310 | tmp1[i] ^= loc_1CD4[i];
311 | }
312 |
313 | if(mkey->type==2){
314 | memcpy(kbuf, tmp1, 16);
315 |
316 | retv = kirk5(kirk_buf, 0x10);
317 | if(retv)
318 | goto _exit;
319 |
320 | retv = kirk4(kirk_buf, 0x10, code);
321 | if(retv)
322 | goto _exit;
323 |
324 | memcpy(tmp1, kbuf, 16);
325 | }
326 |
327 | if(vkey){
328 | for(i=0; i<0x10; i++){
329 | tmp1[i] ^= vkey[i];
330 | }
331 | memcpy(kbuf, tmp1, 16);
332 |
333 | retv = kirk4(kirk_buf, 0x10, code);
334 | if(retv)
335 | goto _exit;
336 |
337 | memcpy(tmp1, kbuf, 16);
338 | }
339 |
340 | memcpy(buf, tmp1, 16);
341 |
342 | memset(mkey->key, 0, 16);
343 | memset(mkey->pad, 0, 16);
344 |
345 | mkey->pad_size = 0;
346 | mkey->type = 0;
347 | retv = 0;
348 |
349 | _exit:
350 | return retv;
351 | }
352 |
353 | int sceDrmBBMacFinal2(MAC_KEY *mkey, u8 *out, u8 *vkey)
354 | {
355 | int i, retv, type;
356 | u8 *kbuf, tmp[16];
357 |
358 | type = mkey->type;
359 | retv = sceDrmBBMacFinal(mkey, tmp, vkey);
360 | if(retv)
361 | return retv;
362 |
363 | kbuf = kirk_buf+0x14;
364 |
365 | if(type==3){
366 | memcpy(kbuf, out, 0x10);
367 | kirk7(kirk_buf, 0x10, 0x63);
368 | }else{
369 | memcpy(kirk_buf, out, 0x10);
370 | }
371 |
372 | retv = 0;
373 | for(i=0; i<0x10; i++){
374 | if(kirk_buf[i]!=tmp[i]){
375 | retv = 0x80510300;
376 | break;
377 | }
378 | }
379 |
380 | return retv;
381 | }
382 |
383 | int sceDrmBBCipherInit(CIPHER_KEY *ckey, int type, int mode, u8 *header_key, u8 *version_key, u32 seed)
384 | {
385 | int i, retv;
386 | u8 *kbuf;
387 |
388 | kbuf = kirk_buf+0x14;
389 | ckey->type = type;
390 | if(mode==2){
391 | ckey->seed = seed+1;
392 | for(i=0; i<16; i++){
393 | ckey->key[i] = header_key[i];
394 | }
395 | if(version_key){
396 | for(i=0; i<16; i++){
397 | ckey->key[i] ^= version_key[i];
398 | }
399 | }
400 | retv = 0;
401 | }else if(mode==1){
402 | ckey->seed = 1;
403 | retv = kirk14(kirk_buf);
404 | if(retv)
405 | return retv;
406 |
407 | memcpy(kbuf, kirk_buf, 0x10);
408 | memset(kbuf+0x0c, 0, 4);
409 |
410 | if(ckey->type==2){
411 | for(i=0; i<16; i++){
412 | kbuf[i] ^= loc_1CE4[i];
413 | }
414 | retv = kirk5(kirk_buf, 0x10);
415 | for(i=0; i<16; i++){
416 | kbuf[i] ^= loc_1CF4[i];
417 | }
418 | }else{
419 | for(i=0; i<16; i++){
420 | kbuf[i] ^= loc_1CE4[i];
421 | }
422 | retv = kirk4(kirk_buf, 0x10, 0x39);
423 | for(i=0; i<16; i++){
424 | kbuf[i] ^= loc_1CF4[i];
425 | }
426 | }
427 | if(retv)
428 | return retv;
429 |
430 | memcpy(ckey->key, kbuf, 0x10);
431 | memcpy(header_key, kbuf, 0x10);
432 |
433 | if(version_key){
434 | for(i=0; i<16; i++){
435 | ckey->key[i] ^= version_key[i];
436 | }
437 | }
438 | }else{
439 | retv = 0;
440 | }
441 |
442 | return retv;
443 | }
444 |
445 | int sceDrmBBCipherUpdate(CIPHER_KEY *ckey, u8 *data, int size)
446 | {
447 | int p, retv, dsize;
448 |
449 | retv = 0;
450 | p = 0;
451 |
452 | while(size>0){
453 | dsize = (size>=0x0800)? 0x0800 : size;
454 | retv = sub_428(kirk_buf, data+p, dsize, ckey);
455 | if(retv)
456 | break;
457 | size -= dsize;
458 | p += dsize;
459 | }
460 |
461 | return retv;
462 | }
463 |
464 | int sceDrmBBCipherFinal(CIPHER_KEY *ckey)
465 | {
466 | memset(ckey->key, 0, 16);
467 | ckey->type = 0;
468 | ckey->seed = 0;
469 |
470 | return 0;
471 | }
472 |
473 | int bbmac_build_final2(int type, u8 *mac)
474 | {
475 | u8 *kbuf = kirk_buf+0x14;
476 |
477 | if(type==3){
478 | memcpy(kbuf, mac, 16);
479 | kirk4(kirk_buf, 0x10, 0x63);
480 | memcpy(mac, kbuf, 16);
481 | }
482 |
483 | return 0;
484 | }
485 |
486 | int bbmac_getkey(MAC_KEY *mkey, u8 *bbmac, u8 *vkey)
487 | {
488 | int i, retv, type, code;
489 | u8 *kbuf, tmp[16], tmp1[16];
490 |
491 | type = mkey->type;
492 | retv = sceDrmBBMacFinal(mkey, tmp, NULL);
493 | if(retv)
494 | return retv;
495 |
496 | kbuf = kirk_buf+0x14;
497 |
498 | if(type==3){
499 | memcpy(kbuf, bbmac, 0x10);
500 | kirk7(kirk_buf, 0x10, 0x63);
501 | }else{
502 | memcpy(kirk_buf, bbmac, 0x10);
503 | }
504 |
505 | memcpy(tmp1, kirk_buf, 16);
506 | memcpy(kbuf, tmp1, 16);
507 |
508 | code = (type==2)? 0x3A : 0x38;
509 | kirk7(kirk_buf, 0x10, code);
510 |
511 | for(i=0; i<0x10; i++){
512 | vkey[i] = tmp[i] ^ kirk_buf[i];
513 | }
514 |
515 | return 0;
516 | }
517 |
518 | int bbmac_forge(MAC_KEY *mkey, u8 *bbmac, u8 *vkey, u8 *buf)
519 | {
520 | int i, retv, type;
521 | u8 *kbuf, tmp[16], tmp1[16];
522 | u32 t0, v0, v1;
523 |
524 | if(mkey->pad_size>16)
525 | return 0x80510302;
526 |
527 | type = (mkey->type==2)? 0x3A : 0x38;
528 | kbuf = kirk_buf+0x14;
529 |
530 | memset(kbuf, 0, 16);
531 | retv = kirk4(kirk_buf, 16, type);
532 | if(retv)
533 | return retv;
534 | memcpy(tmp, kbuf, 16);
535 |
536 | t0 = (tmp[0]&0x80)? 0x87 : 0;
537 | for(i=0; i<15; i++){
538 | v1 = tmp[i+0];
539 | v0 = tmp[i+1];
540 | v1 <<= 1;
541 | v0 >>= 7;
542 | v0 |= v1;
543 | tmp[i+0] = v0;
544 | }
545 | v0 = tmp[15];
546 | v0 <<= 1;
547 | v0 ^= t0;
548 | tmp[15] = v0;
549 |
550 | if(mkey->pad_size<16){
551 | t0 = (tmp[0]&0x80)? 0x87 : 0;
552 | for(i=0; i<15; i++){
553 | v1 = tmp[i+0];
554 | v0 = tmp[i+1];
555 | v1 <<= 1;
556 | v0 >>= 7;
557 | v0 |= v1;
558 | tmp[i+0] = v0;
559 | }
560 | v0 = tmp[15];
561 | v0 <<= 1;
562 | v0 ^= t0;
563 | tmp[15] = t0;
564 |
565 | mkey->pad[mkey->pad_size] = 0x80;
566 | if(mkey->pad_size+1<16)
567 | memset(mkey->pad+mkey->pad_size+1, 0, 16-mkey->pad_size-1);
568 | }
569 |
570 | for(i=0; i<16; i++){
571 | mkey->pad[i] ^= tmp[i];
572 | }
573 | for(i=0; i<0x10; i++){
574 | mkey->pad[i] ^= mkey->key[i];
575 | }
576 |
577 | memcpy(kbuf, bbmac, 0x10);
578 | kirk7(kirk_buf, 0x10, 0x63);
579 |
580 | memcpy(kbuf, kirk_buf, 0x10);
581 | kirk7(kirk_buf, 0x10, type);
582 |
583 | memcpy(tmp1, kirk_buf, 0x10);
584 | for(i=0; i<0x10; i++){
585 | tmp1[i] ^= vkey[i];
586 | }
587 | for(i=0; i<0x10; i++){
588 | tmp1[i] ^= loc_1CD4[i];
589 | }
590 |
591 | memcpy(kbuf, tmp1, 0x10);
592 | kirk7(kirk_buf, 0x10, type);
593 |
594 | memcpy(tmp1, kirk_buf, 0x10);
595 | for(i=0; i<16; i++){
596 | mkey->pad[i] ^= tmp1[i];
597 | }
598 |
599 | for(i=0; i<16; i++){
600 | buf[i] ^= mkey->pad[i];
601 | }
602 |
603 | return 0;
604 | }
--------------------------------------------------------------------------------
/src/libkirk/amctrl.h:
--------------------------------------------------------------------------------
1 | #ifndef AMCTRL_H
2 | #define AMCTRL_H
3 |
4 | typedef struct {
5 | int type;
6 | u8 key[16];
7 | u8 pad[16];
8 | int pad_size;
9 | } MAC_KEY;
10 |
11 | typedef struct
12 | {
13 | u32 type;
14 | u32 seed;
15 | u8 key[16];
16 | } CIPHER_KEY;
17 |
18 | int sceDrmBBMacInit(MAC_KEY *mkey, int type);
19 | int sceDrmBBMacUpdate(MAC_KEY *mkey, u8 *buf, int size);
20 | int sceDrmBBMacFinal(MAC_KEY *mkey, u8 *buf, u8 *vkey);
21 | int sceDrmBBMacFinal2(MAC_KEY *mkey, u8 *out, u8 *vkey);
22 |
23 | int bbmac_build_final2(int type, u8 *mac);
24 | int bbmac_getkey(MAC_KEY *mkey, u8 *bbmac, u8 *vkey);
25 | int bbmac_forge(MAC_KEY *mkey, u8 *bbmac, u8 *vkey, u8 *buf);
26 |
27 | int sceDrmBBCipherInit(CIPHER_KEY *ckey, int type, int mode, u8 *header_key, u8 *version_key, u32 seed);
28 | int sceDrmBBCipherUpdate(CIPHER_KEY *ckey, u8 *data, int size);
29 | int sceDrmBBCipherFinal(CIPHER_KEY *ckey);
30 |
31 | #endif
32 |
--------------------------------------------------------------------------------
/src/libkirk/bn.c:
--------------------------------------------------------------------------------
1 | // Copyright 2007,2008,2010 Segher Boessenkool
2 | // Licensed under the terms of the GNU GPL, version 2
3 | // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
4 | // Updated and simplified for use by Kirk Engine - July 2011
5 |
6 | #include
7 | #include
8 |
9 | // Include definitions from kirk header
10 | #include "kirk_engine.h"
11 |
12 | void bn_print(char *name, u8 *a, u32 n)
13 | {
14 | u32 i;
15 |
16 | printf("%s = ", name);
17 |
18 | for (i = 0; i < n; i++)
19 | printf("%02x", a[i]);
20 |
21 | printf("\n");
22 | }
23 |
24 | static void bn_zero(u8 *d, u32 n)
25 | {
26 | memset(d, 0, n);
27 | }
28 |
29 | void bn_copy(u8 *d, u8 *a, u32 n)
30 | {
31 | memcpy(d, a, n);
32 | }
33 |
34 | int bn_compare(u8 *a, u8 *b, u32 n)
35 | {
36 | u32 i;
37 |
38 | for (i = 0; i < n; i++) {
39 | if (a[i] < b[i])
40 | return -1;
41 | if (a[i] > b[i])
42 | return 1;
43 | }
44 |
45 | return 0;
46 | }
47 |
48 | static u8 bn_add_1(u8 *d, u8 *a, u8 *b, u32 n)
49 | {
50 | u32 i;
51 | u32 dig;
52 | u8 c;
53 |
54 | c = 0;
55 | for (i = n - 1; i < n; i--) {
56 | dig = a[i] + b[i] + c;
57 | c = dig >> 8;
58 | d[i] = dig;
59 | }
60 |
61 | return c;
62 | }
63 |
64 | static u8 bn_sub_1(u8 *d, u8 *a, u8 *b, u32 n)
65 | {
66 | u32 i;
67 | u32 dig;
68 | u8 c;
69 |
70 | c = 1;
71 | for (i = n - 1; i < n; i--) {
72 | dig = a[i] + 255 - b[i] + c;
73 | c = dig >> 8;
74 | d[i] = dig;
75 | }
76 |
77 | return 1 - c;
78 | }
79 |
80 | void bn_reduce(u8 *d, u8 *N, u32 n)
81 | {
82 | if (bn_compare(d, N, n) >= 0)
83 | bn_sub_1(d, d, N, n);
84 | }
85 |
86 | void bn_add(u8 *d, u8 *a, u8 *b, u8 *N, u32 n)
87 | {
88 | if (bn_add_1(d, a, b, n))
89 | bn_sub_1(d, d, N, n);
90 |
91 | bn_reduce(d, N, n);
92 | }
93 |
94 | void bn_sub(u8 *d, u8 *a, u8 *b, u8 *N, u32 n)
95 | {
96 | if (bn_sub_1(d, a, b, n))
97 | bn_add_1(d, d, N, n);
98 | }
99 |
100 | static const u8 inv256[0x80] = {
101 | 0x01, 0xab, 0xcd, 0xb7, 0x39, 0xa3, 0xc5, 0xef,
102 | 0xf1, 0x1b, 0x3d, 0xa7, 0x29, 0x13, 0x35, 0xdf,
103 | 0xe1, 0x8b, 0xad, 0x97, 0x19, 0x83, 0xa5, 0xcf,
104 | 0xd1, 0xfb, 0x1d, 0x87, 0x09, 0xf3, 0x15, 0xbf,
105 | 0xc1, 0x6b, 0x8d, 0x77, 0xf9, 0x63, 0x85, 0xaf,
106 | 0xb1, 0xdb, 0xfd, 0x67, 0xe9, 0xd3, 0xf5, 0x9f,
107 | 0xa1, 0x4b, 0x6d, 0x57, 0xd9, 0x43, 0x65, 0x8f,
108 | 0x91, 0xbb, 0xdd, 0x47, 0xc9, 0xb3, 0xd5, 0x7f,
109 | 0x81, 0x2b, 0x4d, 0x37, 0xb9, 0x23, 0x45, 0x6f,
110 | 0x71, 0x9b, 0xbd, 0x27, 0xa9, 0x93, 0xb5, 0x5f,
111 | 0x61, 0x0b, 0x2d, 0x17, 0x99, 0x03, 0x25, 0x4f,
112 | 0x51, 0x7b, 0x9d, 0x07, 0x89, 0x73, 0x95, 0x3f,
113 | 0x41, 0xeb, 0x0d, 0xf7, 0x79, 0xe3, 0x05, 0x2f,
114 | 0x31, 0x5b, 0x7d, 0xe7, 0x69, 0x53, 0x75, 0x1f,
115 | 0x21, 0xcb, 0xed, 0xd7, 0x59, 0xc3, 0xe5, 0x0f,
116 | 0x11, 0x3b, 0x5d, 0xc7, 0x49, 0x33, 0x55, 0xff,
117 | };
118 |
119 | static void bn_mon_muladd_dig(u8 *d, u8 *a, u8 b, u8 *N, u32 n)
120 | {
121 | u32 dig;
122 | u32 i;
123 |
124 | u8 z = -(d[n-1] + a[n-1]*b) * inv256[N[n-1]/2];
125 |
126 | dig = d[n-1] + a[n-1]*b + N[n-1]*z;
127 | dig >>= 8;
128 |
129 | for (i = n - 2; i < n; i--) {
130 | dig += d[i] + a[i]*b + N[i]*z;
131 | d[i+1] = dig;
132 | dig >>= 8;
133 | }
134 |
135 | d[0] = dig;
136 | dig >>= 8;
137 |
138 | if (dig)
139 | bn_sub_1(d, d, N, n);
140 |
141 | bn_reduce(d, N, n);
142 | }
143 |
144 | void bn_mon_mul(u8 *d, u8 *a, u8 *b, u8 *N, u32 n)
145 | {
146 | u8 t[512];
147 | u32 i;
148 |
149 | bn_zero(t, n);
150 |
151 | for (i = n - 1; i < n; i--)
152 | bn_mon_muladd_dig(t, a, b[i], N, n);
153 |
154 | bn_copy(d, t, n);
155 | }
156 |
157 | void bn_to_mon(u8 *d, u8 *N, u32 n)
158 | {
159 | u32 i;
160 |
161 | for (i = 0; i < 8*n; i++)
162 | bn_add(d, d, d, N, n);
163 | }
164 |
165 | void bn_from_mon(u8 *d, u8 *N, u32 n)
166 | {
167 | u8 t[512];
168 |
169 | bn_zero(t, n);
170 | t[n-1] = 1;
171 | bn_mon_mul(d, d, t, N, n);
172 | }
173 |
174 | static void bn_mon_exp(u8 *d, u8 *a, u8 *N, u32 n, u8 *e, u32 en)
175 | {
176 | u8 t[512];
177 | u32 i;
178 | u8 mask;
179 |
180 | bn_zero(d, n);
181 | d[n-1] = 1;
182 | bn_to_mon(d, N, n);
183 |
184 | for (i = 0; i < en; i++)
185 | for (mask = 0x80; mask != 0; mask >>= 1) {
186 | bn_mon_mul(t, d, d, N, n);
187 | if ((e[i] & mask) != 0)
188 | bn_mon_mul(d, t, a, N, n);
189 | else
190 | bn_copy(d, t, n);
191 | }
192 | }
193 |
194 | void bn_mon_inv(u8 *d, u8 *a, u8 *N, u32 n)
195 | {
196 | u8 t[512], s[512];
197 |
198 | bn_zero(s, n);
199 | s[n-1] = 2;
200 | bn_sub_1(t, N, s, n);
201 | bn_mon_exp(d, a, N, n, t, n);
202 | }
203 |
--------------------------------------------------------------------------------
/src/libkirk/ec.c:
--------------------------------------------------------------------------------
1 | // Copyright 2007,2008,2010 Segher Boessenkool
2 | // Licensed under the terms of the GNU GPL, version 2
3 | // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
4 |
5 |
6 | // Modified for Kirk engine by setting single curve and internal function
7 | // to support Kirk elliptic curve options.- July 2011
8 |
9 | #include
10 | #include
11 |
12 | // Include definitions from kirk header
13 | #include "kirk_engine.h"
14 |
15 | struct point {
16 | u8 x[20];
17 | u8 y[20];
18 | };
19 | // Simplified for use by Kirk Engine since it has only 1 curve
20 |
21 | u8 ec_p[20];
22 | u8 ec_a[20];
23 | u8 ec_b[20];
24 | u8 ec_N[21];
25 | struct point ec_G; // mon
26 | struct point ec_Q; // mon
27 | u8 ec_k[21];
28 |
29 |
30 |
31 | void hex_dump(char *str, u8 *buf, int size)
32 | {
33 | int i;
34 |
35 | if(str)
36 | printf("%s:", str);
37 |
38 | for(i=0; ix, ec_p, 20);
98 | bn_to_mon(p->y, ec_p, 20);
99 | }
100 |
101 | static void point_from_mon(struct point *p)
102 | {
103 | bn_from_mon(p->x, ec_p, 20);
104 | bn_from_mon(p->y, ec_p, 20);
105 | }
106 |
107 | #if 0
108 | static int point_is_on_curve(u8 *p)
109 | {
110 | u8 s[20], t[20];
111 | u8 *x, *y;
112 |
113 | x = p;
114 | y = p + 20;
115 |
116 | elt_square(t, x);
117 | elt_mul(s, t, x);
118 |
119 | elt_mul(t, x, ec_a);
120 | elt_add(s, s, t);
121 |
122 | elt_add(s, s, ec_b);
123 |
124 | elt_square(t, y);
125 | elt_sub(s, s, t);
126 |
127 | return elt_is_zero(s);
128 | }
129 | #endif
130 |
131 | static void point_zero(struct point *p)
132 | {
133 | elt_zero(p->x);
134 | elt_zero(p->y);
135 | }
136 |
137 | static int point_is_zero(struct point *p)
138 | {
139 | return elt_is_zero(p->x) && elt_is_zero(p->y);
140 | }
141 |
142 | static void point_double(struct point *r, struct point *p)
143 | {
144 | u8 s[20], t[20];
145 | struct point pp;
146 | u8 *px, *py, *rx, *ry;
147 |
148 | pp = *p;
149 |
150 | px = pp.x;
151 | py = pp.y;
152 | rx = r->x;
153 | ry = r->y;
154 |
155 | if (elt_is_zero(py)) {
156 | point_zero(r);
157 | return;
158 | }
159 |
160 | elt_square(t, px); // t = px*px
161 | elt_add(s, t, t); // s = 2*px*px
162 | elt_add(s, s, t); // s = 3*px*px
163 | elt_add(s, s, ec_a); // s = 3*px*px + a
164 | elt_add(t, py, py); // t = 2*py
165 | elt_inv(t, t); // t = 1/(2*py)
166 | elt_mul(s, s, t); // s = (3*px*px+a)/(2*py)
167 |
168 | elt_square(rx, s); // rx = s*s
169 | elt_add(t, px, px); // t = 2*px
170 | elt_sub(rx, rx, t); // rx = s*s - 2*px
171 |
172 | elt_sub(t, px, rx); // t = -(rx-px)
173 | elt_mul(ry, s, t); // ry = -s*(rx-px)
174 | elt_sub(ry, ry, py); // ry = -s*(rx-px) - py
175 | }
176 |
177 | static void point_add(struct point *r, struct point *p, struct point *q)
178 | {
179 | u8 s[20], t[20], u[20];
180 | u8 *px, *py, *qx, *qy, *rx, *ry;
181 | struct point pp, qq;
182 |
183 | pp = *p;
184 | qq = *q;
185 |
186 | px = pp.x;
187 | py = pp.y;
188 | qx = qq.x;
189 | qy = qq.y;
190 | rx = r->x;
191 | ry = r->y;
192 |
193 | if (point_is_zero(&pp)) {
194 | elt_copy(rx, qx);
195 | elt_copy(ry, qy);
196 | return;
197 | }
198 |
199 | if (point_is_zero(&qq)) {
200 | elt_copy(rx, px);
201 | elt_copy(ry, py);
202 | return;
203 | }
204 |
205 | elt_sub(u, qx, px);
206 |
207 | if (elt_is_zero(u)) {
208 | elt_sub(u, qy, py);
209 | if (elt_is_zero(u))
210 | point_double(r, &pp);
211 | else
212 | point_zero(r);
213 |
214 | return;
215 | }
216 |
217 | elt_inv(t, u); // t = 1/(qx-px)
218 | elt_sub(u, qy, py); // u = qy-py
219 | elt_mul(s, t, u); // s = (qy-py)/(qx-px)
220 |
221 | elt_square(rx, s); // rx = s*s
222 | elt_add(t, px, qx); // t = px+qx
223 | elt_sub(rx, rx, t); // rx = s*s - (px+qx)
224 |
225 | elt_sub(t, px, rx); // t = -(rx-px)
226 | elt_mul(ry, s, t); // ry = -s*(rx-px)
227 | elt_sub(ry, ry, py); // ry = -s*(rx-px) - py
228 | }
229 |
230 | static void point_mul(struct point *d, u8 *a, struct point *b) // a is bignum
231 | {
232 | u32 i;
233 | u8 mask;
234 |
235 | point_zero(d);
236 |
237 | for (i = 0; i < 21; i++)
238 | for (mask = 0x80; mask != 0; mask >>= 1) {
239 | point_double(d, d);
240 | if ((a[i] & mask) != 0)
241 | point_add(d, d, b);
242 | }
243 | }
244 | // Modified from original to support kirk engine use - July 2011
245 | // Added call to Kirk Random number generator rather than /dev/random
246 |
247 | static void generate_ecdsa(u8 *outR, u8 *outS, u8 *k, u8 *hash)
248 | {
249 | u8 e[21];
250 | u8 kk[21];
251 | u8 m[21];
252 | u8 R[21];
253 | u8 S[21];
254 | u8 minv[21];
255 | struct point mG;
256 |
257 | e[0] = 0;R[0] = 0;S[0] = 0;
258 | memcpy(e + 1, hash, 20);
259 | bn_reduce(e, ec_N, 21);
260 |
261 | // Original removed for portability
262 | //try_again:
263 | //fp = fopen("/dev/random", "rb");
264 | //if (fread(m, sizeof m, 1, fp) != 1)
265 | //fail("reading random");
266 | //fclose(fp);
267 | //m[0] = 0;
268 | //if (bn_compare(m, ec_N, 21) >= 0)
269 | //goto try_again;
270 |
271 | // R = (mG).x
272 |
273 | // Added call back to kirk PRNG - July 2011
274 | kirk_CMD14(m+1, 20);
275 | m[0] = 0;
276 |
277 | point_mul(&mG, m, &ec_G);
278 | point_from_mon(&mG);
279 | R[0] = 0;
280 | elt_copy(R+1, mG.x);
281 |
282 | // S = m**-1*(e + Rk) (mod N)
283 |
284 | bn_copy(kk, k, 21);
285 | bn_reduce(kk, ec_N, 21);
286 | bn_to_mon(m, ec_N, 21);
287 | bn_to_mon(e, ec_N, 21);
288 | bn_to_mon(R, ec_N, 21);
289 | bn_to_mon(kk, ec_N, 21);
290 |
291 | bn_mon_mul(S, R, kk, ec_N, 21);
292 | bn_add(kk, S, e, ec_N, 21);
293 | bn_mon_inv(minv, m, ec_N, 21);
294 | bn_mon_mul(S, minv, kk, ec_N, 21);
295 |
296 | bn_from_mon(R, ec_N, 21);
297 | bn_from_mon(S, ec_N, 21);
298 | memcpy(outR,R+1,0x20);
299 | memcpy(outS,S+1,0x20);
300 | }
301 |
302 | // Signing =
303 | // r = k *G;
304 | // s = x*r+m / k
305 |
306 | // Verify =
307 | // r/s * P = m/s * G
308 |
309 | // Slightly modified to support kirk compatible signature input - July 2011
310 | static int check_ecdsa(struct point *Q, u8 *inR, u8 *inS, u8 *hash)
311 | {
312 | u8 Sinv[21];
313 | u8 e[21], R[21], S[21];
314 | u8 w1[21], w2[21];
315 | struct point r1, r2;
316 | u8 rr[21];
317 |
318 | e[0] = 0;
319 | memcpy(e + 1, hash, 20);
320 | bn_reduce(e, ec_N, 21);
321 | R[0] = 0;
322 | memcpy(R + 1, inR, 20);
323 | bn_reduce(R, ec_N, 21);
324 | S[0] = 0;
325 | memcpy(S + 1, inS, 20);
326 | bn_reduce(S, ec_N, 21);
327 |
328 | bn_to_mon(R, ec_N, 21);
329 | bn_to_mon(S, ec_N, 21);
330 | bn_to_mon(e, ec_N, 21);
331 | // make Sinv = 1/S
332 | bn_mon_inv(Sinv, S, ec_N, 21);
333 | // w1 = m * Sinv
334 | bn_mon_mul(w1, e, Sinv, ec_N, 21);
335 | // w2 = r * Sinv
336 | bn_mon_mul(w2, R, Sinv, ec_N, 21);
337 |
338 | // mod N both
339 | bn_from_mon(w1, ec_N, 21);
340 | bn_from_mon(w2, ec_N, 21);
341 |
342 | // r1 = m/s * G
343 | point_mul(&r1, w1, &ec_G);
344 | // r2 = r/s * P
345 | point_mul(&r2, w2, Q);
346 |
347 | //r1 = r1 + r2
348 | point_add(&r1, &r1, &r2);
349 |
350 | point_from_mon(&r1);
351 |
352 | rr[0] = 0;
353 | memcpy(rr + 1, r1.x, 20);
354 | bn_reduce(rr, ec_N, 21);
355 |
356 | bn_from_mon(R, ec_N, 21);
357 | bn_from_mon(S, ec_N, 21);
358 |
359 | return (bn_compare(rr, R, 21) == 0);
360 | }
361 |
362 |
363 | // Modified from original to support kirk engine use - July 2011
364 | void ec_priv_to_pub(u8 *k, u8 *Q)
365 | {
366 | struct point ec_temp;
367 | bn_to_mon(k, ec_N, 21);
368 | point_mul(&ec_temp, k, &ec_G);
369 | point_from_mon(&ec_temp);
370 | //bn_from_mon(k, ec_N, 21);
371 | memcpy(Q,ec_temp.x,20);
372 | memcpy(Q+20,ec_temp.y,20);
373 | }
374 |
375 | // Modified from original to support kirk engine use - July 2011
376 | void ec_pub_mult(u8 *k, u8 *Q)
377 | {
378 | struct point ec_temp;
379 | //bn_to_mon(k, ec_N, 21);
380 | point_mul(&ec_temp, k, &ec_Q);
381 | point_from_mon(&ec_temp);
382 | //bn_from_mon(k, ec_N, 21);
383 | memcpy(Q,ec_temp.x,20);
384 | memcpy(Q+20,ec_temp.y,20);
385 | }
386 |
387 |
388 | // Simplified for use by Kirk Engine - NO LONGER COMPATIABLE WITH ORIGINAL VERSION - July 2011
389 | int ecdsa_set_curve(u8* p,u8* a,u8* b,u8* N,u8* Gx,u8* Gy)
390 | {
391 | memcpy(ec_p,p,20);
392 | memcpy(ec_a,a,20);
393 | memcpy(ec_b,b,20);
394 | memcpy(ec_N,N,21);
395 |
396 | bn_to_mon(ec_a, ec_p, 20);
397 | bn_to_mon(ec_b, ec_p, 20);
398 |
399 | memcpy(ec_G.x, Gx, 20);
400 | memcpy(ec_G.y, Gy, 20);
401 | point_to_mon(&ec_G);
402 |
403 | return 0;
404 | }
405 |
406 | void ecdsa_set_pub(u8 *Q)
407 | {
408 | memcpy(ec_Q.x, Q, 20);
409 | memcpy(ec_Q.y, Q+20, 20);
410 | point_to_mon(&ec_Q);
411 | }
412 |
413 | void ecdsa_set_priv(u8 *ink)
414 | {
415 | u8 k[21];
416 | k[0]=0;
417 | memcpy(k+1,ink,20);
418 | bn_reduce(k, ec_N, 21);
419 |
420 | memcpy(ec_k, k, sizeof ec_k);
421 | }
422 |
423 | int ecdsa_verify(u8 *hash, u8 *R, u8 *S)
424 | {
425 | return check_ecdsa(&ec_Q, R, S, hash);
426 | }
427 |
428 | void ecdsa_sign(u8 *hash, u8 *R, u8 *S)
429 | {
430 | generate_ecdsa(R, S, ec_k, hash);
431 | }
432 |
433 | int point_is_on_curve(u8 *p)
434 | {
435 | u8 s[20], t[20];
436 | u8 *x, *y;
437 |
438 | x = p;
439 | y = p + 20;
440 |
441 | elt_square(t, x);
442 | elt_mul(s, t, x);// s = x^3
443 |
444 | elt_mul(t, x, ec_a);
445 | elt_add(s, s, t); //s = x^3 + a *x
446 |
447 | elt_add(s, s, ec_b);//s = x^3 + a *x + b
448 |
449 | elt_square(t, y); //t = y^2
450 | elt_sub(s, s, t); // is s - t = 0?
451 | hex_dump("S", s, 20);
452 | hex_dump("T", t,20);
453 | return elt_is_zero(s);
454 | }
455 |
456 | void dump_ecc(void) {
457 | hex_dump("P", ec_p, 20);
458 | hex_dump("a", ec_a, 20);
459 | hex_dump("b", ec_b, 20);
460 | hex_dump("N", ec_N, 21);
461 | hex_dump("Gx", ec_G.x, 20);
462 | hex_dump("Gy", ec_G.y, 20);
463 | }
464 |
--------------------------------------------------------------------------------
/src/libkirk/kirk_engine.c:
--------------------------------------------------------------------------------
1 | /*
2 | Draan proudly presents:
3 |
4 | With huge help from community:
5 | coyotebean, Davee, hitchhikr, kgsws, liquidzigong, Mathieulh, Proxima, SilverSpring
6 |
7 | ******************** KIRK-ENGINE ********************
8 | An Open-Source implementation of KIRK (PSP crypto engine) algorithms and keys.
9 | Includes also additional routines for hash forging.
10 |
11 | ********************
12 |
13 | This program is free software: you can redistribute it and/or modify
14 | it under the terms of the GNU General Public License as published by
15 | the Free Software Foundation, either version 3 of the License, or
16 | (at your option) any later version.
17 |
18 | This program is distributed in the hope that it will be useful,
19 | but WITHOUT ANY WARRANTY; without even the implied warranty of
20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 | GNU General Public License for more details.
22 |
23 | You should have received a copy of the GNU General Public License
24 | along with this program. If not, see .
25 | */
26 |
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include "kirk_engine.h"
32 | #include "AES.h"
33 | #include "SHA1.h"
34 |
35 | /* ------------------------- KEY VAULT ------------------------- */
36 |
37 | u8 kirk1_key[] = {0x98, 0xC9, 0x40, 0x97, 0x5C, 0x1D, 0x10, 0xE8, 0x7F, 0xE6, 0x0E, 0xA3, 0xFD, 0x03, 0xA8, 0xBA};
38 | u8 kirk7_key02[] = {0xB8, 0x13, 0xC3, 0x5E, 0xC6, 0x44, 0x41, 0xE3, 0xDC, 0x3C, 0x16, 0xF5, 0xB4, 0x5E, 0x64, 0x84}; // New from PS3
39 | u8 kirk7_key03[] = {0x98, 0x02, 0xC4, 0xE6, 0xEC, 0x9E, 0x9E, 0x2F, 0xFC, 0x63, 0x4C, 0xE4, 0x2F, 0xBB, 0x46, 0x68};
40 | u8 kirk7_key04[] = {0x99, 0x24, 0x4C, 0xD2, 0x58, 0xF5, 0x1B, 0xCB, 0xB0, 0x61, 0x9C, 0xA7, 0x38, 0x30, 0x07, 0x5F};
41 | u8 kirk7_key05[] = {0x02, 0x25, 0xD7, 0xBA, 0x63, 0xEC, 0xB9, 0x4A, 0x9D, 0x23, 0x76, 0x01, 0xB3, 0xF6, 0xAC, 0x17};
42 | u8 kirk7_key07[] = {0x76, 0x36, 0x8B, 0x43, 0x8F, 0x77, 0xD8, 0x7E, 0xFE, 0x5F, 0xB6, 0x11, 0x59, 0x39, 0x88, 0x5C}; // New from PS3
43 | u8 kirk7_key0C[] = {0x84, 0x85, 0xC8, 0x48, 0x75, 0x08, 0x43, 0xBC, 0x9B, 0x9A, 0xEC, 0xA7, 0x9C, 0x7F, 0x60, 0x18};
44 | u8 kirk7_key0D[] = {0xB5, 0xB1, 0x6E, 0xDE, 0x23, 0xA9, 0x7B, 0x0E, 0xA1, 0x7C, 0xDB, 0xA2, 0xDC, 0xDE, 0xC4, 0x6E};
45 | u8 kirk7_key0E[] = {0xC8, 0x71, 0xFD, 0xB3, 0xBC, 0xC5, 0xD2, 0xF2, 0xE2, 0xD7, 0x72, 0x9D, 0xDF, 0x82, 0x68, 0x82};
46 | u8 kirk7_key0F[] = {0x0A, 0xBB, 0x33, 0x6C, 0x96, 0xD4, 0xCD, 0xD8, 0xCB, 0x5F, 0x4B, 0xE0, 0xBA, 0xDB, 0x9E, 0x03};
47 | u8 kirk7_key10[] = {0x32, 0x29, 0x5B, 0xD5, 0xEA, 0xF7, 0xA3, 0x42, 0x16, 0xC8, 0x8E, 0x48, 0xFF, 0x50, 0xD3, 0x71};
48 | u8 kirk7_key11[] = {0x46, 0xF2, 0x5E, 0x8E, 0x4D, 0x2A, 0xA5, 0x40, 0x73, 0x0B, 0xC4, 0x6E, 0x47, 0xEE, 0x6F, 0x0A};
49 | u8 kirk7_key12[] = {0x5D, 0xC7, 0x11, 0x39, 0xD0, 0x19, 0x38, 0xBC, 0x02, 0x7F, 0xDD, 0xDC, 0xB0, 0x83, 0x7D, 0x9D};
50 | u8 kirk7_key38[] = {0x12, 0x46, 0x8D, 0x7E, 0x1C, 0x42, 0x20, 0x9B, 0xBA, 0x54, 0x26, 0x83, 0x5E, 0xB0, 0x33, 0x03};
51 | u8 kirk7_key39[] = {0xC4, 0x3B, 0xB6, 0xD6, 0x53, 0xEE, 0x67, 0x49, 0x3E, 0xA9, 0x5F, 0xBC, 0x0C, 0xED, 0x6F, 0x8A};
52 | u8 kirk7_key3A[] = {0x2C, 0xC3, 0xCF, 0x8C, 0x28, 0x78, 0xA5, 0xA6, 0x63, 0xE2, 0xAF, 0x2D, 0x71, 0x5E, 0x86, 0xBA};
53 | u8 kirk7_key44[] = {0x7D, 0xF4, 0x92, 0x65, 0xE3, 0xFA, 0xD6, 0x78, 0xD6, 0xFE, 0x78, 0xAD, 0xBB, 0x3D, 0xFB, 0x63}; // New from PS3
54 | u8 kirk7_key4B[] = {0x0C, 0xFD, 0x67, 0x9A, 0xF9, 0xB4, 0x72, 0x4F, 0xD7, 0x8D, 0xD6, 0xE9, 0x96, 0x42, 0x28, 0x8B}; //1.xx game eboot.bin
55 | u8 kirk7_key53[] = {0xAF, 0xFE, 0x8E, 0xB1, 0x3D, 0xD1, 0x7E, 0xD8, 0x0A, 0x61, 0x24, 0x1C, 0x95, 0x92, 0x56, 0xB6};
56 | u8 kirk7_key57[] = {0x1C, 0x9B, 0xC4, 0x90, 0xE3, 0x06, 0x64, 0x81, 0xFA, 0x59, 0xFD, 0xB6, 0x00, 0xBB, 0x28, 0x70};
57 | u8 kirk7_key5D[] = {0x11, 0x5A, 0x5D, 0x20, 0xD5, 0x3A, 0x8D, 0xD3, 0x9C, 0xC5, 0xAF, 0x41, 0x0F, 0x0F, 0x18, 0x6F};
58 | u8 kirk7_key63[] = {0x9C, 0x9B, 0x13, 0x72, 0xF8, 0xC6, 0x40, 0xCF, 0x1C, 0x62, 0xF5, 0xD5, 0x92, 0xDD, 0xB5, 0x82};
59 | u8 kirk7_key64[] = {0x03, 0xB3, 0x02, 0xE8, 0x5F, 0xF3, 0x81, 0xB1, 0x3B, 0x8D, 0xAA, 0x2A, 0x90, 0xFF, 0x5E, 0x61};
60 |
61 | u8 kirk16_key[] = {0x47, 0x5E, 0x09, 0xF4, 0xA2, 0x37, 0xDA, 0x9B, 0xEF, 0xFF, 0x3B, 0xC0, 0x77, 0x14, 0x3D, 0x8A};
62 |
63 | /* ECC Curves for Kirk 1 and Kirk 0x11 */
64 | // Common Curve paramters p and a
65 | static u8 ec_p[20] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
66 | static u8 ec_a[20] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC}; // mon
67 |
68 | // Kirk 0xC,0xD,0x10,0x11,(likely 0x12)- Unique curve parameters for b, N, and base point G for Kirk 0xC,0xD,0x10,0x11,(likely 0x12) service
69 | // Since public key is variable, it is not specified here
70 | static u8 ec_b2[20] = {0xA6, 0x8B, 0xED, 0xC3, 0x34, 0x18, 0x02, 0x9C, 0x1D, 0x3C, 0xE3, 0x3B, 0x9A, 0x32, 0x1F, 0xCC, 0xBB, 0x9E, 0x0F, 0x0B};// mon
71 | static u8 ec_N2[21] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xB5, 0xAE, 0x3C, 0x52, 0x3E, 0x63, 0x94, 0x4F, 0x21, 0x27};
72 | static u8 Gx2[20] = {0x12, 0x8E, 0xC4, 0x25, 0x64, 0x87, 0xFD, 0x8F, 0xDF, 0x64, 0xE2, 0x43, 0x7B, 0xC0, 0xA1, 0xF6, 0xD5, 0xAF, 0xDE, 0x2C };
73 | static u8 Gy2[20] = {0x59, 0x58, 0x55, 0x7E, 0xB1, 0xDB, 0x00, 0x12, 0x60, 0x42, 0x55, 0x24, 0xDB, 0xC3, 0x79, 0xD5, 0xAC, 0x5F, 0x4A, 0xDF };
74 |
75 | // KIRK 1 - Unique curve parameters for b, N, and base point G
76 | // Since public key is hard coded, it is also included
77 |
78 | static u8 ec_b1[20] = {0x65, 0xD1, 0x48, 0x8C, 0x03, 0x59, 0xE2, 0x34, 0xAD, 0xC9, 0x5B, 0xD3, 0x90, 0x80, 0x14, 0xBD, 0x91, 0xA5, 0x25, 0xF9};
79 | static u8 ec_N1[21] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0xB5, 0xC6, 0x17, 0xF2, 0x90, 0xEA, 0xE1, 0xDB, 0xAD, 0x8F};
80 | static u8 Gx1[20] = {0x22, 0x59, 0xAC, 0xEE, 0x15, 0x48, 0x9C, 0xB0, 0x96, 0xA8, 0x82, 0xF0, 0xAE, 0x1C, 0xF9, 0xFD, 0x8E, 0xE5, 0xF8, 0xFA };
81 | static u8 Gy1[20] = {0x60, 0x43, 0x58, 0x45, 0x6D, 0x0A, 0x1C, 0xB2, 0x90, 0x8D, 0xE9, 0x0F, 0x27, 0xD7, 0x5C, 0x82, 0xBE, 0xC1, 0x08, 0xC0 };
82 |
83 | static u8 Px1[20] = {0xED, 0x9C, 0xE5, 0x82, 0x34, 0xE6, 0x1A, 0x53, 0xC6, 0x85, 0xD6, 0x4D, 0x51, 0xD0, 0x23, 0x6B, 0xC3, 0xB5, 0xD4, 0xB9 };
84 | static u8 Py1[20] = {0x04, 0x9D, 0xF1, 0xA0, 0x75, 0xC0, 0xE0, 0x4F, 0xB3, 0x44, 0x85, 0x8B, 0x61, 0xB7, 0x9B, 0x69, 0xA6, 0x3D, 0x2C, 0x39 };
85 |
86 | /* ------------------------- KEY VAULT END ------------------------- */
87 |
88 | /* ------------------------- INTERNAL STUFF ------------------------- */
89 | typedef struct blah
90 | {
91 | u8 fuseid[8]; //0
92 | u8 mesh[0x40]; //0x8
93 | } kirk16_data; //0x48
94 |
95 | typedef struct header_keys
96 | {
97 | u8 AES[16];
98 | u8 CMAC[16];
99 | }header_keys; //small struct for temporary keeping AES & CMAC key from CMD1 header
100 |
101 |
102 | u32 g_fuse90; // This is to match FuseID HW at BC100090 and BC100094
103 | u32 g_fuse94;
104 |
105 | AES_ctx aes_kirk1; //global
106 | u8 PRNG_DATA[0x14];
107 |
108 | char is_kirk_initialized; //"init" emulation
109 |
110 | /* ------------------------- INTERNAL STUFF END ------------------------- */
111 |
112 |
113 | /* ------------------------- IMPLEMENTATION ------------------------- */
114 |
115 | int kirk_CMD0(u8* outbuff, u8* inbuff, int size, int generate_trash)
116 | {
117 | KIRK_CMD1_HEADER* header = (KIRK_CMD1_HEADER*)outbuff;
118 | header_keys *keys = (header_keys *)outbuff; //0-15 AES key, 16-31 CMAC key
119 | int chk_size;
120 | AES_ctx k1;
121 | AES_ctx cmac_key;
122 | u8 cmac_header_hash[16];
123 | u8 cmac_data_hash[16];
124 |
125 | if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
126 |
127 | memcpy(outbuff, inbuff, size);
128 |
129 | if(header->mode != KIRK_MODE_CMD1) return KIRK_INVALID_MODE;
130 |
131 | //FILL PREDATA WITH RANDOM DATA
132 | if(generate_trash) kirk_CMD14(outbuff+sizeof(KIRK_CMD1_HEADER), header->data_offset);
133 |
134 | //Make sure data is 16 aligned
135 | chk_size = header->data_size;
136 | if(chk_size % 16) chk_size += 16 - (chk_size % 16);
137 |
138 | //ENCRYPT DATA
139 | AES_set_key(&k1, keys->AES, 128);
140 | AES_cbc_encrypt(&k1, inbuff+sizeof(KIRK_CMD1_HEADER)+header->data_offset, (u8*)outbuff+sizeof(KIRK_CMD1_HEADER)+header->data_offset, chk_size);
141 |
142 | //CMAC HASHES
143 | AES_set_key(&cmac_key, keys->CMAC, 128);
144 | AES_CMAC(&cmac_key, outbuff+0x60, 0x30, cmac_header_hash);
145 | AES_CMAC(&cmac_key, outbuff+0x60, 0x30 + chk_size + header->data_offset, cmac_data_hash);
146 |
147 | memcpy(header->CMAC_header_hash, cmac_header_hash, 16);
148 | memcpy(header->CMAC_data_hash, cmac_data_hash, 16);
149 |
150 | //ENCRYPT KEYS
151 | AES_cbc_encrypt(&aes_kirk1, inbuff, outbuff, 16*2);
152 | return KIRK_OPERATION_SUCCESS;
153 | }
154 |
155 | int kirk_CMD1(u8* outbuff, u8* inbuff, int size)
156 | {
157 | KIRK_CMD1_HEADER* header = (KIRK_CMD1_HEADER*)inbuff;
158 | header_keys keys; //0-15 AES key, 16-31 CMAC key
159 | AES_ctx k1;
160 |
161 | if(size < 0x90) return KIRK_INVALID_SIZE;
162 | if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
163 | if(header->mode != KIRK_MODE_CMD1) return KIRK_INVALID_MODE;
164 |
165 | AES_cbc_decrypt(&aes_kirk1, inbuff, (u8*)&keys, 16*2); //decrypt AES & CMAC key to temp buffer
166 |
167 | if(header->ecdsa_hash == 1)
168 | {
169 | SHA_CTX sha;
170 | KIRK_CMD1_ECDSA_HEADER* eheader = (KIRK_CMD1_ECDSA_HEADER*) inbuff;
171 | u8 kirk1_pub[40];
172 | u8 header_hash[20];u8 data_hash[20];
173 | ecdsa_set_curve(ec_p,ec_a,ec_b1,ec_N1,Gx1,Gy1);
174 | memcpy(kirk1_pub,Px1,20);
175 | memcpy(kirk1_pub+20,Py1,20);
176 | ecdsa_set_pub(kirk1_pub);
177 | //Hash the Header
178 | SHAInit(&sha);
179 | SHAUpdate(&sha, (u8*)eheader+0x60, 0x30);
180 | SHAFinal(header_hash, &sha);
181 |
182 | if(!ecdsa_verify(header_hash,eheader->header_sig_r,eheader->header_sig_s)) {
183 | return KIRK_HEADER_HASH_INVALID;
184 | }
185 | SHAInit(&sha);
186 | SHAUpdate(&sha, (u8*)eheader+0x60, size-0x60);
187 | SHAFinal(data_hash, &sha);
188 |
189 | if(!ecdsa_verify(data_hash,eheader->data_sig_r,eheader->data_sig_s)) {
190 | return KIRK_DATA_HASH_INVALID;
191 | }
192 |
193 | } else {
194 | int ret = kirk_CMD10(inbuff, size);
195 | if(ret != KIRK_OPERATION_SUCCESS) return ret;
196 | }
197 |
198 | AES_set_key(&k1, keys.AES, 128);
199 | AES_cbc_decrypt(&k1, inbuff+sizeof(KIRK_CMD1_HEADER)+header->data_offset, outbuff, header->data_size);
200 |
201 | return KIRK_OPERATION_SUCCESS;
202 | }
203 |
204 | int kirk_CMD4(u8* outbuff, u8* inbuff, int size)
205 | {
206 | KIRK_AES128CBC_HEADER *header = (KIRK_AES128CBC_HEADER*)inbuff;
207 | u8* key;
208 | AES_ctx aesKey;
209 |
210 | if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
211 | if(header->mode != KIRK_MODE_ENCRYPT_CBC) return KIRK_INVALID_MODE;
212 | if(header->data_size == 0) return KIRK_DATA_SIZE_ZERO;
213 |
214 | key = kirk_4_7_get_key(header->keyseed);
215 | if(key == (u8*)KIRK_INVALID_SIZE) return KIRK_INVALID_SIZE;
216 |
217 | //Set the key
218 | AES_set_key(&aesKey, key, 128);
219 | AES_cbc_encrypt(&aesKey, inbuff+sizeof(KIRK_AES128CBC_HEADER), outbuff+sizeof(KIRK_AES128CBC_HEADER), size);
220 |
221 | return KIRK_OPERATION_SUCCESS;
222 | }
223 |
224 | int kirk_CMD7(u8* outbuff, u8* inbuff, int size)
225 | {
226 | KIRK_AES128CBC_HEADER *header = (KIRK_AES128CBC_HEADER*)inbuff;
227 | u8* key;
228 | AES_ctx aesKey;
229 |
230 | if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
231 | if(header->mode != KIRK_MODE_DECRYPT_CBC) return KIRK_INVALID_MODE;
232 | if(header->data_size == 0) return KIRK_DATA_SIZE_ZERO;
233 |
234 | key = kirk_4_7_get_key(header->keyseed);
235 | if(key == (u8*)KIRK_INVALID_SIZE) return KIRK_INVALID_SIZE;
236 |
237 | //Set the key
238 | AES_set_key(&aesKey, key, 128);
239 | AES_cbc_decrypt(&aesKey, inbuff+sizeof(KIRK_AES128CBC_HEADER), outbuff, size);
240 |
241 | return KIRK_OPERATION_SUCCESS;
242 | }
243 |
244 | int kirk_CMD10(u8* inbuff, int insize)
245 | {
246 | KIRK_CMD1_HEADER* header = (KIRK_CMD1_HEADER*)inbuff;
247 | header_keys keys; //0-15 AES key, 16-31 CMAC key
248 | u8 cmac_header_hash[16];
249 | u8 cmac_data_hash[16];
250 | AES_ctx cmac_key;
251 | int chk_size;
252 |
253 | if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
254 | if(!(header->mode == KIRK_MODE_CMD1 || header->mode == KIRK_MODE_CMD2 || header->mode == KIRK_MODE_CMD3)) return KIRK_INVALID_MODE;
255 | if(header->data_size == 0) return KIRK_DATA_SIZE_ZERO;
256 |
257 | if(header->mode == KIRK_MODE_CMD1)
258 | {
259 | AES_cbc_decrypt(&aes_kirk1, inbuff, (u8*)&keys, 32); //decrypt AES & CMAC key to temp buffer
260 | AES_set_key(&cmac_key, keys.CMAC, 128);
261 | AES_CMAC(&cmac_key, inbuff+0x60, 0x30, cmac_header_hash);
262 |
263 | //Make sure data is 16 aligned
264 | chk_size = header->data_size;
265 | if(chk_size % 16) chk_size += 16 - (chk_size % 16);
266 | AES_CMAC(&cmac_key, inbuff+0x60, 0x30 + chk_size + header->data_offset, cmac_data_hash);
267 |
268 | if(memcmp(cmac_header_hash, header->CMAC_header_hash, 16) != 0) return KIRK_HEADER_HASH_INVALID;
269 | if(memcmp(cmac_data_hash, header->CMAC_data_hash, 16) != 0) return KIRK_DATA_HASH_INVALID;
270 |
271 | return KIRK_OPERATION_SUCCESS;
272 | }
273 | return KIRK_SIG_CHECK_INVALID; //Checks for cmd 2 & 3 not included right now
274 | }
275 |
276 | int kirk_CMD11(u8* outbuff, u8* inbuff, int size)
277 | {
278 | KIRK_SHA1_HEADER *header = (KIRK_SHA1_HEADER *)inbuff;
279 | SHA_CTX sha;
280 | if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
281 | if(header->data_size == 0 || size == 0) return KIRK_DATA_SIZE_ZERO;
282 |
283 | SHAInit(&sha);
284 | SHAUpdate(&sha, inbuff+sizeof(KIRK_SHA1_HEADER), header->data_size);
285 | SHAFinal(outbuff, &sha);
286 | return KIRK_OPERATION_SUCCESS;
287 | }
288 |
289 | // Generate an ECDSA Key pair
290 | // offset 0 = private key (0x14 len)
291 | // offset 0x14 = public key point (0x28 len)
292 | int kirk_CMD12(u8 * outbuff, int outsize) {
293 | u8 k[0x15];
294 | KIRK_CMD12_BUFFER * keypair = (KIRK_CMD12_BUFFER *) outbuff;
295 |
296 | if(outsize != 0x3C) return KIRK_INVALID_SIZE;
297 | ecdsa_set_curve(ec_p,ec_a,ec_b2,ec_N2,Gx2,Gy2);
298 | k[0] = 0;
299 | kirk_CMD14(k+1,0x14);
300 | ec_priv_to_pub(k, (u8*)keypair->public_key.x);
301 | memcpy(keypair->private_key,k+1,0x14);
302 |
303 | return KIRK_OPERATION_SUCCESS;
304 | }
305 | // Point multiplication
306 | // offset 0 = mulitplication value (0x14 len)
307 | // offset 0x14 = point to multiply (0x28 len)
308 | int kirk_CMD13(u8 * outbuff, int outsize,u8 * inbuff, int insize) {
309 | u8 k[0x15];
310 | KIRK_CMD13_BUFFER * pointmult = (KIRK_CMD13_BUFFER *) inbuff;
311 | k[0]=0;
312 | if(outsize != 0x28) return KIRK_INVALID_SIZE;
313 | if(insize != 0x3C) return KIRK_INVALID_SIZE;
314 | ecdsa_set_curve(ec_p,ec_a,ec_b2,ec_N2,Gx2,Gy2);
315 | ecdsa_set_pub((u8*)pointmult->public_key.x);
316 | memcpy(k+1,pointmult->multiplier,0x14);
317 | ec_pub_mult(k, outbuff);
318 | return KIRK_OPERATION_SUCCESS;
319 | }
320 |
321 | int kirk_CMD14(u8 * outbuff, int outsize) {
322 | u8 temp[0x104];
323 | KIRK_SHA1_HEADER *header = (KIRK_SHA1_HEADER *) temp;
324 |
325 | // Some randomly selected data for a "key" to add to each randomization
326 | u8 key[0x10] = { 0xA7, 0x2E, 0x4C, 0xB6, 0xC3, 0x34, 0xDF, 0x85, 0x70, 0x01, 0x49, 0xFC, 0xC0, 0x87, 0xC4, 0x77 };
327 | u32 curtime;
328 | //if(outsize != 0x14) return KIRK_INVALID_SIZE; // Need real error code
329 | if(outsize <=0) return KIRK_OPERATION_SUCCESS;
330 |
331 | memcpy(temp+4, PRNG_DATA,0x14);
332 | // This uses the standard C time function for portability.
333 | curtime=(u32)time(0);
334 | temp[0x18] = curtime &0xFF;
335 | temp[0x19] = (curtime>>8) &0xFF;
336 | temp[0x1A] = (curtime>>16) &0xFF;
337 | temp[0x1B] = (curtime>>24) &0xFF;
338 | memcpy(&temp[0x1C], key, 0x10);
339 | //This leaves the remainder of the 0x100 bytes in temp to whatever remains on the stack
340 | // in an uninitialized state. This should add unpredicableness to the results as well
341 | header->data_size=0x100;
342 | kirk_CMD11(PRNG_DATA, temp, 0x104);
343 | while(outsize)
344 | {
345 | int blockrem= outsize %0x14;
346 | int block = outsize /0x14;
347 |
348 | if(block)
349 | {
350 | memcpy(outbuff, PRNG_DATA, 0x14);
351 | outbuff+=0x14;
352 | outsize -= 0x14;
353 | kirk_CMD14(outbuff, outsize);
354 | } else {
355 | if(blockrem)
356 | {
357 | memcpy(outbuff, PRNG_DATA, blockrem);
358 | outsize -= blockrem;
359 | }
360 | }
361 |
362 | }
363 | return KIRK_OPERATION_SUCCESS;
364 | }
365 |
366 | void decrypt_kirk16_private(u8 *dA_out, u8 *dA_enc)
367 | {
368 | int i, k;
369 | kirk16_data keydata;
370 | u8 subkey_1[0x10], subkey_2[0x10];
371 | rijndael_ctx aes_ctx;
372 |
373 | keydata.fuseid[7] = g_fuse90 &0xFF;
374 | keydata.fuseid[6] = (g_fuse90>>8) &0xFF;
375 | keydata.fuseid[5] = (g_fuse90>>16) &0xFF;
376 | keydata.fuseid[4] = (g_fuse90>>24) &0xFF;
377 | keydata.fuseid[3] = g_fuse94 &0xFF;
378 | keydata.fuseid[2] = (g_fuse94>>8) &0xFF;
379 | keydata.fuseid[1] = (g_fuse94>>16) &0xFF;
380 | keydata.fuseid[0] = (g_fuse94>>24) &0xFF;
381 |
382 | /* set encryption key */
383 | rijndael_set_key(&aes_ctx, kirk16_key, 128);
384 |
385 | /* set the subkeys */
386 | for (i = 0; i < 0x10; i++)
387 | {
388 | /* set to the fuseid */
389 | subkey_2[i] = subkey_1[i] = keydata.fuseid[i % 8];
390 | }
391 |
392 | /* do aes crypto */
393 | for (i = 0; i < 3; i++)
394 | {
395 | /* encrypt + decrypt */
396 | rijndael_encrypt(&aes_ctx, subkey_1, subkey_1);
397 | rijndael_decrypt(&aes_ctx, subkey_2, subkey_2);
398 | }
399 |
400 | /* set new key */
401 | rijndael_set_key(&aes_ctx, subkey_1, 128);
402 |
403 | /* now lets make the key mesh */
404 | for (i = 0; i < 3; i++)
405 | {
406 | /* do encryption in group of 3 */
407 | for (k = 0; k < 3; k++)
408 | {
409 | /* crypto */
410 | rijndael_encrypt(&aes_ctx, subkey_2, subkey_2);
411 | }
412 |
413 | /* copy to out block */
414 | memcpy(&keydata.mesh[i * 0x10], subkey_2, 0x10);
415 | }
416 |
417 | /* set the key to the mesh */
418 | rijndael_set_key(&aes_ctx, &keydata.mesh[0x20], 128);
419 |
420 | /* do the encryption routines for the aes key */
421 | for (i = 0; i < 2; i++)
422 | {
423 | /* encrypt the data */
424 | rijndael_encrypt(&aes_ctx, &keydata.mesh[0x10], &keydata.mesh[0x10]);
425 | }
426 |
427 | /* set the key to that mesh shit */
428 | rijndael_set_key(&aes_ctx, &keydata.mesh[0x10], 128);
429 |
430 | /* cbc decrypt the dA */
431 | AES_cbc_decrypt((AES_ctx *)&aes_ctx, dA_enc, dA_out, 0x20);
432 | }
433 |
434 | void encrypt_kirk16_private(u8 *dA_out, u8 *dA_dec)
435 | {
436 | int i, k;
437 | kirk16_data keydata;
438 | u8 subkey_1[0x10], subkey_2[0x10];
439 | rijndael_ctx aes_ctx;
440 |
441 |
442 | keydata.fuseid[7] = g_fuse90 &0xFF;
443 | keydata.fuseid[6] = (g_fuse90>>8) &0xFF;
444 | keydata.fuseid[5] = (g_fuse90>>16) &0xFF;
445 | keydata.fuseid[4] = (g_fuse90>>24) &0xFF;
446 | keydata.fuseid[3] = g_fuse94 &0xFF;
447 | keydata.fuseid[2] = (g_fuse94>>8) &0xFF;
448 | keydata.fuseid[1] = (g_fuse94>>16) &0xFF;
449 | keydata.fuseid[0] = (g_fuse94>>24) &0xFF;
450 | /* set encryption key */
451 | rijndael_set_key(&aes_ctx, kirk16_key, 128);
452 |
453 | /* set the subkeys */
454 | for (i = 0; i < 0x10; i++)
455 | {
456 | /* set to the fuseid */
457 | subkey_2[i] = subkey_1[i] = keydata.fuseid[i % 8];
458 | }
459 |
460 | /* do aes crypto */
461 | for (i = 0; i < 3; i++)
462 | {
463 | /* encrypt + decrypt */
464 | rijndael_encrypt(&aes_ctx, subkey_1, subkey_1);
465 | rijndael_decrypt(&aes_ctx, subkey_2, subkey_2);
466 | }
467 |
468 | /* set new key */
469 | rijndael_set_key(&aes_ctx, subkey_1, 128);
470 |
471 | /* now lets make the key mesh */
472 | for (i = 0; i < 3; i++)
473 | {
474 | /* do encryption in group of 3 */
475 | for (k = 0; k < 3; k++)
476 | {
477 | /* crypto */
478 | rijndael_encrypt(&aes_ctx, subkey_2, subkey_2);
479 | }
480 |
481 | /* copy to out block */
482 | memcpy(&keydata.mesh[i * 0x10], subkey_2, 0x10);
483 | }
484 |
485 | /* set the key to the mesh */
486 | rijndael_set_key(&aes_ctx, &keydata.mesh[0x20], 128);
487 |
488 | /* do the encryption routines for the aes key */
489 | for (i = 0; i < 2; i++)
490 | {
491 | /* encrypt the data */
492 | rijndael_encrypt(&aes_ctx, &keydata.mesh[0x10], &keydata.mesh[0x10]);
493 | }
494 |
495 | /* set the key to that mesh shit */
496 | rijndael_set_key(&aes_ctx, &keydata.mesh[0x10], 128);
497 |
498 | /* cbc encrypt the dA */
499 | AES_cbc_encrypt((AES_ctx *)&aes_ctx, dA_dec, dA_out, 0x20);
500 | }
501 |
502 | int kirk_CMD16(u8 * outbuff, int outsize, u8 * inbuff, int insize) {
503 | u8 dec_private[0x20];
504 | KIRK_CMD16_BUFFER * signbuf = (KIRK_CMD16_BUFFER *) inbuff;
505 | ECDSA_SIG * sig = (ECDSA_SIG *) outbuff;
506 | if(insize != 0x34) return KIRK_INVALID_SIZE;
507 | if(outsize != 0x28) return KIRK_INVALID_SIZE;
508 | decrypt_kirk16_private(dec_private,signbuf->enc_private);
509 | // Clear out the padding for safety
510 | memset(&dec_private[0x14], 0, 0xC);
511 | ecdsa_set_curve(ec_p,ec_a,ec_b2,ec_N2,Gx2,Gy2);
512 | ecdsa_set_priv(dec_private);
513 | ecdsa_sign(signbuf->message_hash,sig->r, sig->s);
514 | return KIRK_OPERATION_SUCCESS;
515 | }
516 |
517 | // ECDSA Verify
518 | // inbuff structure:
519 | // 00 = public key (0x28 length)
520 | // 28 = message hash (0x14 length)
521 | // 3C = signature R (0x14 length)
522 | // 50 = signature S (0x14 length)
523 | int kirk_CMD17(u8 * inbuff, int insize) {
524 | KIRK_CMD17_BUFFER * sig = (KIRK_CMD17_BUFFER *) inbuff;
525 | if(insize != 0x64) return KIRK_INVALID_SIZE;
526 | ecdsa_set_curve(ec_p,ec_a,ec_b2,ec_N2,Gx2,Gy2);
527 | ecdsa_set_pub(sig->public_key.x);
528 | // ecdsa_verify(u8 *hash, u8 *R, u8 *S)
529 | if(ecdsa_verify(sig->message_hash,sig->signature.r,sig->signature.s)) {
530 | return KIRK_OPERATION_SUCCESS;
531 | } else {
532 | return KIRK_SIG_CHECK_INVALID;
533 | }
534 | }
535 |
536 |
537 |
538 | int kirk_init()
539 | {
540 | return kirk_init2((u8*)"Lazy Dev should have initialized!",33,0xBABEF00D, 0xDEADBEEF );
541 | }
542 |
543 | int kirk_init2(u8 * rnd_seed, u32 seed_size, u32 fuseid_90, u32 fuseid_94) {
544 | u8 temp[0x104];
545 |
546 | KIRK_SHA1_HEADER *header = (KIRK_SHA1_HEADER *) temp;
547 | // Another randomly selected data for a "key" to add to each randomization
548 | u8 key[0x10] = {0x07, 0xAB, 0xEF, 0xF8, 0x96, 0x8C, 0xF3, 0xD6, 0x14, 0xE0, 0xEB, 0xB2, 0x9D, 0x8B, 0x4E, 0x74};
549 | u32 curtime;
550 |
551 | //Set PRNG_DATA initially, otherwise use what ever uninitialized data is in the buffer
552 | if(seed_size > 0) {
553 | u8 * seedbuf;
554 | KIRK_SHA1_HEADER *seedheader;;
555 | seedbuf=(u8*)malloc(seed_size+4);
556 | seedheader= (KIRK_SHA1_HEADER *) seedbuf;
557 | seedheader->data_size = seed_size;
558 | kirk_CMD11(PRNG_DATA, seedbuf, seed_size+4);
559 | free(seedbuf);
560 | }
561 | memcpy(temp+4, PRNG_DATA,0x14);
562 | // This uses the standard C time function for portability.
563 | curtime=(u32)time(0);
564 | temp[0x18] = curtime &0xFF;
565 | temp[0x19] = (curtime>>8) &0xFF;
566 | temp[0x1A] = (curtime>>16) &0xFF;
567 | temp[0x1B] = (curtime>>24) &0xFF;
568 | memcpy(&temp[0x1C], key, 0x10);
569 | //This leaves the remainder of the 0x100 bytes in temp to whatever remains on the stack
570 | // in an uninitialized state. This should add unpredicableness to the results as well
571 | header->data_size=0x100;
572 | kirk_CMD11(PRNG_DATA, temp, 0x104);
573 |
574 | //Set Fuse ID
575 | g_fuse90=fuseid_90;
576 | g_fuse94=fuseid_94;
577 |
578 | //Set KIRK1 main key
579 | AES_set_key(&aes_kirk1, kirk1_key, 128);
580 |
581 |
582 | is_kirk_initialized = 1;
583 | return 0;
584 | }
585 | u8* kirk_4_7_get_key(int key_type)
586 | {
587 | switch(key_type)
588 | {
589 | case(0x02): return kirk7_key02; break;
590 | case(0x03): return kirk7_key03; break;
591 | case(0x04): return kirk7_key04; break;
592 | case(0x05): return kirk7_key05; break;
593 | case(0x07): return kirk7_key07; break;
594 | case(0x0C): return kirk7_key0C; break;
595 | case(0x0D): return kirk7_key0D; break;
596 | case(0x0E): return kirk7_key0E; break;
597 | case(0x0F): return kirk7_key0F; break;
598 | case(0x10): return kirk7_key10; break;
599 | case(0x11): return kirk7_key11; break;
600 | case(0x12): return kirk7_key12; break;
601 | case(0x38): return kirk7_key38; break;
602 | case(0x39): return kirk7_key39; break;
603 | case(0x3A): return kirk7_key3A; break;
604 | case(0x44): return kirk7_key44; break;
605 | case(0x4B): return kirk7_key4B; break;
606 | case(0x53): return kirk7_key53; break;
607 | case(0x57): return kirk7_key57; break;
608 | case(0x5D): return kirk7_key5D; break;
609 | case(0x63): return kirk7_key63; break;
610 | case(0x64): return kirk7_key64; break;
611 | default: return (u8*)KIRK_INVALID_SIZE; break; //need to get the real error code for that, placeholder now :)
612 | }
613 | }
614 |
615 | int kirk_CMD1_ex(u8* outbuff, u8* inbuff, int size, KIRK_CMD1_HEADER* header)
616 | {
617 | u8* buffer = (u8*)malloc(size);
618 | int ret;
619 |
620 | memcpy(buffer, header, sizeof(KIRK_CMD1_HEADER));
621 | memcpy(buffer+sizeof(KIRK_CMD1_HEADER), inbuff, header->data_size);
622 |
623 | ret = kirk_CMD1(outbuff, buffer, size);
624 | free(buffer);
625 | return ret;
626 | }
627 |
628 |
629 | int sceUtilsBufferCopyWithRange(u8* outbuff, int outsize, u8* inbuff, int insize, int cmd)
630 | {
631 | switch(cmd)
632 | {
633 | case KIRK_CMD_DECRYPT_PRIVATE: return kirk_CMD1(outbuff, inbuff, insize); break;
634 | case KIRK_CMD_ENCRYPT_IV_0: return kirk_CMD4(outbuff, inbuff, insize); break;
635 | case KIRK_CMD_DECRYPT_IV_0: return kirk_CMD7(outbuff, inbuff, insize); break;
636 | case KIRK_CMD_PRIV_SIGN_CHECK: return kirk_CMD10(inbuff, insize); break;
637 | case KIRK_CMD_SHA1_HASH: return kirk_CMD11(outbuff, inbuff, insize); break;
638 | case KIRK_CMD_ECDSA_GEN_KEYS: return kirk_CMD12(outbuff,outsize); break;
639 | case KIRK_CMD_ECDSA_MULTIPLY_POINT: return kirk_CMD13(outbuff,outsize, inbuff, insize); break;
640 | case KIRK_CMD_PRNG: return kirk_CMD14(outbuff,outsize); break;
641 | case KIRK_CMD_ECDSA_SIGN: return kirk_CMD16(outbuff, outsize, inbuff, insize); break;
642 | case KIRK_CMD_ECDSA_VERIFY: return kirk_CMD17(inbuff, insize); break;
643 | }
644 | return -1;
645 | }
646 |
--------------------------------------------------------------------------------
/src/libkirk/kirk_engine.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/has207/psxtract-2/558e7da132f79d126dc6e94ccd63548f605a6ffc/src/libkirk/kirk_engine.h
--------------------------------------------------------------------------------
/src/lz.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 Hykem
2 | // Licensed under the terms of the GNU GPL, version 3
3 | // http://www.gnu.org/licenses/gpl-3.0.txt
4 |
5 | #include "lz.h"
6 |
7 | int decode_range(unsigned int *range, unsigned int *code, unsigned char **src)
8 | {
9 | if (!((*range) >> 24))
10 | {
11 | (*range) <<= 8;
12 | *code = ((*code) << 8) + (*src)++[5];
13 | return 1;
14 | }
15 | else
16 | return 0;
17 | }
18 |
19 | int decode_bit(unsigned int *range, unsigned int *code, int *index, unsigned char **src, unsigned char *c)
20 | {
21 | unsigned int val = *range;
22 |
23 | if (decode_range(range, code, src))
24 | val *= (*c);
25 | else
26 | val = (val >> 8) * (*c);
27 |
28 | *c -= ((*c) >> 3);
29 | if (index) (*index) <<= 1;
30 |
31 | if (*code < val)
32 | {
33 | *range = val;
34 | *c += 31;
35 | if (index) (*index)++;
36 | return 1;
37 | }
38 | else
39 | {
40 | *code -= val;
41 | *range -= val;
42 | return 0;
43 | }
44 | }
45 |
46 | int decode_number(unsigned char *ptr, int index, int *bit_flag, unsigned int *range, unsigned int *code, unsigned char **src)
47 | {
48 | int i = 1;
49 |
50 | if (index >= 3)
51 | {
52 | decode_bit(range, code, &i, src, ptr + 0x18); // Offset 0x978
53 | if (index >= 4)
54 | {
55 | decode_bit(range, code, &i, src, ptr + 0x18); // Offset 0x978
56 | if (index >= 5)
57 | {
58 | decode_range(range, code, src);
59 | for (; index >= 5; index--)
60 | {
61 | i <<= 1;
62 | (*range) >>= 1;
63 | if (*code < *range)
64 | i++;
65 | else
66 | (*code) -= *range;
67 | }
68 | }
69 | }
70 | }
71 |
72 | *bit_flag = decode_bit(range, code, &i, src, ptr); // Offset 0x960
73 |
74 | if (index >= 1)
75 | {
76 | decode_bit(range, code, &i, src, ptr + 0x8); // Offset 0x968
77 | if (index >= 2)
78 | {
79 | decode_bit(range, code, &i, src, ptr + 0x10); // Offset 0x970
80 | }
81 | }
82 |
83 | return i;
84 | }
85 |
86 | int decode_word(unsigned char *ptr, int index, int *bit_flag, unsigned int *range, unsigned int *code, unsigned char **src)
87 | {
88 | int i = 1;
89 | index /= 8;
90 |
91 | if (index >= 3)
92 | {
93 | decode_bit(range, code, &i, src, ptr); // Offset 0x8A8
94 | if (index >= 4)
95 | {
96 | decode_bit(range, code, &i, src, ptr); // Offset 0x8A8
97 | if (index >= 5)
98 | {
99 | decode_range(range, code, src);
100 | for (; index >= 5; index--)
101 | {
102 | i <<= 1;
103 | (*range) >>= 1;
104 | if (*code < *range)
105 | i++;
106 | else
107 | (*code) -= *range;
108 | }
109 | }
110 | }
111 | }
112 |
113 | *bit_flag = decode_bit(range, code, &i, src, ptr + 3); // Offset 0x8A8 + 3
114 |
115 | if (index >= 1)
116 | {
117 | decode_bit(range, code, &i, src, ptr + 2); // Offset 0x8A8 + 2
118 | if (index >= 2)
119 | {
120 | decode_bit(range, code, &i, src, ptr + 1); // Offset 0x8A8 + 1
121 | }
122 | }
123 |
124 | return i;
125 | }
126 |
127 | int decompress(unsigned char *out, unsigned char *in, unsigned int size)
128 | {
129 | int result;
130 |
131 | unsigned char *tmp = new unsigned char[0xA70];
132 |
133 | int offset = 0;
134 | int bit_flag = 0;
135 | int data_length = 0;
136 | int data_offset = 0;
137 |
138 | unsigned char *tmp_sect1, *tmp_sect2, *tmp_sect3;
139 | unsigned char *buf_start, *buf_end;
140 | unsigned char prev = 0;
141 |
142 | unsigned char *start = out;
143 | unsigned char *end = (out + size);
144 | unsigned char head = in[0];
145 |
146 | unsigned int range = 0xFFFFFFFF;
147 | unsigned int code = (in[1] << 24) | (in[2] << 16) | (in[3] << 8) | in[4];
148 |
149 | if (head < 0) // Check if we have a valid starting byte.
150 | {
151 | // The dictionary header is invalid, the data is not compressed.
152 | result = -1;
153 | if (code <= size)
154 | {
155 | memcpy(out, (const void *)(in + 5), code);
156 | result = (start - out);
157 | }
158 | }
159 | else
160 | {
161 | // Set up a temporary buffer (sliding window).
162 | memset(tmp, 0x80, 0xA60);
163 | while (1)
164 | {
165 | // Start reading at 0x920.
166 | tmp_sect1 = tmp + offset + 0x920;
167 | if (!decode_bit(&range, &code, 0, &in, tmp_sect1)) // Raw char.
168 | {
169 | // Adjust offset and check for stream end.
170 | if (offset > 0) offset--;
171 | if (start == end) return (start - out);
172 |
173 | // Locate first section.
174 | int sect = (((((((int)(start - out)) & 7) << 8) + prev) >> head) & 7) * 0xFF - 1;
175 | tmp_sect1 = tmp + sect;
176 | int index = 1;
177 |
178 | // Read, decode and write back.
179 | do
180 | {
181 | decode_bit(&range, &code, &index, &in, tmp_sect1 + index);
182 | } while ((index >> 8) == 0);
183 |
184 | // Save index.
185 | *start++ = index;
186 | }
187 | else // Compressed char stream.
188 | {
189 | int index = -1;
190 |
191 | // Identify the data length bit field.
192 | do {
193 | tmp_sect1 += 8;
194 | bit_flag = decode_bit(&range, &code, 0, &in, tmp_sect1);
195 | index += bit_flag;
196 | } while ((bit_flag != 0) && (index < 6));
197 |
198 | // Default block size is 0x40.
199 | int b_size = 0x40;
200 | tmp_sect2 = tmp + index + 0x7F1;
201 |
202 | // If the data length was found, parse it as a number.
203 | if ((index >= 0) || (bit_flag != 0))
204 | {
205 | // Locate next section.
206 | int sect = (index << 5) | (((((int)(start - out)) << index) & 3) << 3) | (offset & 7);
207 | tmp_sect1 = tmp + 0x960 + sect;
208 |
209 | // Decode the data length (8 bit fields).
210 | data_length = decode_number(tmp_sect1, index, &bit_flag, &range, &code, &in);
211 |
212 | // If we got valid parameters, seek to find data offset.
213 | if ((data_length != 3) && ((index > 0) || (bit_flag != 0))) {
214 | tmp_sect2 += 0x38;
215 | b_size = 0x80; // Block size is now 0x80.
216 | }
217 | } else {
218 | // Assume one byte of advance.
219 | data_length = 1;
220 | }
221 |
222 | int diff = 0;
223 | int shift = 1;
224 |
225 | // Identify the data offset bit field.
226 | do {
227 | diff = (shift << 4) - b_size;
228 | bit_flag = decode_bit(&range, &code, &shift, &in, tmp_sect2 + (shift << 3));
229 | } while (diff < 0);
230 |
231 | // If the data offset was found, parse it as a number.
232 | if ((diff > 0) || (bit_flag != 0))
233 | {
234 | // Adjust diff if needed.
235 | if (bit_flag == 0) diff -= 8;
236 |
237 | // Locate section.
238 | tmp_sect3 = tmp + 0x8A8 + diff;
239 |
240 | // Decode the data offset (1 bit fields).
241 | data_offset = decode_word(tmp_sect3, diff, &bit_flag, &range, &code, &in);
242 | } else {
243 | // Assume one byte of advance.
244 | data_offset = 1;
245 | }
246 |
247 | // Set buffer start/end.
248 | buf_start = start - data_offset;
249 | buf_end = start + data_length + 1;
250 |
251 | // Underflow.
252 | if (buf_start < out)
253 | return -1;
254 |
255 | // Overflow.
256 | if (buf_end > end)
257 | return -1;
258 |
259 | // Update offset.
260 | offset = ((((int)(buf_end - out)) + 1) & 1) + 6;
261 |
262 | // Copy data.
263 | do {
264 | *start++ = *buf_start++;
265 | } while (start < buf_end);
266 |
267 | }
268 | prev = *(start - 1);
269 | }
270 | result = (start - out);
271 | }
272 | delete[] tmp;
273 | return result;
274 | }
--------------------------------------------------------------------------------
/src/lz.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 Hykem
2 | // Licensed under the terms of the GNU GPL, version 3
3 | // http://www.gnu.org/licenses/gpl-3.0.txt
4 |
5 | // Reverse-engineered custom Lempel–Ziv–Markov based compression (unknown variant of LZRC).
6 |
7 | #include
8 |
9 | int decode_range(unsigned int *range, unsigned int *code, unsigned char **src);
10 | int decode_bit(unsigned int *range, unsigned int *code, int *index, unsigned char **src, unsigned char *c);
11 | int decode_number(unsigned char *ptr, int index, int *bit_flag, unsigned int *range, unsigned int *code, unsigned char **src);
12 | int decode_word(unsigned char *ptr, int index, int *bit_flag, unsigned int *range, unsigned int *code, unsigned char **src);
13 | int decompress(unsigned char *out, unsigned char *in, unsigned int size);
--------------------------------------------------------------------------------
/src/psxtract.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 Hykem
2 | // Licensed under the terms of the GNU GPL, version 3
3 | // http://www.gnu.org/licenses/gpl-3.0.txt
4 |
5 | #define _CRT_SECURE_NO_WARNINGS
6 |
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | #include "cdrom.h"
13 | #include "lz.h"
14 | #include "crypto.h"
15 |
16 | #define GAP_FRAMES 2 * 75 // 2 seconds
17 | #define GAP_SIZE GAP_FRAMES * SECTOR_SIZE // 2 seconds * 75 frames * 2352 sector size
18 | #define ISO_BLOCK_SIZE 16 * SECTOR_SIZE
19 | #define ISO_HEADER_OFFSET 0x400
20 | #define ISO_HEADER_SIZE 0xB6600
21 | #define ISO_BASE_OFFSET 0x100000
22 | #define CUE_LEADOUT_OFFSET 0x414
23 | #define MAX_DISCS 5
24 | #define NBYTES 0x180
25 |
26 | // Multidisc ISO image signature.
27 | char multi_iso_magic[0x10] = {
28 | 0x50, // P
29 | 0x53, // S
30 | 0x54, // T
31 | 0x49, // I
32 | 0x54, // T
33 | 0x4C, // L
34 | 0x45, // E
35 | 0x49, // I
36 | 0x4D, // M
37 | 0x47, // G
38 | 0x30, // 0
39 | 0x30, // 0
40 | 0x30, // 0
41 | 0x30, // 0
42 | 0x30, // 0
43 | 0x30 // 0
44 | };
45 |
46 | // ISO image signature.
47 | char iso_magic[0xC] = {
48 | 0x50, // P
49 | 0x53, // S
50 | 0x49, // I
51 | 0x53, // S
52 | 0x4F, // O
53 | 0x49, // I
54 | 0x4D, // M
55 | 0x47, // G
56 | 0x30, // 0
57 | 0x30, // 0
58 | 0x30, // 0
59 | 0x30 // 0
60 | };
61 |
62 | // CUE structure
63 | typedef struct {
64 | unsigned short type; // Track Type = 41h for DATA, 01h for CDDA, A2h for lead out
65 | unsigned char number; // Track Number (01h to 99h)
66 | unsigned char I0m; // INDEX 00 MM
67 | unsigned char I0s; // INDEX 00 SS
68 | unsigned char I0f; // INDEX 00 FF
69 | unsigned char padding; // NULL
70 | unsigned char I1m; // INDEX 01 MM
71 | unsigned char I1s; // INDEX 01 SS
72 | unsigned char I1f; // INDEX 01 FF
73 | } CUE_ENTRY;
74 |
75 | // CDDA table entry structure.
76 | typedef struct {
77 | unsigned int offset;
78 | unsigned int size;
79 | unsigned char padding[0x4];
80 | unsigned int checksum;
81 | } CDDA_ENTRY;
82 |
83 | // ISO table entry structure.
84 | typedef struct {
85 | unsigned int offset;
86 | unsigned short size;
87 | unsigned short marker; // 0x01 or 0x00
88 | unsigned char checksum[0x10]; // first 0x10 bytes of sha1 sum of 0x10 disc sectors
89 | unsigned char padding[0x8];
90 | } ISO_ENTRY;
91 |
92 | // STARTDAT header structure.
93 | typedef struct {
94 | unsigned char magic[8]; // STARTDAT
95 | unsigned int unk1; // 0x01
96 | unsigned int unk2; // 0x01
97 | unsigned int header_size;
98 | unsigned int data_size;
99 | } STARTDAT_HEADER;
100 |
101 | // ATRAC3 RIFF WAVE header structure.
102 | typedef struct {
103 | unsigned char riff_id[4]; // "RIFF"
104 | uint32_t riff_size; // size of rest of the file: audio + header - 8
105 | unsigned char riff_format[4]; // "WAVE"
106 | unsigned char fmt_id[4]; // "fmt\x20"
107 | uint32_t fmt_size; // size of format, always 32
108 | uint16_t codec_id; // always 624 (ATRAC3+?)
109 | uint16_t channels; // number of channels, always 2
110 | uint32_t sample_rate; // sample rate - always 44100
111 | uint32_t unknown1; // always 16538, seems connected to next value
112 | uint32_t bytes_per_frame; // always 384
113 | uint16_t param_size; // likely the length of remaining params, always 14
114 | uint16_t param1; // unknown, always 1
115 | uint16_t param2; // unknown, always 4096
116 | uint16_t param3; // unknown, always 0
117 | uint16_t param4; // unknown, always 0
118 | uint16_t param5; // unknown, always 0
119 | uint16_t param6; // unknown, always 1
120 | uint16_t param7; // unknown, always 0
121 | unsigned char fact_id[4]; // "fact"
122 | uint32_t fact_size; // always 8
123 | uint32_t fact_param1; // size of (in|out)put file sans 44byte WAVE header, divided by 4
124 | // we can get this by taking the track time in mm:ss:ff
125 | // convert to frames (mm*60*75 + ss*75 + ff)
126 | // and multiply by sector size 2352
127 | uint32_t fact_param2; // unknown, always 1024
128 | unsigned char data_id[4]; // "data"
129 | uint32_t data_size; // size of data segment
130 | } AT3_HEADER;
131 |
132 | // Pregap mapping
133 | typedef struct {
134 | int mm, ss, ff;
135 | } TIMESTAMP;
136 |
137 | typedef struct {
138 | const char* game_id;
139 | size_t num_tracks;
140 | TIMESTAMP timestamps[99];
141 | } PREGAP_OVERRIDE;
142 |
143 |
144 | // Game ID, number of audio tracks, timestamps for pregap on each, taken from redump.org
145 | // We calculate track 2 pregap automatically based on on diff with data track 1, but it's included here anyway though is not used
146 | static const PREGAP_OVERRIDE pregap_overrides [] = {
147 | // '99 Koushien
148 | { "SLPS_02110", 10, {{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00} }},
149 | // A.IV Evolution Global
150 | { "SCES_00290", 6, {{00 , 15, 26},{00 , 02, 18},{00 , 02, 26},{00 , 02, 43},{00 , 02, 06},{00 , 02, 42}} },
151 | // Bowling
152 | { "SLUS_01288", 14, {{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 02, 00}} },
153 | // Centipede (US)
154 | { "SLUS_00807", 14, {{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 04, 00}} },
155 | // Centipede (Eng, Spa, Swe)
156 | { "SLES_01664", 14, {{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 04, 00}} },
157 | // Centipede (Dut, Fra, Ger, Ita)
158 | { "SLES_01900", 14, {{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{03, 00, 00}} },
159 | // Dai-4-Ji Super Robot Taisen S
160 | { "SLPS_00196", 2, {{00 , 02, 00}, {03, 00, 00}} },
161 | // GTA - not sure which ID is used so account for both
162 | { "SLPM_87007", 10, {{00 , 02, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00}} },
163 | { "SLPS_01554", 10, {{00 , 02, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00}} },
164 | // Hanabi Fantast
165 | { "SLPS_01439", 22, {{00 , 05, 00},{00 , 05, 00},{00 , 05, 00},{00 , 05, 00},{00 , 05, 00},{00 , 05, 00},{00 , 05, 00},{00 , 04, 46},{00 , 04, 18},{00 , 04, 35},{00 , 04, 8},{00 , 04, 23},{00 , 04, 61},{00 , 04, 10},{00 , 05, 00},{00 , 05, 00},{00 , 05, 00},{00 , 05, 00},{00 , 05, 00},{00 , 05, 00},{00 , 05, 00},{00 , 05, 00}} },
166 | // Jet Copter X
167 | { "SLPM_86894", 9, {{00 , 02, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 02, 00},{00 , 02, 00}} },
168 | // KOF '96
169 | { "SLPS_00834", 40, {{00 , 06, 47},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 57},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00}} },
170 | // KOF Kyo
171 | { "SLPM_86095", 3, {{00 , 03, 00}, {00 , 02, 00}, {00 , 03, 00}} },
172 | // Koushien V
173 | { "SLPS_00729", 16, {{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00}} },
174 | // Motteke Tamago With Ganbare
175 | { "SLPS_01242", 22, {{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00},{00 , 03, 00}} },
176 | // Perfect Weapon (US)
177 | { "SLUS_00341", 15, {{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 04, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 04, 00},{00 , 02, 00},{00 , 02, 00},{00 , 28, 00}} },
178 | // Perfect Weapon (EU)
179 | { "SLES_00681", 15, {{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 04, 00},{00 , 02, 00},{00 , 02, 00},{00 , 28, 00}} },
180 | // Perfect Weapon (Fra)
181 | { "SLES_00685", 15, {{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 04, 00},{00 , 02, 00},{00 , 02, 00},{00 , 28, 00}} },
182 | // Perfect Weapon (Ger)
183 | { "SLES_00686", 15, {{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 04, 00},{00 , 02, 00},{00 , 02, 00},{00 , 28, 00}} },
184 | // Perfect Weapon (Ita)
185 | { "SLES_00687", 15, {{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 04, 00},{00 , 02, 00},{00 , 02, 00},{00 , 28, 00}} },
186 | // Touge Max Saisoku Drift Master - not sure which ID is used so account for all 3
187 | { "SCPS_45006", 11, {{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00}} },
188 | { "SLPS_00592", 11, {{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00}} },
189 | { "SLPS_91041", 11, {{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00},{00 , 04, 00}} },
190 | // Tsuukai!! Slot Shooting
191 | { "SLPS_00334", 11, {{00 , 02, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00},{00 , 01, 00}} },
192 | // Vib-Ribbon JP
193 | { "SCPS_18012", 7, {{00 , 04, 04},{00 , 02, 03},{00 , 02, 31},{00 , 02, 00},{00 , 02, 18},{00 , 02, 66},{00 , 02, 61}} },
194 | // Vib-Ribbon EU
195 | { "SCES_02873", 7, {{00 , 11, 8},{00 , 02, 03},{00 , 02, 31},{00 , 02, 00},{00 , 02, 18},{00 , 02, 66},{00 , 02, 61}} },
196 | //Yamasa Digi Guide Hyper Rush
197 | { "SLPS_02989", 10, {{00 , 03, 00},{00 , 03, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00},{00 , 02, 00}} },
198 | };
--------------------------------------------------------------------------------
/src/psxtract.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 | {B86E1508-26B6-465B-ABEC-A35E07E2A187}
15 | psxtract
16 | psxtract
17 |
18 |
19 |
20 | Application
21 | true
22 | v143
23 | MultiByte
24 |
25 |
26 | Application
27 | false
28 | v143
29 | true
30 | MultiByte
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | ..\bin
44 | psxtract.debug
45 |
46 |
47 | ..\bin
48 | psxtract
49 |
50 |
51 |
52 | Level3
53 | Disabled
54 | true
55 |
56 |
57 | true
58 |
59 |
60 |
61 |
62 | Level3
63 | MaxSpeed
64 | true
65 | true
66 | true
67 |
68 |
69 | true
70 | true
71 | true
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/src/psxtract.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 | {587a9468-22a3-4044-b7f3-87bb43cf8eb8}
18 |
19 |
20 |
21 |
22 | Source Files
23 |
24 |
25 | Source Files\libkirk
26 |
27 |
28 | Source Files\libkirk
29 |
30 |
31 | Source Files\libkirk
32 |
33 |
34 | Source Files\libkirk
35 |
36 |
37 | Source Files\libkirk
38 |
39 |
40 | Source Files\libkirk
41 |
42 |
43 | Source Files\libkirk
44 |
45 |
46 | Source Files
47 |
48 |
49 | Source Files
50 |
51 |
52 | Source Files
53 |
54 |
55 | Source Files
56 |
57 |
58 |
59 |
60 | Source Files
61 |
62 |
63 | Source Files\libkirk
64 |
65 |
66 | Source Files\libkirk
67 |
68 |
69 | Source Files\libkirk
70 |
71 |
72 | Source Files\libkirk
73 |
74 |
75 | Source Files\libkirk
76 |
77 |
78 | Source Files
79 |
80 |
81 | Source Files
82 |
83 |
84 | Source Files
85 |
86 |
87 | Header Files
88 |
89 |
90 |
--------------------------------------------------------------------------------
/src/psxtract.vcxproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/utils.cpp:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 Hykem
2 | // Licensed under the terms of the GNU GPL, version 3
3 | // http://www.gnu.org/licenses/gpl-3.0.txt
4 |
5 | #include "utils.h"
6 |
7 | bool isEmpty(unsigned char* buf, int buf_size)
8 | {
9 | if (buf != NULL)
10 | {
11 | int i;
12 | for(i = 0; i < buf_size; i++)
13 | {
14 | if (buf[i] != 0) return false;
15 | }
16 | }
17 | return true;
18 | }
19 |
20 | int se32(int i)
21 | {
22 | return ((i & 0xFF000000) >> 24) | ((i & 0xFF0000) >> 8) | ((i & 0xFF00) << 8) | ((i & 0xFF) << 24);
23 | }
24 |
25 | u64 se64(u64 i)
26 | {
27 | return ((i & 0x00000000000000ff) << 56) | ((i & 0x000000000000ff00) << 40) |
28 | ((i & 0x0000000000ff0000) << 24) | ((i & 0x00000000ff000000) << 8) |
29 | ((i & 0x000000ff00000000) >> 8) | ((i & 0x0000ff0000000000) >> 24) |
30 | ((i & 0x00ff000000000000) >> 40) | ((i & 0xff00000000000000) >> 56);
31 | }
--------------------------------------------------------------------------------
/src/utils.h:
--------------------------------------------------------------------------------
1 | // Copyright (C) 2014 Hykem
2 | // Licensed under the terms of the GNU GPL, version 3
3 | // http://www.gnu.org/licenses/gpl-3.0.txt
4 |
5 | #include
6 |
7 | typedef unsigned long long u64;
8 |
9 | unsigned char* strip_utf8(unsigned char *src, int size);
10 | bool isEmpty(unsigned char* buf, int buf_size);
11 | int se32(int i);
12 | u64 se64(u64 i);
--------------------------------------------------------------------------------