tree checksum vpatch file split hunks

all signers: asciilifeform diana_coman

antecedents:

press order:

mpi-genesisasciilifeform diana_coman

patch:

-
+ 9225ACDFEE37D53F45669EAC0ABD4F4E8EBA5E9DBF39F49E9F182530A038A159934F8645E2BDC00783B4AF40743643C1B3256653B5D3A4DEA375ACE1613B72FC
mpi/COPYING
(0 . 0)(1 . 676)
5
6 GNU GENERAL PUBLIC LICENSE
7 Version 3, 29 June 2007
8
9 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
10 Everyone is permitted to copy and distribute verbatim copies
11 of this license document, but changing it is not allowed.
12
13 Preamble
14
15 The GNU General Public License is a free, copyleft license for
16 software and other kinds of works.
17
18 The licenses for most software and other practical works are designed
19 to take away your freedom to share and change the works. By contrast,
20 the GNU General Public License is intended to guarantee your freedom to
21 share and change all versions of a program--to make sure it remains free
22 software for all its users. We, the Free Software Foundation, use the
23 GNU General Public License for most of our software; it applies also to
24 any other work released this way by its authors. You can apply it to
25 your programs, too.
26
27 When we speak of free software, we are referring to freedom, not
28 price. Our General Public Licenses are designed to make sure that you
29 have the freedom to distribute copies of free software (and charge for
30 them if you wish), that you receive source code or can get it if you
31 want it, that you can change the software or use pieces of it in new
32 free programs, and that you know you can do these things.
33
34 To protect your rights, we need to prevent others from denying you
35 these rights or asking you to surrender the rights. Therefore, you have
36 certain responsibilities if you distribute copies of the software, or if
37 you modify it: responsibilities to respect the freedom of others.
38
39 For example, if you distribute copies of such a program, whether
40 gratis or for a fee, you must pass on to the recipients the same
41 freedoms that you received. You must make sure that they, too, receive
42 or can get the source code. And you must show them these terms so they
43 know their rights.
44
45 Developers that use the GNU GPL protect your rights with two steps:
46 (1) assert copyright on the software, and (2) offer you this License
47 giving you legal permission to copy, distribute and/or modify it.
48
49 For the developers' and authors' protection, the GPL clearly explains
50 that there is no warranty for this free software. For both users' and
51 authors' sake, the GPL requires that modified versions be marked as
52 changed, so that their problems will not be attributed erroneously to
53 authors of previous versions.
54
55 Some devices are designed to deny users access to install or run
56 modified versions of the software inside them, although the manufacturer
57 can do so. This is fundamentally incompatible with the aim of
58 protecting users' freedom to change the software. The systematic
59 pattern of such abuse occurs in the area of products for individuals to
60 use, which is precisely where it is most unacceptable. Therefore, we
61 have designed this version of the GPL to prohibit the practice for those
62 products. If such problems arise substantially in other domains, we
63 stand ready to extend this provision to those domains in future versions
64 of the GPL, as needed to protect the freedom of users.
65
66 Finally, every program is threatened constantly by software patents.
67 States should not allow patents to restrict development and use of
68 software on general-purpose computers, but in those that do, we wish to
69 avoid the special danger that patents applied to a free program could
70 make it effectively proprietary. To prevent this, the GPL assures that
71 patents cannot be used to render the program non-free.
72
73 The precise terms and conditions for copying, distribution and
74 modification follow.
75
76 TERMS AND CONDITIONS
77
78 0. Definitions.
79
80 "This License" refers to version 3 of the GNU General Public License.
81
82 "Copyright" also means copyright-like laws that apply to other kinds of
83 works, such as semiconductor masks.
84
85 "The Program" refers to any copyrightable work licensed under this
86 License. Each licensee is addressed as "you". "Licensees" and
87 "recipients" may be individuals or organizations.
88
89 To "modify" a work means to copy from or adapt all or part of the work
90 in a fashion requiring copyright permission, other than the making of an
91 exact copy. The resulting work is called a "modified version" of the
92 earlier work or a work "based on" the earlier work.
93
94 A "covered work" means either the unmodified Program or a work based
95 on the Program.
96
97 To "propagate" a work means to do anything with it that, without
98 permission, would make you directly or secondarily liable for
99 infringement under applicable copyright law, except executing it on a
100 computer or modifying a private copy. Propagation includes copying,
101 distribution (with or without modification), making available to the
102 public, and in some countries other activities as well.
103
104 To "convey" a work means any kind of propagation that enables other
105 parties to make or receive copies. Mere interaction with a user through
106 a computer network, with no transfer of a copy, is not conveying.
107
108 An interactive user interface displays "Appropriate Legal Notices"
109 to the extent that it includes a convenient and prominently visible
110 feature that (1) displays an appropriate copyright notice, and (2)
111 tells the user that there is no warranty for the work (except to the
112 extent that warranties are provided), that licensees may convey the
113 work under this License, and how to view a copy of this License. If
114 the interface presents a list of user commands or options, such as a
115 menu, a prominent item in the list meets this criterion.
116
117 1. Source Code.
118
119 The "source code" for a work means the preferred form of the work
120 for making modifications to it. "Object code" means any non-source
121 form of a work.
122
123 A "Standard Interface" means an interface that either is an official
124 standard defined by a recognized standards body, or, in the case of
125 interfaces specified for a particular programming language, one that
126 is widely used among developers working in that language.
127
128 The "System Libraries" of an executable work include anything, other
129 than the work as a whole, that (a) is included in the normal form of
130 packaging a Major Component, but which is not part of that Major
131 Component, and (b) serves only to enable use of the work with that
132 Major Component, or to implement a Standard Interface for which an
133 implementation is available to the public in source code form. A
134 "Major Component", in this context, means a major essential component
135 (kernel, window system, and so on) of the specific operating system
136 (if any) on which the executable work runs, or a compiler used to
137 produce the work, or an object code interpreter used to run it.
138
139 The "Corresponding Source" for a work in object code form means all
140 the source code needed to generate, install, and (for an executable
141 work) run the object code and to modify the work, including scripts to
142 control those activities. However, it does not include the work's
143 System Libraries, or general-purpose tools or generally available free
144 programs which are used unmodified in performing those activities but
145 which are not part of the work. For example, Corresponding Source
146 includes interface definition files associated with source files for
147 the work, and the source code for shared libraries and dynamically
148 linked subprograms that the work is specifically designed to require,
149 such as by intimate data communication or control flow between those
150 subprograms and other parts of the work.
151
152 The Corresponding Source need not include anything that users
153 can regenerate automatically from other parts of the Corresponding
154 Source.
155
156 The Corresponding Source for a work in source code form is that
157 same work.
158
159 2. Basic Permissions.
160
161 All rights granted under this License are granted for the term of
162 copyright on the Program, and are irrevocable provided the stated
163 conditions are met. This License explicitly affirms your unlimited
164 permission to run the unmodified Program. The output from running a
165 covered work is covered by this License only if the output, given its
166 content, constitutes a covered work. This License acknowledges your
167 rights of fair use or other equivalent, as provided by copyright law.
168
169 You may make, run and propagate covered works that you do not
170 convey, without conditions so long as your license otherwise remains
171 in force. You may convey covered works to others for the sole purpose
172 of having them make modifications exclusively for you, or provide you
173 with facilities for running those works, provided that you comply with
174 the terms of this License in conveying all material for which you do
175 not control copyright. Those thus making or running the covered works
176 for you must do so exclusively on your behalf, under your direction
177 and control, on terms that prohibit them from making any copies of
178 your copyrighted material outside their relationship with you.
179
180 Conveying under any other circumstances is permitted solely under
181 the conditions stated below. Sublicensing is not allowed; section 10
182 makes it unnecessary.
183
184 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
185
186 No covered work shall be deemed part of an effective technological
187 measure under any applicable law fulfilling obligations under article
188 11 of the WIPO copyright treaty adopted on 20 December 1996, or
189 similar laws prohibiting or restricting circumvention of such
190 measures.
191
192 When you convey a covered work, you waive any legal power to forbid
193 circumvention of technological measures to the extent such circumvention
194 is effected by exercising rights under this License with respect to
195 the covered work, and you disclaim any intention to limit operation or
196 modification of the work as a means of enforcing, against the work's
197 users, your or third parties' legal rights to forbid circumvention of
198 technological measures.
199
200 4. Conveying Verbatim Copies.
201
202 You may convey verbatim copies of the Program's source code as you
203 receive it, in any medium, provided that you conspicuously and
204 appropriately publish on each copy an appropriate copyright notice;
205 keep intact all notices stating that this License and any
206 non-permissive terms added in accord with section 7 apply to the code;
207 keep intact all notices of the absence of any warranty; and give all
208 recipients a copy of this License along with the Program.
209
210 You may charge any price or no price for each copy that you convey,
211 and you may offer support or warranty protection for a fee.
212
213 5. Conveying Modified Source Versions.
214
215 You may convey a work based on the Program, or the modifications to
216 produce it from the Program, in the form of source code under the
217 terms of section 4, provided that you also meet all of these conditions:
218
219 a) The work must carry prominent notices stating that you modified
220 it, and giving a relevant date.
221
222 b) The work must carry prominent notices stating that it is
223 released under this License and any conditions added under section
224 7. This requirement modifies the requirement in section 4 to
225 "keep intact all notices".
226
227 c) You must license the entire work, as a whole, under this
228 License to anyone who comes into possession of a copy. This
229 License will therefore apply, along with any applicable section 7
230 additional terms, to the whole of the work, and all its parts,
231 regardless of how they are packaged. This License gives no
232 permission to license the work in any other way, but it does not
233 invalidate such permission if you have separately received it.
234
235 d) If the work has interactive user interfaces, each must display
236 Appropriate Legal Notices; however, if the Program has interactive
237 interfaces that do not display Appropriate Legal Notices, your
238 work need not make them do so.
239
240 A compilation of a covered work with other separate and independent
241 works, which are not by their nature extensions of the covered work,
242 and which are not combined with it such as to form a larger program,
243 in or on a volume of a storage or distribution medium, is called an
244 "aggregate" if the compilation and its resulting copyright are not
245 used to limit the access or legal rights of the compilation's users
246 beyond what the individual works permit. Inclusion of a covered work
247 in an aggregate does not cause this License to apply to the other
248 parts of the aggregate.
249
250 6. Conveying Non-Source Forms.
251
252 You may convey a covered work in object code form under the terms
253 of sections 4 and 5, provided that you also convey the
254 machine-readable Corresponding Source under the terms of this License,
255 in one of these ways:
256
257 a) Convey the object code in, or embodied in, a physical product
258 (including a physical distribution medium), accompanied by the
259 Corresponding Source fixed on a durable physical medium
260 customarily used for software interchange.
261
262 b) Convey the object code in, or embodied in, a physical product
263 (including a physical distribution medium), accompanied by a
264 written offer, valid for at least three years and valid for as
265 long as you offer spare parts or customer support for that product
266 model, to give anyone who possesses the object code either (1) a
267 copy of the Corresponding Source for all the software in the
268 product that is covered by this License, on a durable physical
269 medium customarily used for software interchange, for a price no
270 more than your reasonable cost of physically performing this
271 conveying of source, or (2) access to copy the
272 Corresponding Source from a network server at no charge.
273
274 c) Convey individual copies of the object code with a copy of the
275 written offer to provide the Corresponding Source. This
276 alternative is allowed only occasionally and noncommercially, and
277 only if you received the object code with such an offer, in accord
278 with subsection 6b.
279
280 d) Convey the object code by offering access from a designated
281 place (gratis or for a charge), and offer equivalent access to the
282 Corresponding Source in the same way through the same place at no
283 further charge. You need not require recipients to copy the
284 Corresponding Source along with the object code. If the place to
285 copy the object code is a network server, the Corresponding Source
286 may be on a different server (operated by you or a third party)
287 that supports equivalent copying facilities, provided you maintain
288 clear directions next to the object code saying where to find the
289 Corresponding Source. Regardless of what server hosts the
290 Corresponding Source, you remain obligated to ensure that it is
291 available for as long as needed to satisfy these requirements.
292
293 e) Convey the object code using peer-to-peer transmission, provided
294 you inform other peers where the object code and Corresponding
295 Source of the work are being offered to the general public at no
296 charge under subsection 6d.
297
298 A separable portion of the object code, whose source code is excluded
299 from the Corresponding Source as a System Library, need not be
300 included in conveying the object code work.
301
302 A "User Product" is either (1) a "consumer product", which means any
303 tangible personal property which is normally used for personal, family,
304 or household purposes, or (2) anything designed or sold for incorporation
305 into a dwelling. In determining whether a product is a consumer product,
306 doubtful cases shall be resolved in favor of coverage. For a particular
307 product received by a particular user, "normally used" refers to a
308 typical or common use of that class of product, regardless of the status
309 of the particular user or of the way in which the particular user
310 actually uses, or expects or is expected to use, the product. A product
311 is a consumer product regardless of whether the product has substantial
312 commercial, industrial or non-consumer uses, unless such uses represent
313 the only significant mode of use of the product.
314
315 "Installation Information" for a User Product means any methods,
316 procedures, authorization keys, or other information required to install
317 and execute modified versions of a covered work in that User Product from
318 a modified version of its Corresponding Source. The information must
319 suffice to ensure that the continued functioning of the modified object
320 code is in no case prevented or interfered with solely because
321 modification has been made.
322
323 If you convey an object code work under this section in, or with, or
324 specifically for use in, a User Product, and the conveying occurs as
325 part of a transaction in which the right of possession and use of the
326 User Product is transferred to the recipient in perpetuity or for a
327 fixed term (regardless of how the transaction is characterized), the
328 Corresponding Source conveyed under this section must be accompanied
329 by the Installation Information. But this requirement does not apply
330 if neither you nor any third party retains the ability to install
331 modified object code on the User Product (for example, the work has
332 been installed in ROM).
333
334 The requirement to provide Installation Information does not include a
335 requirement to continue to provide support service, warranty, or updates
336 for a work that has been modified or installed by the recipient, or for
337 the User Product in which it has been modified or installed. Access to a
338 network may be denied when the modification itself materially and
339 adversely affects the operation of the network or violates the rules and
340 protocols for communication across the network.
341
342 Corresponding Source conveyed, and Installation Information provided,
343 in accord with this section must be in a format that is publicly
344 documented (and with an implementation available to the public in
345 source code form), and must require no special password or key for
346 unpacking, reading or copying.
347
348 7. Additional Terms.
349
350 "Additional permissions" are terms that supplement the terms of this
351 License by making exceptions from one or more of its conditions.
352 Additional permissions that are applicable to the entire Program shall
353 be treated as though they were included in this License, to the extent
354 that they are valid under applicable law. If additional permissions
355 apply only to part of the Program, that part may be used separately
356 under those permissions, but the entire Program remains governed by
357 this License without regard to the additional permissions.
358
359 When you convey a copy of a covered work, you may at your option
360 remove any additional permissions from that copy, or from any part of
361 it. (Additional permissions may be written to require their own
362 removal in certain cases when you modify the work.) You may place
363 additional permissions on material, added by you to a covered work,
364 for which you have or can give appropriate copyright permission.
365
366 Notwithstanding any other provision of this License, for material you
367 add to a covered work, you may (if authorized by the copyright holders of
368 that material) supplement the terms of this License with terms:
369
370 a) Disclaiming warranty or limiting liability differently from the
371 terms of sections 15 and 16 of this License; or
372
373 b) Requiring preservation of specified reasonable legal notices or
374 author attributions in that material or in the Appropriate Legal
375 Notices displayed by works containing it; or
376
377 c) Prohibiting misrepresentation of the origin of that material, or
378 requiring that modified versions of such material be marked in
379 reasonable ways as different from the original version; or
380
381 d) Limiting the use for publicity purposes of names of licensors or
382 authors of the material; or
383
384 e) Declining to grant rights under trademark law for use of some
385 trade names, trademarks, or service marks; or
386
387 f) Requiring indemnification of licensors and authors of that
388 material by anyone who conveys the material (or modified versions of
389 it) with contractual assumptions of liability to the recipient, for
390 any liability that these contractual assumptions directly impose on
391 those licensors and authors.
392
393 All other non-permissive additional terms are considered "further
394 restrictions" within the meaning of section 10. If the Program as you
395 received it, or any part of it, contains a notice stating that it is
396 governed by this License along with a term that is a further
397 restriction, you may remove that term. If a license document contains
398 a further restriction but permits relicensing or conveying under this
399 License, you may add to a covered work material governed by the terms
400 of that license document, provided that the further restriction does
401 not survive such relicensing or conveying.
402
403 If you add terms to a covered work in accord with this section, you
404 must place, in the relevant source files, a statement of the
405 additional terms that apply to those files, or a notice indicating
406 where to find the applicable terms.
407
408 Additional terms, permissive or non-permissive, may be stated in the
409 form of a separately written license, or stated as exceptions;
410 the above requirements apply either way.
411
412 8. Termination.
413
414 You may not propagate or modify a covered work except as expressly
415 provided under this License. Any attempt otherwise to propagate or
416 modify it is void, and will automatically terminate your rights under
417 this License (including any patent licenses granted under the third
418 paragraph of section 11).
419
420 However, if you cease all violation of this License, then your
421 license from a particular copyright holder is reinstated (a)
422 provisionally, unless and until the copyright holder explicitly and
423 finally terminates your license, and (b) permanently, if the copyright
424 holder fails to notify you of the violation by some reasonable means
425 prior to 60 days after the cessation.
426
427 Moreover, your license from a particular copyright holder is
428 reinstated permanently if the copyright holder notifies you of the
429 violation by some reasonable means, this is the first time you have
430 received notice of violation of this License (for any work) from that
431 copyright holder, and you cure the violation prior to 30 days after
432 your receipt of the notice.
433
434 Termination of your rights under this section does not terminate the
435 licenses of parties who have received copies or rights from you under
436 this License. If your rights have been terminated and not permanently
437 reinstated, you do not qualify to receive new licenses for the same
438 material under section 10.
439
440 9. Acceptance Not Required for Having Copies.
441
442 You are not required to accept this License in order to receive or
443 run a copy of the Program. Ancillary propagation of a covered work
444 occurring solely as a consequence of using peer-to-peer transmission
445 to receive a copy likewise does not require acceptance. However,
446 nothing other than this License grants you permission to propagate or
447 modify any covered work. These actions infringe copyright if you do
448 not accept this License. Therefore, by modifying or propagating a
449 covered work, you indicate your acceptance of this License to do so.
450
451 10. Automatic Licensing of Downstream Recipients.
452
453 Each time you convey a covered work, the recipient automatically
454 receives a license from the original licensors, to run, modify and
455 propagate that work, subject to this License. You are not responsible
456 for enforcing compliance by third parties with this License.
457
458 An "entity transaction" is a transaction transferring control of an
459 organization, or substantially all assets of one, or subdividing an
460 organization, or merging organizations. If propagation of a covered
461 work results from an entity transaction, each party to that
462 transaction who receives a copy of the work also receives whatever
463 licenses to the work the party's predecessor in interest had or could
464 give under the previous paragraph, plus a right to possession of the
465 Corresponding Source of the work from the predecessor in interest, if
466 the predecessor has it or can get it with reasonable efforts.
467
468 You may not impose any further restrictions on the exercise of the
469 rights granted or affirmed under this License. For example, you may
470 not impose a license fee, royalty, or other charge for exercise of
471 rights granted under this License, and you may not initiate litigation
472 (including a cross-claim or counterclaim in a lawsuit) alleging that
473 any patent claim is infringed by making, using, selling, offering for
474 sale, or importing the Program or any portion of it.
475
476 11. Patents.
477
478 A "contributor" is a copyright holder who authorizes use under this
479 License of the Program or a work on which the Program is based. The
480 work thus licensed is called the contributor's "contributor version".
481
482 A contributor's "essential patent claims" are all patent claims
483 owned or controlled by the contributor, whether already acquired or
484 hereafter acquired, that would be infringed by some manner, permitted
485 by this License, of making, using, or selling its contributor version,
486 but do not include claims that would be infringed only as a
487 consequence of further modification of the contributor version. For
488 purposes of this definition, "control" includes the right to grant
489 patent sublicenses in a manner consistent with the requirements of
490 this License.
491
492 Each contributor grants you a non-exclusive, worldwide, royalty-free
493 patent license under the contributor's essential patent claims, to
494 make, use, sell, offer for sale, import and otherwise run, modify and
495 propagate the contents of its contributor version.
496
497 In the following three paragraphs, a "patent license" is any express
498 agreement or commitment, however denominated, not to enforce a patent
499 (such as an express permission to practice a patent or covenant not to
500 sue for patent infringement). To "grant" such a patent license to a
501 party means to make such an agreement or commitment not to enforce a
502 patent against the party.
503
504 If you convey a covered work, knowingly relying on a patent license,
505 and the Corresponding Source of the work is not available for anyone
506 to copy, free of charge and under the terms of this License, through a
507 publicly available network server or other readily accessible means,
508 then you must either (1) cause the Corresponding Source to be so
509 available, or (2) arrange to deprive yourself of the benefit of the
510 patent license for this particular work, or (3) arrange, in a manner
511 consistent with the requirements of this License, to extend the patent
512 license to downstream recipients. "Knowingly relying" means you have
513 actual knowledge that, but for the patent license, your conveying the
514 covered work in a country, or your recipient's use of the covered work
515 in a country, would infringe one or more identifiable patents in that
516 country that you have reason to believe are valid.
517
518 If, pursuant to or in connection with a single transaction or
519 arrangement, you convey, or propagate by procuring conveyance of, a
520 covered work, and grant a patent license to some of the parties
521 receiving the covered work authorizing them to use, propagate, modify
522 or convey a specific copy of the covered work, then the patent license
523 you grant is automatically extended to all recipients of the covered
524 work and works based on it.
525
526 A patent license is "discriminatory" if it does not include within
527 the scope of its coverage, prohibits the exercise of, or is
528 conditioned on the non-exercise of one or more of the rights that are
529 specifically granted under this License. You may not convey a covered
530 work if you are a party to an arrangement with a third party that is
531 in the business of distributing software, under which you make payment
532 to the third party based on the extent of your activity of conveying
533 the work, and under which the third party grants, to any of the
534 parties who would receive the covered work from you, a discriminatory
535 patent license (a) in connection with copies of the covered work
536 conveyed by you (or copies made from those copies), or (b) primarily
537 for and in connection with specific products or compilations that
538 contain the covered work, unless you entered into that arrangement,
539 or that patent license was granted, prior to 28 March 2007.
540
541 Nothing in this License shall be construed as excluding or limiting
542 any implied license or other defenses to infringement that may
543 otherwise be available to you under applicable patent law.
544
545 12. No Surrender of Others' Freedom.
546
547 If conditions are imposed on you (whether by court order, agreement or
548 otherwise) that contradict the conditions of this License, they do not
549 excuse you from the conditions of this License. If you cannot convey a
550 covered work so as to satisfy simultaneously your obligations under this
551 License and any other pertinent obligations, then as a consequence you may
552 not convey it at all. For example, if you agree to terms that obligate you
553 to collect a royalty for further conveying from those to whom you convey
554 the Program, the only way you could satisfy both those terms and this
555 License would be to refrain entirely from conveying the Program.
556
557 13. Use with the GNU Affero General Public License.
558
559 Notwithstanding any other provision of this License, you have
560 permission to link or combine any covered work with a work licensed
561 under version 3 of the GNU Affero General Public License into a single
562 combined work, and to convey the resulting work. The terms of this
563 License will continue to apply to the part which is the covered work,
564 but the special requirements of the GNU Affero General Public License,
565 section 13, concerning interaction through a network will apply to the
566 combination as such.
567
568 14. Revised Versions of this License.
569
570 The Free Software Foundation may publish revised and/or new versions of
571 the GNU General Public License from time to time. Such new versions will
572 be similar in spirit to the present version, but may differ in detail to
573 address new problems or concerns.
574
575 Each version is given a distinguishing version number. If the
576 Program specifies that a certain numbered version of the GNU General
577 Public License "or any later version" applies to it, you have the
578 option of following the terms and conditions either of that numbered
579 version or of any later version published by the Free Software
580 Foundation. If the Program does not specify a version number of the
581 GNU General Public License, you may choose any version ever published
582 by the Free Software Foundation.
583
584 If the Program specifies that a proxy can decide which future
585 versions of the GNU General Public License can be used, that proxy's
586 public statement of acceptance of a version permanently authorizes you
587 to choose that version for the Program.
588
589 Later license versions may give you additional or different
590 permissions. However, no additional obligations are imposed on any
591 author or copyright holder as a result of your choosing to follow a
592 later version.
593
594 15. Disclaimer of Warranty.
595
596 THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
597 APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
598 HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
599 OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
600 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
601 PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
602 IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
603 ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
604
605 16. Limitation of Liability.
606
607 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
608 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
609 THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
610 GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
611 USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
612 DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
613 PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
614 EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
615 SUCH DAMAGES.
616
617 17. Interpretation of Sections 15 and 16.
618
619 If the disclaimer of warranty and limitation of liability provided
620 above cannot be given local legal effect according to their terms,
621 reviewing courts shall apply local law that most closely approximates
622 an absolute waiver of all civil liability in connection with the
623 Program, unless a warranty or assumption of liability accompanies a
624 copy of the Program in return for a fee.
625
626 END OF TERMS AND CONDITIONS
627
628 How to Apply These Terms to Your New Programs
629
630 If you develop a new program, and you want it to be of the greatest
631 possible use to the public, the best way to achieve this is to make it
632 free software which everyone can redistribute and change under these terms.
633
634 To do so, attach the following notices to the program. It is safest
635 to attach them to the start of each source file to most effectively
636 state the exclusion of warranty; and each file should have at least
637 the "copyright" line and a pointer to where the full notice is found.
638
639 <one line to give the program's name and a brief idea of what it does.>
640 Copyright (C) <year> <name of author>
641
642 This program is free software: you can redistribute it and/or modify
643 it under the terms of the GNU General Public License as published by
644 the Free Software Foundation, either version 3 of the License, or
645 (at your option) any later version.
646
647 This program is distributed in the hope that it will be useful,
648 but WITHOUT ANY WARRANTY; without even the implied warranty of
649 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
650 GNU General Public License for more details.
651
652 You should have received a copy of the GNU General Public License
653 along with this program. If not, see <http://www.gnu.org/licenses/>.
654
655 Also add information on how to contact you by electronic and paper mail.
656
657 If the program does terminal interaction, make it output a short
658 notice like this when it starts in an interactive mode:
659
660 <program> Copyright (C) <year> <name of author>
661 This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
662 This is free software, and you are welcome to redistribute it
663 under certain conditions; type `show c' for details.
664
665 The hypothetical commands `show w' and `show c' should show the appropriate
666 parts of the General Public License. Of course, your program's commands
667 might be different; for a GUI interface, you would use an "about box".
668
669 You should also get your employer (if you work as a programmer) or school,
670 if any, to sign a "copyright disclaimer" for the program, if necessary.
671 For more information on this, and how to apply and follow the GNU GPL, see
672 <http://www.gnu.org/licenses/>.
673
674 The GNU General Public License does not permit incorporating your program
675 into proprietary programs. If your program is a subroutine library, you
676 may consider it more useful to permit linking proprietary applications with
677 the library. If this is what you want to do, use the GNU Lesser General
678 Public License instead of this License. But first, please read
679 <http://www.gnu.org/philosophy/why-not-lgpl.html>.
680
-
+ 2637E827D61AC5BE58C3CC88799EAF49DAED6C957ED6C6647B6D8D787E4F7FD731CDD16DB53CB1FA15E35230E918CD62DA33B4DD410CC073CA4092BC973F5AD1
mpi/errors.c
(0 . 0)(1 . 113)
685 /* errors.c - error strings
686 * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
687 *
688 * This file is part of GnuPG.
689 *
690 * GnuPG is free software; you can redistribute it and/or modify
691 * it under the terms of the GNU General Public License as published by
692 * the Free Software Foundation; either version 3 of the License, or
693 * (at your option) any later version.
694 *
695 * GnuPG is distributed in the hope that it will be useful,
696 * but WITHOUT ANY WARRANTY; without even the implied warranty of
697 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
698 * GNU General Public License for more details.
699 *
700 * You should have received a copy of the GNU General Public License
701 * along with this program; if not, see <http://www.gnu.org/licenses/>.
702 */
703
704 #include <config.h>
705 #include <stdio.h>
706 #include <stdlib.h>
707 #include <stdarg.h>
708
709 #include "errors.h"
710
711 #ifndef HAVE_STRERROR
712 char *
713 strerror( int n )
714 {
715 extern char *sys_errlist[];
716 extern int sys_nerr;
717 static char buf[15];
718
719 if( n >= 0 && n < sys_nerr )
720 return sys_errlist[n];
721 strcpy( buf, "Unknown error" );
722 return buf;
723 }
724 #endif /* !HAVE_STRERROR */
725
726 const char *
727 g10_errstr( int err )
728 {
729 static char buf[50];
730 const char *p;
731
732 #define X(n,s) case G10ERR_##n : p = s; break;
733 switch( err ) {
734 case -1: p = "eof"; break;
735 case 0: p = "okay"; break;
736 X(GENERAL, N_("general error"))
737 X(UNKNOWN_PACKET, N_("unknown packet type"))
738 X(UNKNOWN_VERSION,N_("unknown version"))
739 X(PUBKEY_ALGO ,N_("unknown pubkey algorithm"))
740 X(DIGEST_ALGO ,N_("unknown digest algorithm"))
741 X(BAD_PUBKEY ,N_("bad public key"))
742 X(BAD_SECKEY ,N_("bad secret key"))
743 X(BAD_SIGN ,N_("bad signature"))
744 X(CHECKSUM , N_("checksum error"))
745 X(BAD_PASS , N_("bad passphrase"))
746 X(NO_PUBKEY ,N_("public key not found"))
747 X(CIPHER_ALGO ,N_("unknown cipher algorithm"))
748 X(KEYRING_OPEN ,N_("can't open the keyring"))
749 X(INVALID_PACKET ,N_("invalid packet"))
750 X(INVALID_ARMOR ,N_("invalid armor"))
751 X(NO_USER_ID ,N_("no such user id"))
752 X(NO_SECKEY ,N_("secret key not available"))
753 X(WRONG_SECKEY ,N_("wrong secret key used"))
754 X(UNSUPPORTED ,N_("not supported"))
755 X(BAD_KEY ,N_("bad key"))
756 X(READ_FILE ,N_("file read error"))
757 X(WRITE_FILE ,N_("file write error"))
758 X(COMPR_ALGO ,N_("unknown compress algorithm"))
759 X(OPEN_FILE ,N_("file open error"))
760 X(CREATE_FILE ,N_("file create error"))
761 X(PASSPHRASE ,N_("invalid passphrase"))
762 X(NI_PUBKEY ,N_("unimplemented pubkey algorithm"))
763 X(NI_CIPHER ,N_("unimplemented cipher algorithm"))
764 X(SIG_CLASS ,N_("unknown signature class"))
765 X(TRUSTDB ,N_("trust database error"))
766 X(BAD_MPI ,N_("bad MPI"))
767 X(RESOURCE_LIMIT ,N_("resource limit"))
768 X(INV_KEYRING ,N_("invalid keyring"))
769 X(BAD_CERT ,N_("bad certificate"))
770 X(INV_USER_ID ,N_("malformed user id"))
771 X(CLOSE_FILE ,N_("file close error"))
772 X(RENAME_FILE ,N_("file rename error"))
773 X(DELETE_FILE ,N_("file delete error"))
774 X(UNEXPECTED ,N_("unexpected data"))
775 X(TIME_CONFLICT ,N_("timestamp conflict"))
776 X(WR_PUBKEY_ALGO ,N_("unusable pubkey algorithm"))
777 X(FILE_EXISTS ,N_("file exists"))
778 X(WEAK_KEY ,N_("weak key"))
779 X(INV_ARG ,N_("invalid argument"))
780 X(BAD_URI ,N_("bad URI"))
781 X(INVALID_URI ,N_("unsupported URI"))
782 X(NETWORK ,N_("network error"))
783 X(SELFTEST_FAILED,"selftest failed")
784 X(NOT_ENCRYPTED ,N_("not encrypted"))
785 X(NOT_PROCESSED ,N_("not processed"))
786 /* the key cannot be used for a specific usage */
787 X(UNU_PUBKEY ,N_("unusable public key"))
788 X(UNU_SECKEY ,N_("unusable secret key"))
789 X(KEYSERVER ,N_("keyserver error"))
790 X(CANCELED ,N_("canceled"))
791 X(NO_CARD ,N_("no card"))
792 X(NO_DATA ,N_("no data"))
793 default: p = buf; sprintf(buf, "g10err=%d", err); break;
794 }
795 #undef X
796 return _(p);
797 }
-
+ CBB804CBF1D96718EEBC82ABDED7FB63514BA10EFD2EB136A606D85BD1896DBEAA0D631CD87BF01C8C1E014350F5664309EC9136A0D4C6EDF63C039227450926
mpi/include/compat.h
(0 . 0)(1 . 25)
802 #ifndef _COMPAT_H_
803 #define _COMPAT_H_
804
805 /* Note this isn't identical to a C locale isspace() without \f and
806 \v, but works for the purposes used here. */
807 #define ascii_isspace(a) ((a)==' ' || (a)=='\n' || (a)=='\r' || (a)=='\t')
808
809 int hextobyte( const char *s );
810 int ascii_toupper (int c);
811 int ascii_tolower (int c);
812 int ascii_strcasecmp( const char *a, const char *b );
813 int ascii_strncasecmp( const char *a, const char *b, size_t n);
814
815 #ifndef HAVE_STRSEP
816 char *strsep (char **stringp, const char *delim);
817 #endif
818
819 #if __GNUC__ >= 4
820 char *xstrconcat (const char *s1, ...) __attribute__ ((sentinel(0)));
821 #else
822 char *xstrconcat (const char *s1, ...);
823 #endif
824
825
826 #endif /* !_COMPAT_H_ */
-
+ F16ECF4FD4CFFB8CB4C97BEE3A486E8FEAAA6CE8C2D70FDF6AB80687847AE8700B2DC199476459401505048D1642B4D94FD2E4152D911E8B6D54065DA09EFE66
mpi/include/config.h
(0 . 0)(1 . 89)
831 /* config.h.
832 ORIGINALLY Generated from config.h.in by configure.
833 Cleaned up by hand. The price of this is that the knobs must
834 now be turned by hand.
835 */
836
837 #ifndef GNUPG_CONFIG_H_INCLUDED
838 #define GNUPG_CONFIG_H_INCLUDED
839
840 /* Define to 1 if you have the `atexit' function. */
841 #define HAVE_ATEXIT 1
842
843 /* Defined if the mlock() call does not work */
844 /* #undef HAVE_BROKEN_MLOCK */
845
846 /* Defined if a `byte' is typedef'd */
847 /* #undef HAVE_BYTE_TYPEDEF */
848
849 /* defined if we run on some of the PCDOS like systems (DOS, Windoze. OS/2)
850 with special properties like no file modes */
851 /* #undef HAVE_DOSISH_SYSTEM */
852
853 /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
854 #define HAVE_FSEEKO 1
855
856 /* Define to 1 if you have the `getpagesize' function. */
857 #define HAVE_GETPAGESIZE 1
858
859 /* Define to 1 if you have the <inttypes.h> header file. */
860 #define HAVE_INTTYPES_H 1
861
862 /* Define to 1 if you have the <limits.h> header file. */
863 #define HAVE_LIMITS_H 1
864
865 /* Define to 1 if you have the <locale.h> header file. */
866 // #undef HAVE_LOCALE_H
867
868 /* Define to 1 if you have the `memmove' function. */
869 #define HAVE_MEMMOVE 1
870
871 /* Defined if the system supports an mlock() call */
872 #define HAVE_MLOCK 1
873
874 /* Define to 1 if you have the `mmap' function. */
875 #define HAVE_MMAP 1
876
877 /* Define to 1 if you have the `plock' function. */
878 /* #undef HAVE_PLOCK */
879
880 /* Define to 1 if you have the `raise' function. */
881 #define HAVE_RAISE 1
882
883 /* Define to 1 if you have the `stpcpy' function. */
884 #define HAVE_STPCPY 1
885
886 /* Define to 1 if you have the `strcasecmp' function. */
887 #define HAVE_STRCASECMP 1
888
889 /* Define to 1 if you have the `strerror' function. */
890 #define HAVE_STRERROR 1
891
892 /* Define to 1 if you have the `strlwr' function. */
893 /* #undef HAVE_STRLWR */
894
895 /* Define to 1 if you have the `strncasecmp' function. */
896 #define HAVE_STRNCASECMP 1
897
898 /* Define to 1 if you have the `strsep' function. */
899 #define HAVE_STRSEP 1
900
901 /* Define to 1 if you have the `strtoul' function. */
902 #define HAVE_STRTOUL 1
903
904 /* Define to 1 if you have the `sysconf' function. */
905 #define HAVE_SYSCONF 1
906
907 /* Defined if a `u16' is typedef'd */
908 /* #undef HAVE_U16_TYPEDEF */
909
910 /* Defined if a `u32' is typedef'd */
911 /* #undef HAVE_U32_TYPEDEF */
912
913 /* Defined if a `ulong' is typedef'd */
914 #define HAVE_ULONG_TYPEDEF 1
915
916 /* Defined if a `ushort' is typedef'd */
917 #define HAVE_USHORT_TYPEDEF 1
918
919 #endif /*GNUPG_CONFIG_H_INCLUDED*/
-
+ 6C4FAB042DB987C280EA86471C8549A167903CB11073D0B74A426DC78CE9E65A1B66FB2815722ACB069DF807506181548960E60C33EE27C64246672A8457F752
mpi/include/errors.h
(0 . 0)(1 . 89)
924 /* errors.h - erro code
925 * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
926 *
927 * This file is part of GNUPG.
928 *
929 * GNUPG is free software; you can redistribute it and/or modify
930 * it under the terms of the GNU General Public License as published by
931 * the Free Software Foundation; either version 3 of the License, or
932 * (at your option) any later version.
933 *
934 * GNUPG is distributed in the hope that it will be useful,
935 * but WITHOUT ANY WARRANTY; without even the implied warranty of
936 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
937 * GNU General Public License for more details.
938 *
939 * You should have received a copy of the GNU General Public License
940 * along with this program; if not, see <http://www.gnu.org/licenses/>.
941 */
942 #ifndef G10_ERRORS_H
943 #define G10_ERRORS_H
944
945 #define G10ERR_GENERAL 1
946 #define G10ERR_UNKNOWN_PACKET 2
947 #define G10ERR_UNKNOWN_VERSION 3 /* Unknown version (in packet) */
948 #define G10ERR_PUBKEY_ALGO 4 /* Unknown pubkey algorithm */
949 #define G10ERR_DIGEST_ALGO 5 /* Unknown digest algorithm */
950 #define G10ERR_BAD_PUBKEY 6 /* Bad public key */
951 #define G10ERR_BAD_SECKEY 7 /* Bad secret key */
952 #define G10ERR_BAD_SIGN 8 /* Bad signature */
953 #define G10ERR_NO_PUBKEY 9 /* public key not found */
954 #define G10ERR_CHECKSUM 10 /* checksum error */
955 #define G10ERR_BAD_PASS 11 /* Bad passphrase */
956 #define G10ERR_CIPHER_ALGO 12 /* Unknown cipher algorithm */
957 #define G10ERR_KEYRING_OPEN 13
958 #define G10ERR_INVALID_PACKET 14
959 #define G10ERR_INVALID_ARMOR 15
960 #define G10ERR_NO_USER_ID 16
961 #define G10ERR_NO_SECKEY 17 /* secret key not available */
962 #define G10ERR_WRONG_SECKEY 18 /* wrong seckey used */
963 #define G10ERR_UNSUPPORTED 19
964 #define G10ERR_BAD_KEY 20 /* bad (session) key */
965 #define G10ERR_READ_FILE 21
966 #define G10ERR_WRITE_FILE 22
967 #define G10ERR_COMPR_ALGO 23 /* Unknown compress algorithm */
968 #define G10ERR_OPEN_FILE 24
969 #define G10ERR_CREATE_FILE 25
970 #define G10ERR_PASSPHRASE 26 /* invalid passphrase */
971 #define G10ERR_NI_PUBKEY 27
972 #define G10ERR_NI_CIPHER 28
973 #define G10ERR_SIG_CLASS 29
974 #define G10ERR_BAD_MPI 30
975 #define G10ERR_RESOURCE_LIMIT 31
976 #define G10ERR_INV_KEYRING 32
977 #define G10ERR_TRUSTDB 33 /* a problem with the trustdb */
978 #define G10ERR_BAD_CERT 34 /* bad certicate */
979 #define G10ERR_INV_USER_ID 35
980 #define G10ERR_CLOSE_FILE 36
981 #define G10ERR_RENAME_FILE 37
982 #define G10ERR_DELETE_FILE 38
983 #define G10ERR_UNEXPECTED 39
984 #define G10ERR_TIME_CONFLICT 40
985 #define G10ERR_WR_PUBKEY_ALGO 41 /* unusabe pubkey algo */
986 #define G10ERR_FILE_EXISTS 42
987 #define G10ERR_WEAK_KEY 43 /* NOTE: hardcoded into the cipher modules */
988 #define G10ERR_WRONG_KEYLEN 44 /* NOTE: hardcoded into the cipher modules */
989 #define G10ERR_INV_ARG 45
990 #define G10ERR_BAD_URI 46 /* syntax error in URI */
991 #define G10ERR_INVALID_URI 47 /* e.g. unsupported scheme */
992 #define G10ERR_NETWORK 48 /* general network error */
993 #define G10ERR_UNKNOWN_HOST 49
994 #define G10ERR_SELFTEST_FAILED 50
995 #define G10ERR_NOT_ENCRYPTED 51
996 #define G10ERR_NOT_PROCESSED 52
997 #define G10ERR_UNU_PUBKEY 53
998 #define G10ERR_UNU_SECKEY 54
999 #define G10ERR_KEYSERVER 55
1000 #define G10ERR_CANCELED 56
1001 #define G10ERR_NO_CARD 57
1002 #define G10ERR_NO_DATA 58
1003
1004 #ifndef HAVE_STRERROR
1005 char *strerror (int n);
1006 #endif
1007
1008 #ifdef _WIN32
1009 const char * w32_strerror (int w32_errno);
1010 #endif
1011
1012 #endif /*G10_ERRORS_H*/
-
+ 42269E10B09731558FE6D6E4F8D52F3C3CE10AD1C67496E22F7EC0E19C6D6586F1491921486E90A468905A68D6414D7B7F68914582206CCC2CE2E3ED1E2D3F3D
mpi/include/iobuf.h
(0 . 0)(1 . 161)
1017 /* iobuf.h - I/O buffer
1018 * Copyright (C) 1998, 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
1019 *
1020 * This file is part of GNUPG.
1021 *
1022 * GNUPG is free software; you can redistribute it and/or modify
1023 * it under the terms of the GNU General Public License as published by
1024 * the Free Software Foundation; either version 3 of the License, or
1025 * (at your option) any later version.
1026 *
1027 * GNUPG is distributed in the hope that it will be useful,
1028 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1029 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1030 * GNU General Public License for more details.
1031 *
1032 * You should have received a copy of the GNU General Public License
1033 * along with this program; if not, see <http://www.gnu.org/licenses/>.
1034 */
1035
1036 #ifndef G10_IOBUF_H
1037 #define G10_IOBUF_H
1038
1039 #include "types.h"
1040
1041
1042 #define DBG_IOBUF iobuf_debug_mode
1043
1044 #define IOBUFCTRL_INIT 1
1045 #define IOBUFCTRL_FREE 2
1046 #define IOBUFCTRL_UNDERFLOW 3
1047 #define IOBUFCTRL_FLUSH 4
1048 #define IOBUFCTRL_DESC 5
1049 #define IOBUFCTRL_CANCEL 6
1050 #define IOBUFCTRL_USER 16
1051
1052 typedef struct iobuf_struct *IOBUF;
1053 typedef struct iobuf_struct *iobuf_t;
1054
1055 /* fixme: we should hide most of this stuff */
1056 struct iobuf_struct {
1057 int use; /* 1 input , 2 output, 3 temp */
1058 off_t nlimit;
1059 off_t nbytes; /* used together with nlimit */
1060 off_t ntotal; /* total bytes read (position of stream) */
1061 int nofast; /* used by the iobuf_get() */
1062 void *directfp;
1063 struct {
1064 size_t size; /* allocated size */
1065 size_t start; /* number of invalid bytes at the begin of the buffer */
1066 size_t len; /* currently filled to this size */
1067 byte *buf;
1068 } d;
1069 int filter_eof;
1070 int error;
1071 int (*filter)( void *opaque, int control,
1072 IOBUF chain, byte *buf, size_t *len);
1073 void *filter_ov; /* value for opaque */
1074 int filter_ov_owner;
1075 char *real_fname;
1076 IOBUF chain; /* next iobuf used for i/o if any (passed to filter) */
1077 int no, subno;
1078 const char *desc;
1079 void *opaque; /* can be used to hold any information */
1080 /* this value is copied to all instances */
1081 struct {
1082 size_t size; /* allocated size */
1083 size_t start; /* number of invalid bytes at the begin of the buffer */
1084 size_t len; /* currently filled to this size */
1085 byte *buf;
1086 } unget;
1087 };
1088
1089 #ifndef EXTERN_UNLESS_MAIN_MODULE
1090 #if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE)
1091 #define EXTERN_UNLESS_MAIN_MODULE extern
1092 #else
1093 #define EXTERN_UNLESS_MAIN_MODULE
1094 #endif
1095 #endif
1096 EXTERN_UNLESS_MAIN_MODULE int iobuf_debug_mode;
1097
1098 void iobuf_enable_special_filenames ( int yes );
1099 int iobuf_is_pipe_filename (const char *fname);
1100 IOBUF iobuf_alloc(int use, size_t bufsize);
1101 IOBUF iobuf_temp(void);
1102 IOBUF iobuf_temp_with_content( const char *buffer, size_t length );
1103 IOBUF iobuf_open( const char *fname );
1104 IOBUF iobuf_fdopen( int fd, const char *mode );
1105 IOBUF iobuf_sockopen( int fd, const char *mode );
1106 IOBUF iobuf_create( const char *fname );
1107 IOBUF iobuf_append( const char *fname );
1108 IOBUF iobuf_openrw( const char *fname );
1109 int iobuf_ioctl ( IOBUF a, int cmd, int intval, void *ptrval );
1110 int iobuf_close( IOBUF iobuf );
1111 int iobuf_cancel( IOBUF iobuf );
1112
1113 int iobuf_push_filter( IOBUF a, int (*f)(void *opaque, int control,
1114 IOBUF chain, byte *buf, size_t *len), void *ov );
1115 int iobuf_push_filter2( IOBUF a,
1116 int (*f)(void *opaque, int control,
1117 IOBUF chain, byte *buf, size_t *len),
1118 void *ov, int rel_ov );
1119 int iobuf_flush(IOBUF a);
1120 void iobuf_clear_eof(IOBUF a);
1121 #define iobuf_set_error(a) do { (a)->error = 1; } while(0)
1122 #define iobuf_error(a) ((a)->error)
1123
1124 void iobuf_set_limit( IOBUF a, off_t nlimit );
1125
1126 off_t iobuf_tell( IOBUF a );
1127 int iobuf_seek( IOBUF a, off_t newpos );
1128
1129 int iobuf_readbyte(IOBUF a);
1130 int iobuf_read(IOBUF a, byte *buf, unsigned buflen );
1131 unsigned iobuf_read_line( IOBUF a, byte **addr_of_buffer,
1132 unsigned *length_of_buffer, unsigned *max_length );
1133 int iobuf_peek(IOBUF a, byte *buf, unsigned buflen );
1134 int iobuf_writebyte(IOBUF a, unsigned c);
1135 int iobuf_write(IOBUF a, byte *buf, unsigned buflen );
1136 int iobuf_writestr(IOBUF a, const char *buf );
1137
1138 void iobuf_flush_temp( IOBUF temp );
1139 int iobuf_write_temp( IOBUF a, IOBUF temp );
1140 size_t iobuf_temp_to_buffer( IOBUF a, byte *buffer, size_t buflen );
1141 void iobuf_unget_and_close_temp( IOBUF a, IOBUF temp );
1142
1143 int iobuf_get_fd (IOBUF a);
1144 off_t iobuf_get_filelength (IOBUF a, int *overflow);
1145 #define IOBUF_FILELENGTH_LIMIT 0xffffffff
1146 const char *iobuf_get_real_fname( IOBUF a );
1147 const char *iobuf_get_fname( IOBUF a );
1148
1149 void iobuf_set_partial_block_mode( IOBUF a, size_t len );
1150
1151 int iobuf_translate_file_handle ( int fd, int for_write );
1152
1153 /* Get a byte form the iobuf; must check for eof prior to this function.
1154 * This function returns values in the range 0 .. 255 or -1 to indicate EOF
1155 * iobuf_get_noeof() does not return -1 to indicate EOF, but masks the
1156 * returned value to be in the range 0..255.
1157 */
1158 #define iobuf_get(a) \
1159 ( ((a)->nofast || (a)->d.start >= (a)->d.len )? \
1160 iobuf_readbyte((a)) : ( (a)->nbytes++, (a)->d.buf[(a)->d.start++] ) )
1161 #define iobuf_get_noeof(a) (iobuf_get((a))&0xff)
1162
1163 /* write a byte to the iobuf and return true on write error
1164 * This macro does only write the low order byte
1165 */
1166 #define iobuf_put(a,c) iobuf_writebyte(a,c)
1167
1168 #define iobuf_where(a) "[don't know]"
1169 #define iobuf_id(a) ((a)->no)
1170
1171 #define iobuf_get_temp_buffer(a) ( (a)->d.buf )
1172 #define iobuf_get_temp_length(a) ( (a)->d.len )
1173 #define iobuf_is_temp(a) ( (a)->use == 3 )
1174
1175 void iobuf_skip_rest (IOBUF a, unsigned long n, int partial);
1176
1177 #endif /*G10_IOBUF_H*/
-
+ 042BA62021E6A33FA5F28447D8D268D4FD9A66D49BD10B904AA5F5C9FB6A30345F5CFEA787FBA1145B328F56E77C39E4D7C3D6DF94CCD4B7696B9FE2C8AA7055
mpi/include/longlong.h
(0 . 0)(1 . 224)
1182 /* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
1183 Note: I added some stuff for use with gnupg
1184
1185 Copyright (C) 1991, 1992, 1993, 1994, 1996, 1998,
1186 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
1187
1188 This file is free software; you can redistribute it and/or modify
1189 it under the terms of the GNU Lesser General Public License as published by
1190 the Free Software Foundation; either version 2.1 of the License, or (at your
1191 option) any later version.
1192
1193 This file is distributed in the hope that it will be useful, but
1194 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1195 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
1196 License for more details.
1197
1198 You should have received a copy of the GNU Lesser General Public License
1199 along with this file; if not, see <http://www.gnu.org/licenses/>. */
1200
1201
1202 /* You have to define the following before including this file:
1203
1204 UWtype -- An unsigned type, default type for operations (typically a "word")
1205 UHWtype -- An unsigned type, at least half the size of UWtype.
1206 UDWtype -- An unsigned type, at least twice as large a UWtype
1207 W_TYPE_SIZE -- size in bits of UWtype
1208
1209 SItype, USItype -- Signed and unsigned 32 bit types.
1210 DItype, UDItype -- Signed and unsigned 64 bit types.
1211
1212 On a 32 bit machine UWtype should typically be USItype;
1213 on a 64 bit machine, UWtype should typically be UDItype.
1214 */
1215
1216 #define __BITS4 (W_TYPE_SIZE / 4)
1217 #define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
1218 #define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
1219 #define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
1220
1221 /* This is used to make sure no undesirable sharing between different libraries
1222 that use this file takes place. */
1223 #ifndef __MPN
1224 #define __MPN(x) __##x
1225 #endif
1226
1227 /***************************************
1228 *********** Generic Versions ********
1229 ***************************************/
1230 #if !defined (umul_ppmm) && defined (__umulsidi3)
1231 #define umul_ppmm(ph, pl, m0, m1) \
1232 { \
1233 UDWtype __ll = __umulsidi3 (m0, m1); \
1234 ph = (UWtype) (__ll >> W_TYPE_SIZE); \
1235 pl = (UWtype) __ll; \
1236 }
1237 #endif
1238
1239 #if !defined (__umulsidi3)
1240 #define __umulsidi3(u, v) \
1241 ({UWtype __hi, __lo; \
1242 umul_ppmm (__hi, __lo, u, v); \
1243 ((UDWtype) __hi << W_TYPE_SIZE) | __lo; })
1244 #endif
1245
1246 /* If this machine has no inline assembler, use C macros. */
1247
1248 #if !defined (add_ssaaaa)
1249 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
1250 do { \
1251 UWtype __x; \
1252 __x = (al) + (bl); \
1253 (sh) = (ah) + (bh) + (__x < (al)); \
1254 (sl) = __x; \
1255 } while (0)
1256 #endif
1257
1258 #if !defined (sub_ddmmss)
1259 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
1260 do { \
1261 UWtype __x; \
1262 __x = (al) - (bl); \
1263 (sh) = (ah) - (bh) - (__x > (al)); \
1264 (sl) = __x; \
1265 } while (0)
1266 #endif
1267
1268 #if !defined (umul_ppmm)
1269 #define umul_ppmm(w1, w0, u, v) \
1270 do { \
1271 UWtype __x0, __x1, __x2, __x3; \
1272 UHWtype __ul, __vl, __uh, __vh; \
1273 UWtype __u = (u), __v = (v); \
1274 \
1275 __ul = __ll_lowpart (__u); \
1276 __uh = __ll_highpart (__u); \
1277 __vl = __ll_lowpart (__v); \
1278 __vh = __ll_highpart (__v); \
1279 \
1280 __x0 = (UWtype) __ul * __vl; \
1281 __x1 = (UWtype) __ul * __vh; \
1282 __x2 = (UWtype) __uh * __vl; \
1283 __x3 = (UWtype) __uh * __vh; \
1284 \
1285 __x1 += __ll_highpart (__x0);/* this can't give carry */ \
1286 __x1 += __x2; /* but this indeed can */ \
1287 if (__x1 < __x2) /* did we get it? */ \
1288 __x3 += __ll_B; /* yes, add it in the proper pos. */ \
1289 \
1290 (w1) = __x3 + __ll_highpart (__x1); \
1291 (w0) = (__ll_lowpart (__x1) << W_TYPE_SIZE/2) + __ll_lowpart (__x0);\
1292 } while (0)
1293 #endif
1294
1295 #if !defined (umul_ppmm)
1296 #define smul_ppmm(w1, w0, u, v) \
1297 do { \
1298 UWtype __w1; \
1299 UWtype __m0 = (u), __m1 = (v); \
1300 umul_ppmm (__w1, w0, __m0, __m1); \
1301 (w1) = __w1 - (-(__m0 >> (W_TYPE_SIZE - 1)) & __m1) \
1302 - (-(__m1 >> (W_TYPE_SIZE - 1)) & __m0); \
1303 } while (0)
1304 #endif
1305
1306 /* Define this unconditionally, so it can be used for debugging. */
1307 #define __udiv_qrnnd_c(q, r, n1, n0, d) \
1308 do { \
1309 UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \
1310 __d1 = __ll_highpart (d); \
1311 __d0 = __ll_lowpart (d); \
1312 \
1313 __r1 = (n1) % __d1; \
1314 __q1 = (n1) / __d1; \
1315 __m = (UWtype) __q1 * __d0; \
1316 __r1 = __r1 * __ll_B | __ll_highpart (n0); \
1317 if (__r1 < __m) \
1318 { \
1319 __q1--, __r1 += (d); \
1320 if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
1321 if (__r1 < __m) \
1322 __q1--, __r1 += (d); \
1323 } \
1324 __r1 -= __m; \
1325 \
1326 __r0 = __r1 % __d1; \
1327 __q0 = __r1 / __d1; \
1328 __m = (UWtype) __q0 * __d0; \
1329 __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
1330 if (__r0 < __m) \
1331 { \
1332 __q0--, __r0 += (d); \
1333 if (__r0 >= (d)) \
1334 if (__r0 < __m) \
1335 __q0--, __r0 += (d); \
1336 } \
1337 __r0 -= __m; \
1338 \
1339 (q) = (UWtype) __q1 * __ll_B | __q0; \
1340 (r) = __r0; \
1341 } while (0)
1342
1343 /* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
1344 __udiv_w_sdiv (defined in libgcc or elsewhere). */
1345 #if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
1346 #define udiv_qrnnd(q, r, nh, nl, d) \
1347 do { \
1348 UWtype __r; \
1349 (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \
1350 (r) = __r; \
1351 } while (0)
1352 #endif
1353
1354 /* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
1355 #if !defined (udiv_qrnnd)
1356 #define UDIV_NEEDS_NORMALIZATION 1
1357 #define udiv_qrnnd __udiv_qrnnd_c
1358 #endif
1359
1360 #if !defined (count_leading_zeros)
1361 extern
1362 #ifdef __STDC__
1363 const
1364 #endif
1365 unsigned char __clz_tab[];
1366 #define MPI_INTERNAL_NEED_CLZ_TAB 1
1367 #define count_leading_zeros(count, x) \
1368 do { \
1369 UWtype __xr = (x); \
1370 UWtype __a; \
1371 \
1372 if (W_TYPE_SIZE <= 32) \
1373 { \
1374 __a = __xr < ((UWtype) 1 << 2*__BITS4) \
1375 ? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4) \
1376 : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 : 3*__BITS4);\
1377 } \
1378 else \
1379 { \
1380 for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
1381 if (((__xr >> __a) & 0xff) != 0) \
1382 break; \
1383 } \
1384 \
1385 (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \
1386 } while (0)
1387 /* This version gives a well-defined value for zero. */
1388 #define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
1389 #endif
1390
1391 #if !defined (count_trailing_zeros)
1392 /* Define count_trailing_zeros using count_leading_zeros. The latter might be
1393 defined in asm, but if it is not, the C version above is good enough. */
1394 #define count_trailing_zeros(count, x) \
1395 do { \
1396 UWtype __ctz_x = (x); \
1397 UWtype __ctz_c; \
1398 count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \
1399 (count) = W_TYPE_SIZE - 1 - __ctz_c; \
1400 } while (0)
1401 #endif
1402
1403 #ifndef UDIV_NEEDS_NORMALIZATION
1404 #define UDIV_NEEDS_NORMALIZATION 0
1405 #endif
-
+ B48416427E71FE46868283490813E4D0A22DA9F4B17EFF706673A9B05380AE2D85EC9B183DB47EAA8AA197B7C7629EB873E63E5F8A66208BF230A794B6967FAB
mpi/include/memory.h
(0 . 0)(1 . 105)
1410 /* memory.h - memory allocation
1411 * Copyright (C) 1998, 1999, 2000, 2001, 2005 Free Software Foundation, Inc.
1412 *
1413 * This file is part of GNUPG.
1414 *
1415 * GNUPG is free software; you can redistribute it and/or modify
1416 * it under the terms of the GNU General Public License as published by
1417 * the Free Software Foundation; either version 3 of the License, or
1418 * (at your option) any later version.
1419 *
1420 * GNUPG is distributed in the hope that it will be useful,
1421 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1422 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1423 * GNU General Public License for more details.
1424 *
1425 * You should have received a copy of the GNU General Public License
1426 * along with this program; if not, see <http://www.gnu.org/licenses/>.
1427 */
1428
1429 #ifndef G10_MEMORY_H
1430 #define G10_MEMORY_H
1431
1432 #ifdef M_DEBUG
1433 #ifndef STR
1434 #define STR(v) #v
1435 #endif
1436 #ifndef __riscos__
1437 #define M_DBGINFO(a) __FUNCTION__ "["__FILE__ ":" STR(a) "]"
1438 #else /* __riscos__ */
1439 #define M_DBGINFO(a) "["__FILE__ ":" STR(a) "]"
1440 #endif /* __riscos__ */
1441 #define xmalloc(n) m_debug_alloc((n), M_DBGINFO( __LINE__ ) )
1442 #define xtrymalloc(n) m_debug_trymalloc ((n), M_DBGINFO( __LINE__ ))
1443 #define xmalloc_clear(n) m_debug_alloc_clear((n), M_DBGINFO(__LINE__) )
1444 #define xmalloc_secure(n) m_debug_alloc_secure(n), M_DBGINFO(__LINE__) )
1445 #define xmalloc_secure_clear(n) m_debug_alloc_secure_clear((n), M_DBGINFO(__LINE__) )
1446 #define xrealloc(n,m) m_debug_realloc((n),(m), M_DBGINFO(__LINE__) )
1447 #define xfree(n) m_debug_free((n), M_DBGINFO(__LINE__) )
1448 #define m_check(n) m_debug_check((n), M_DBGINFO(__LINE__) )
1449 /*#define m_copy(a) m_debug_copy((a), M_DBGINFO(__LINE__) )*/
1450 #define xstrdup(a) m_debug_strdup((a), M_DBGINFO(__LINE__) )
1451 #define xtrystrdup(a) m_debug_trystrdup((a), M_DBGINFO(__LINE__) )
1452
1453 void *m_debug_alloc( size_t n, const char *info );
1454 void *m_debug_trymalloc (size_t n, const char *info);
1455 void *m_debug_alloc_clear( size_t n, const char *info );
1456 void *m_debug_alloc_secure( size_t n, const char *info );
1457 void *m_debug_alloc_secure_clear( size_t n, const char *info );
1458 void *m_debug_realloc( void *a, size_t n, const char *info );
1459 void m_debug_free( void *p, const char *info );
1460 void m_debug_check( const void *a, const char *info );
1461 /*void *m_debug_copy( const void *a, const char *info );*/
1462 char *m_debug_strdup( const char *a, const char *info );
1463 char *m_debug_trystrdup (const char *a, const char *info);
1464
1465 #else
1466 void *xmalloc( size_t n );
1467 void *xtrymalloc (size_t n);
1468 void *xmalloc_clear( size_t n );
1469 void *xmalloc_secure( size_t n );
1470 void *xmalloc_secure_clear( size_t n );
1471 void *xrealloc( void *a, size_t n );
1472 void xfree( void *p );
1473 void m_check( const void *a );
1474 /*void *m_copy( const void *a );*/
1475 char *xstrdup( const char * a);
1476 char *xtrystrdup (const char *a);
1477 #endif
1478
1479 size_t m_size( const void *a );
1480 void m_print_stats(const char *prefix);
1481
1482 /* The follwing functions should be preferred over xmalloc_clear. */
1483 void *xcalloc (size_t n, size_t m);
1484 void *xcalloc_secure (size_t n, size_t m);
1485
1486
1487 /*-- secmem.c --*/
1488 int secmem_init( size_t npool );
1489 void secmem_term( void );
1490 void *secmem_malloc( size_t size );
1491 void *secmexrealloc( void *a, size_t newsize );
1492 void secmem_free( void *a );
1493 int m_is_secure( const void *p );
1494 void secmem_dump_stats(void);
1495 void secmem_set_flags( unsigned flags );
1496 unsigned secmem_get_flags(void);
1497
1498
1499 #define DBG_MEMORY memory_debug_mode
1500 #define DBG_MEMSTAT memory_stat_debug_mode
1501
1502 #ifndef EXTERN_UNLESS_MAIN_MODULE
1503 #if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE)
1504 #define EXTERN_UNLESS_MAIN_MODULE extern
1505 #else
1506 #define EXTERN_UNLESS_MAIN_MODULE
1507 #endif
1508 #endif
1509 EXTERN_UNLESS_MAIN_MODULE int memory_debug_mode;
1510 EXTERN_UNLESS_MAIN_MODULE int memory_stat_debug_mode;
1511
1512
1513
1514 #endif /*G10_MEMORY_H*/
-
+ FB2AFC7686790FA12E3143E79C4728DAC3E43C4056C647650D216B7EC7350F7651F6C44C4393858E8BAB02719B7674AD7F29E1FCB10511DE0A5AE4A2C12AF5A6
mpi/include/mpi-asm-defs.h
(0 . 0)(1 . 10)
1519 /* This file defines some basic constants for the MPI machinery. We
1520 * need to define the types on a per-CPU basis, so it is done with
1521 * this file here. */
1522 #define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG)
1523
1524
1525
1526
1527
1528
-
+ E539EF777487B66317CD23B7D19F883A9BAB67A9CB984DFB5D1A5DF4575A66CB44B7EC199AC0829B1270EDFA68F182D646CE944C14F5C401654E1E0F68271BAF
mpi/include/mpi.h
(0 . 0)(1 . 169)
1533 /* mpi.h - Multi Precision Integers
1534 * Copyright (C) 1994, 1996, 1998, 1999,
1535 * 2000, 2001 Free Software Foundation, Inc.
1536 *
1537 * This file is part of GNUPG.
1538 *
1539 * GNUPG is free software; you can redistribute it and/or modify
1540 * it under the terms of the GNU General Public License as published by
1541 * the Free Software Foundation; either version 3 of the License, or
1542 * (at your option) any later version.
1543 *
1544 * GNUPG is distributed in the hope that it will be useful,
1545 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1546 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1547 * GNU General Public License for more details.
1548 *
1549 * You should have received a copy of the GNU General Public License
1550 * along with this program; if not, see <http://www.gnu.org/licenses/>.
1551 *
1552 * Note: This code is heavily based on the GNU MP Library.
1553 * Actually it's the same code with only minor changes in the
1554 * way the data is stored; this is to support the abstraction
1555 * of an optional secure memory allocation which may be used
1556 * to avoid revealing of sensitive data due to paging etc.
1557 * The GNU MP Library itself is published under the LGPL;
1558 * however I decided to publish this code under the plain GPL.
1559 */
1560
1561 #ifndef G10_MPI_H
1562 #define G10_MPI_H
1563
1564 #include <config.h>
1565 #include <stdio.h>
1566 #include "iobuf.h"
1567 #include "types.h"
1568 #include "memory.h"
1569
1570 #ifndef EXTERN_UNLESS_MAIN_MODULE
1571 #if defined (__riscos__) && !defined (INCLUDED_BY_MAIN_MODULE)
1572 #define EXTERN_UNLESS_MAIN_MODULE extern
1573 #else
1574 #define EXTERN_UNLESS_MAIN_MODULE
1575 #endif
1576 #endif
1577
1578 #define DBG_MPI mpi_debug_mode
1579 EXTERN_UNLESS_MAIN_MODULE int mpi_debug_mode;
1580
1581
1582 struct gcry_mpi;
1583 typedef struct gcry_mpi *MPI;
1584
1585
1586 /*-- mpiutil.c --*/
1587
1588 #ifdef M_DEBUG
1589 #define mpi_alloc(n) mpi_debug_alloc((n), M_DBGINFO( __LINE__ ) )
1590 #define mpi_alloc_secure(n) mpi_debug_alloc_secure((n), M_DBGINFO( __LINE__ ) )
1591 #define mpi_alloc_like(n) mpi_debug_alloc_like((n), M_DBGINFO( __LINE__ ) )
1592 #define mpi_free(a) mpi_debug_free((a), M_DBGINFO(__LINE__) )
1593 #define mpi_resize(a,b) mpi_debug_resize((a),(b), M_DBGINFO(__LINE__) )
1594 #define mpi_copy(a) mpi_debug_copy((a), M_DBGINFO(__LINE__) )
1595 MPI mpi_debug_alloc( unsigned nlimbs, const char *info );
1596 MPI mpi_debug_alloc_secure( unsigned nlimbs, const char *info );
1597 MPI mpi_debug_alloc_like( MPI a, const char *info );
1598 void mpi_debug_free( MPI a, const char *info );
1599 void mpi_debug_resize( MPI a, unsigned nlimbs, const char *info );
1600 MPI mpi_debug_copy( MPI a, const char *info );
1601 #else
1602 MPI mpi_alloc( unsigned nlimbs );
1603 MPI mpi_alloc_secure( unsigned nlimbs );
1604 MPI mpi_alloc_like( MPI a );
1605 void mpi_free( MPI a );
1606 void mpi_resize( MPI a, unsigned nlimbs );
1607 MPI mpi_copy( MPI a );
1608 #endif
1609 #define mpi_is_opaque(a) ((a) && (mpi_get_flags (a)&4))
1610 MPI mpi_set_opaque( MPI a, void *p, unsigned int len );
1611 void *mpi_get_opaque( MPI a, unsigned int *len );
1612 #define mpi_is_secure(a) ((a) && (mpi_get_flags (a)&1))
1613 void mpi_set_secure( MPI a );
1614 void mpi_clear( MPI a );
1615 void mpi_set( MPI w, MPI u);
1616 void mpi_set_ui( MPI w, ulong u);
1617 MPI mpi_alloc_set_ui( unsigned long u);
1618 void mpi_m_check( MPI a );
1619 void mpi_swap( MPI a, MPI b);
1620 int mpi_get_nlimbs (MPI a);
1621 int mpi_is_neg (MPI a);
1622 unsigned int mpi_nlimb_hint_from_nbytes (unsigned int nbytes);
1623 unsigned int mpi_nlimb_hint_from_nbits (unsigned int nbits);
1624 unsigned int mpi_get_flags (MPI a);
1625
1626 /*-- mpicoder.c --*/
1627 int mpi_write( IOBUF out, MPI a );
1628 #ifdef M_DEBUG
1629 #define mpi_read(a,b,c) mpi_debug_read((a),(b),(c), M_DBGINFO( __LINE__ ) )
1630 MPI mpi_debug_read(IOBUF inp, unsigned *nread, int secure, const char *info);
1631 #else
1632 MPI mpi_read(IOBUF inp, unsigned *nread, int secure);
1633 #endif
1634 MPI mpi_read_from_buffer(byte *buffer, unsigned *ret_nread, int secure);
1635 int mpi_fromstr(MPI val, const char *str);
1636 int mpi_print( FILE *fp, MPI a, int mode );
1637 void g10_log_mpidump( const char *text, MPI a );
1638 u32 mpi_get_keyid( MPI a, u32 *keyid );
1639 byte *mpi_get_buffer( MPI a, unsigned *nbytes, int *sign );
1640 byte *mpi_get_secure_buffer( MPI a, unsigned *nbytes, int *sign );
1641 void mpi_set_buffer( MPI a, const byte *buffer, unsigned nbytes, int sign );
1642
1643 #define log_mpidump g10_log_mpidump
1644
1645 /*-- mpi-add.c --*/
1646 void mpi_add_ui(MPI w, MPI u, ulong v );
1647 void mpi_add(MPI w, MPI u, MPI v);
1648 void mpi_addm(MPI w, MPI u, MPI v, MPI m);
1649 void mpi_sub_ui(MPI w, MPI u, ulong v );
1650 void mpi_sub( MPI w, MPI u, MPI v);
1651 void mpi_subm( MPI w, MPI u, MPI v, MPI m);
1652
1653 /*-- mpi-mul.c --*/
1654 void mpi_mul_ui(MPI w, MPI u, ulong v );
1655 void mpi_mul_2exp( MPI w, MPI u, ulong cnt);
1656 void mpi_mul( MPI w, MPI u, MPI v);
1657 void mpi_mulm( MPI w, MPI u, MPI v, MPI m);
1658
1659 /*-- mpi-div.c --*/
1660 ulong mpi_fdiv_r_ui( MPI rem, MPI dividend, ulong divisor );
1661 void mpi_fdiv_r( MPI rem, MPI dividend, MPI divisor );
1662 void mpi_fdiv_q( MPI quot, MPI dividend, MPI divisor );
1663 void mpi_fdiv_qr( MPI quot, MPI rem, MPI dividend, MPI divisor );
1664 void mpi_tdiv_r( MPI rem, MPI num, MPI den);
1665 void mpi_tdiv_qr( MPI quot, MPI rem, MPI num, MPI den);
1666 void mpi_tdiv_q_2exp( MPI w, MPI u, unsigned count );
1667 int mpi_divisible_ui(MPI dividend, ulong divisor );
1668
1669 /*-- mpi-gcd.c --*/
1670 int mpi_gcd( MPI g, MPI a, MPI b );
1671
1672 /*-- mpi-pow.c --*/
1673 void mpi_pow( MPI w, MPI u, MPI v);
1674 void mpi_powm( MPI res, MPI base, MPI exponent, MPI mod);
1675
1676 /*-- mpi-mpow.c --*/
1677 void mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI mod);
1678
1679 /*-- mpi-cmp.c --*/
1680 int mpi_cmp_ui( MPI u, ulong v );
1681 int mpi_cmp( MPI u, MPI v );
1682
1683 /*-- mpi-scan.c --*/
1684 int mpi_getbyte( MPI a, unsigned idx );
1685 void mpi_putbyte( MPI a, unsigned idx, int value );
1686 unsigned mpi_trailing_zeros( MPI a );
1687
1688 /*-- mpi-bit.c --*/
1689 void mpi_normalize( MPI a );
1690 unsigned mpi_get_nbits( MPI a );
1691 int mpi_test_bit( MPI a, unsigned n );
1692 void mpi_set_bit( MPI a, unsigned n );
1693 void mpi_set_highbit( MPI a, unsigned n );
1694 void mpi_clear_highbit( MPI a, unsigned n );
1695 void mpi_clear_bit( MPI a, unsigned n );
1696 void mpi_rshift( MPI x, MPI a, unsigned n );
1697
1698 /*-- mpi-inv.c --*/
1699 void mpi_invm( MPI x, MPI u, MPI v );
1700
1701 #endif /*G10_MPI_H*/
-
+ DF6064B02A11C90FB20945DAD1ECC4753A231F894D6CF60E133D6196D924442E0FA08C1D38421A97511F4007A9545C6A980960A20817E6EAECF4CE36E920F151
mpi/include/mpi-inline.h
(0 . 0)(1 . 126)
1706 /* mpi-inline.h - Internal to the Multi Precision Integers
1707 * Copyright (C) 1994, 1996, 1998, 1999 Free Software Foundation, Inc.
1708 *
1709 * This file is part of GnuPG.
1710 *
1711 * GnuPG is free software; you can redistribute it and/or modify
1712 * it under the terms of the GNU General Public License as published by
1713 * the Free Software Foundation; either version 3 of the License, or
1714 * (at your option) any later version.
1715 *
1716 * GnuPG is distributed in the hope that it will be useful,
1717 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1718 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1719 * GNU General Public License for more details.
1720 *
1721 * You should have received a copy of the GNU General Public License
1722 * along with this program; if not, see <http://www.gnu.org/licenses/>.
1723 *
1724 * Note: This code is heavily based on the GNU MP Library.
1725 * Actually it's the same code with only minor changes in the
1726 * way the data is stored; this is to support the abstraction
1727 * of an optional secure memory allocation which may be used
1728 * to avoid revealing of sensitive data due to paging etc.
1729 * The GNU MP Library itself is published under the LGPL;
1730 * however I decided to publish this code under the plain GPL.
1731 */
1732
1733 #ifndef G10_MPI_INLINE_H
1734 #define G10_MPI_INLINE_H
1735
1736 #ifndef G10_MPI_INLINE_DECL
1737 #define G10_MPI_INLINE_DECL extern __inline__
1738 #endif
1739
1740 G10_MPI_INLINE_DECL mpi_limb_t
1741 mpihelp_add_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
1742 mpi_size_t s1_size, mpi_limb_t s2_limb)
1743 {
1744 mpi_limb_t x;
1745
1746 x = *s1_ptr++;
1747 s2_limb += x;
1748 *res_ptr++ = s2_limb;
1749 if( s2_limb < x ) { /* sum is less than the left operand: handle carry */
1750 while( --s1_size ) {
1751 x = *s1_ptr++ + 1; /* add carry */
1752 *res_ptr++ = x; /* and store */
1753 if( x ) /* not 0 (no overflow): we can stop */
1754 goto leave;
1755 }
1756 return 1; /* return carry (size of s1 to small) */
1757 }
1758
1759 leave:
1760 if( res_ptr != s1_ptr ) { /* not the same variable */
1761 mpi_size_t i; /* copy the rest */
1762 for( i=0; i < s1_size-1; i++ )
1763 res_ptr[i] = s1_ptr[i];
1764 }
1765 return 0; /* no carry */
1766 }
1767
1768
1769
1770 G10_MPI_INLINE_DECL mpi_limb_t
1771 mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
1772 mpi_ptr_t s2_ptr, mpi_size_t s2_size)
1773 {
1774 mpi_limb_t cy = 0;
1775
1776 if( s2_size )
1777 cy = mpihelp_add_n( res_ptr, s1_ptr, s2_ptr, s2_size );
1778
1779 if( s1_size - s2_size )
1780 cy = mpihelp_add_1( res_ptr + s2_size, s1_ptr + s2_size,
1781 s1_size - s2_size, cy);
1782 return cy;
1783 }
1784
1785
1786 G10_MPI_INLINE_DECL mpi_limb_t
1787 mpihelp_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
1788 mpi_size_t s1_size, mpi_limb_t s2_limb )
1789 {
1790 mpi_limb_t x;
1791
1792 x = *s1_ptr++;
1793 s2_limb = x - s2_limb;
1794 *res_ptr++ = s2_limb;
1795 if( s2_limb > x ) {
1796 while( --s1_size ) {
1797 x = *s1_ptr++;
1798 *res_ptr++ = x - 1;
1799 if( x )
1800 goto leave;
1801 }
1802 return 1;
1803 }
1804
1805 leave:
1806 if( res_ptr != s1_ptr ) {
1807 mpi_size_t i;
1808 for( i=0; i < s1_size-1; i++ )
1809 res_ptr[i] = s1_ptr[i];
1810 }
1811 return 0;
1812 }
1813
1814
1815
1816 G10_MPI_INLINE_DECL mpi_limb_t
1817 mpihelp_sub( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
1818 mpi_ptr_t s2_ptr, mpi_size_t s2_size)
1819 {
1820 mpi_limb_t cy = 0;
1821
1822 if( s2_size )
1823 cy = mpihelp_sub_n(res_ptr, s1_ptr, s2_ptr, s2_size);
1824
1825 if( s1_size - s2_size )
1826 cy = mpihelp_sub_1(res_ptr + s2_size, s1_ptr + s2_size,
1827 s1_size - s2_size, cy);
1828 return cy;
1829 }
1830
1831 #endif /*G10_MPI_INLINE_H*/
-
+ 98C4253D69C7531F96DC7631D3D26C5733D5104A3DDBD9EAFD622F8AACD8619E71ABB55D0C951B148E9D33887DAB0EDF2CBD9C9B38CA908BC8E04ED930943FDE
mpi/include/mpi-internal.h
(0 . 0)(1 . 290)
1836 /* mpi-internal.h - Internal to the Multi Precision Integers
1837 * Copyright (C) 1994, 1996 Free Software Foundation, Inc.
1838 * Copyright (C) 1998, 2000 Free Software Foundation, Inc.
1839 *
1840 * This file is part of GnuPG.
1841 *
1842 * GnuPG is free software; you can redistribute it and/or modify
1843 * it under the terms of the GNU General Public License as published by
1844 * the Free Software Foundation; either version 3 of the License, or
1845 * (at your option) any later version.
1846 *
1847 * GnuPG is distributed in the hope that it will be useful,
1848 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1849 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1850 * GNU General Public License for more details.
1851 *
1852 * You should have received a copy of the GNU General Public License
1853 * along with this program; if not, see <http://www.gnu.org/licenses/>.
1854 *
1855 * Note: This code is heavily based on the GNU MP Library.
1856 * Actually it's the same code with only minor changes in the
1857 * way the data is stored; this is to support the abstraction
1858 * of an optional secure memory allocation which may be used
1859 * to avoid revealing of sensitive data due to paging etc.
1860 * The GNU MP Library itself is published under the LGPL;
1861 * however I decided to publish this code under the plain GPL.
1862 */
1863
1864 #ifndef G10_MPI_INTERNAL_H
1865 #define G10_MPI_INTERNAL_H
1866
1867 #include "mpi.h"
1868 #include "mpi-asm-defs.h"
1869
1870 #if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT
1871 typedef unsigned int mpi_limb_t;
1872 typedef signed int mpi_limb_signed_t;
1873 #elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG
1874 typedef unsigned long int mpi_limb_t;
1875 typedef signed long int mpi_limb_signed_t;
1876 #elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG
1877 typedef unsigned long long int mpi_limb_t;
1878 typedef signed long long int mpi_limb_signed_t;
1879 #elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT
1880 typedef unsigned short int mpi_limb_t;
1881 typedef signed short int mpi_limb_signed_t;
1882 #else
1883 #error BYTES_PER_MPI_LIMB does not match any C type
1884 #endif
1885 #define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB)
1886
1887
1888 struct gcry_mpi {
1889 int alloced; /* array size (# of allocated limbs) */
1890 int nlimbs; /* number of valid limbs */
1891 unsigned int nbits; /* the real number of valid bits (info only) */
1892 int sign; /* indicates a negative number */
1893 unsigned flags; /* bit 0: array must be allocated in secure memory space */
1894 /* bit 1: not used */
1895 /* bit 2: the limb is a pointer to some xmalloced data */
1896 mpi_limb_t *d; /* array with the limbs */
1897 };
1898
1899
1900
1901 /* If KARATSUBA_THRESHOLD is not already defined, define it to a
1902 * value which is good on most machines. */
1903
1904 /* tested 4, 16, 32 and 64, where 16 gave the best performance when
1905 * checking a 768 and a 1024 bit ElGamal signature.
1906 * (wk 22.12.97) */
1907 #ifndef KARATSUBA_THRESHOLD
1908 #define KARATSUBA_THRESHOLD 16
1909 #endif
1910
1911 /* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */
1912 #if KARATSUBA_THRESHOLD < 2
1913 #undef KARATSUBA_THRESHOLD
1914 #define KARATSUBA_THRESHOLD 2
1915 #endif
1916
1917
1918 typedef mpi_limb_t *mpi_ptr_t; /* pointer to a limb */
1919 typedef int mpi_size_t; /* (must be a signed type) */
1920
1921 #define ABS(x) (x >= 0 ? x : -x)
1922 #define MIN(l,o) ((l) < (o) ? (l) : (o))
1923 #define MAX(h,i) ((h) > (i) ? (h) : (i))
1924 #define RESIZE_IF_NEEDED(a,b) \
1925 do { \
1926 if( (a)->alloced < (b) ) \
1927 mpi_resize((a), (b)); \
1928 } while(0)
1929
1930 /* Copy N limbs from S to D. */
1931 #define MPN_COPY( d, s, n) \
1932 do { \
1933 mpi_size_t _i; \
1934 for( _i = 0; _i < (n); _i++ ) \
1935 (d)[_i] = (s)[_i]; \
1936 } while(0)
1937
1938 #define MPN_COPY_INCR( d, s, n) \
1939 do { \
1940 mpi_size_t _i; \
1941 for( _i = 0; _i < (n); _i++ ) \
1942 (d)[_i] = (d)[_i]; \
1943 } while (0)
1944
1945 #define MPN_COPY_DECR( d, s, n ) \
1946 do { \
1947 mpi_size_t _i; \
1948 for( _i = (n)-1; _i >= 0; _i--) \
1949 (d)[_i] = (s)[_i]; \
1950 } while(0)
1951
1952 /* Zero N limbs at D */
1953 #define MPN_ZERO(d, n) \
1954 do { \
1955 int _i; \
1956 for( _i = 0; _i < (n); _i++ ) \
1957 (d)[_i] = 0; \
1958 } while (0)
1959
1960 #define MPN_NORMALIZE(d, n) \
1961 do { \
1962 while( (n) > 0 ) { \
1963 if( (d)[(n)-1] ) \
1964 break; \
1965 (n)--; \
1966 } \
1967 } while(0)
1968
1969 #define MPN_NORMALIZE_NOT_ZERO(d, n) \
1970 do { \
1971 for(;;) { \
1972 if( (d)[(n)-1] ) \
1973 break; \
1974 (n)--; \
1975 } \
1976 } while(0)
1977
1978 #define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
1979 do { \
1980 if( (size) < KARATSUBA_THRESHOLD ) \
1981 mul_n_basecase (prodp, up, vp, size); \
1982 else \
1983 mul_n (prodp, up, vp, size, tspace); \
1984 } while (0);
1985
1986
1987 /* Divide the two-limb number in (NH,,NL) by D, with DI being the largest
1988 * limb not larger than (2**(2*BITS_PER_MP_LIMB))/D - (2**BITS_PER_MP_LIMB).
1989 * If this would yield overflow, DI should be the largest possible number
1990 * (i.e., only ones). For correct operation, the most significant bit of D
1991 * has to be set. Put the quotient in Q and the remainder in R.
1992 */
1993 #define UDIV_QRNND_PREINV(q, r, nh, nl, d, di) \
1994 do { \
1995 mpi_limb_t _q, _ql, _r; \
1996 mpi_limb_t _xh, _xl; \
1997 umul_ppmm (_q, _ql, (nh), (di)); \
1998 _q += (nh); /* DI is 2**BITS_PER_MPI_LIMB too small */ \
1999 umul_ppmm (_xh, _xl, _q, (d)); \
2000 sub_ddmmss (_xh, _r, (nh), (nl), _xh, _xl); \
2001 if( _xh ) { \
2002 sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
2003 _q++; \
2004 if( _xh) { \
2005 sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
2006 _q++; \
2007 } \
2008 } \
2009 if( _r >= (d) ) { \
2010 _r -= (d); \
2011 _q++; \
2012 } \
2013 (r) = _r; \
2014 (q) = _q; \
2015 } while (0)
2016
2017
2018 /*-- mpiutil.c --*/
2019 #ifdef M_DEBUG
2020 #define mpi_alloc_limb_space(n,f) mpi_debug_alloc_limb_space((n),(f), M_DBGINFO( __LINE__ ) )
2021 #define mpi_free_limb_space(n) mpi_debug_free_limb_space((n), M_DBGINFO( __LINE__ ) )
2022 mpi_ptr_t mpi_debug_alloc_limb_space( unsigned nlimbs, int sec, const char *info );
2023 void mpi_debug_free_limb_space( mpi_ptr_t a, const char *info );
2024 #else
2025 mpi_ptr_t mpi_alloc_limb_space( unsigned nlimbs, int sec );
2026 void mpi_free_limb_space( mpi_ptr_t a );
2027 #endif
2028 void mpi_assign_limb_space( MPI a, mpi_ptr_t ap, unsigned nlimbs );
2029
2030 /*-- mpi-bit.c --*/
2031 void mpi_rshift_limbs( MPI a, unsigned int count );
2032 void mpi_lshift_limbs( MPI a, unsigned int count );
2033
2034
2035 /*-- mpihelp-add.c --*/
2036 mpi_limb_t mpihelp_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
2037 mpi_size_t s1_size, mpi_limb_t s2_limb );
2038 mpi_limb_t mpihelp_add_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
2039 mpi_ptr_t s2_ptr, mpi_size_t size);
2040 mpi_limb_t mpihelp_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
2041 mpi_ptr_t s2_ptr, mpi_size_t s2_size);
2042
2043 /*-- mpihelp-sub.c --*/
2044 mpi_limb_t mpihelp_sub_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
2045 mpi_size_t s1_size, mpi_limb_t s2_limb );
2046 mpi_limb_t mpihelp_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
2047 mpi_ptr_t s2_ptr, mpi_size_t size);
2048 mpi_limb_t mpihelp_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
2049 mpi_ptr_t s2_ptr, mpi_size_t s2_size);
2050
2051 /*-- mpihelp-cmp.c --*/
2052 int mpihelp_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size );
2053
2054 /*-- mpihelp-mul.c --*/
2055
2056 struct karatsuba_ctx {
2057 struct karatsuba_ctx *next;
2058 mpi_ptr_t tspace;
2059 mpi_size_t tspace_size;
2060 mpi_ptr_t tp;
2061 mpi_size_t tp_size;
2062 };
2063
2064 void mpihelp_release_karatsuba_ctx( struct karatsuba_ctx *ctx );
2065
2066 mpi_limb_t mpihelp_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
2067 mpi_size_t s1_size, mpi_limb_t s2_limb);
2068 mpi_limb_t mpihelp_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
2069 mpi_size_t s1_size, mpi_limb_t s2_limb);
2070 void mpihelp_mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp,
2071 mpi_size_t size);
2072 mpi_limb_t mpihelp_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
2073 mpi_ptr_t vp, mpi_size_t vsize);
2074 void mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size );
2075 void mpih_sqr_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size,
2076 mpi_ptr_t tspace);
2077
2078 void mpihelp_mul_karatsuba_case( mpi_ptr_t prodp,
2079 mpi_ptr_t up, mpi_size_t usize,
2080 mpi_ptr_t vp, mpi_size_t vsize,
2081 struct karatsuba_ctx *ctx );
2082
2083
2084 /*-- mpihelp-mul_1.c (or xxx/cpu/ *.S) --*/
2085 mpi_limb_t mpihelp_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
2086 mpi_size_t s1_size, mpi_limb_t s2_limb);
2087
2088 /*-- mpihelp-div.c --*/
2089 mpi_limb_t mpihelp_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
2090 mpi_limb_t divisor_limb);
2091 mpi_limb_t mpihelp_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs,
2092 mpi_ptr_t np, mpi_size_t nsize,
2093 mpi_ptr_t dp, mpi_size_t dsize);
2094 mpi_limb_t mpihelp_divmod_1( mpi_ptr_t quot_ptr,
2095 mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
2096 mpi_limb_t divisor_limb);
2097
2098 /*-- mpihelp-shift.c --*/
2099 mpi_limb_t mpihelp_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
2100 unsigned cnt);
2101 mpi_limb_t mpihelp_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
2102 unsigned cnt);
2103
2104
2105 /* Define stuff for longlong.h. */
2106 #define W_TYPE_SIZE BITS_PER_MPI_LIMB
2107 typedef mpi_limb_t UWtype;
2108 typedef unsigned int UHWtype;
2109 #if defined (__GNUC__)
2110 typedef unsigned int UQItype __attribute__ ((mode (QI)));
2111 typedef int SItype __attribute__ ((mode (SI)));
2112 typedef unsigned int USItype __attribute__ ((mode (SI)));
2113 typedef int DItype __attribute__ ((mode (DI)));
2114 typedef unsigned int UDItype __attribute__ ((mode (DI)));
2115 #else
2116 typedef unsigned char UQItype;
2117 typedef long SItype;
2118 typedef unsigned long USItype;
2119 #endif
2120
2121 #ifdef __GNUC__
2122 #include "mpi-inline.h"
2123 #endif
2124
2125 #endif /*G10_MPI_INTERNAL_H*/
-
+ 85D1DE1E79681B0CECE4CAEA7CA324374FB41317C449585E8CD4D23FAE4EF10923285545645FAC2921D3C53A0C897E33DA32D895B9BD0B761F696D0D8E036479
mpi/include/ttyio.h
(0 . 0)(1 . 58)
2130 /* ttyio.h
2131 * Copyright (C) 1998, 1999, 2000, 2001, 2005 Free Software Foundation, Inc.
2132 *
2133 * This file is part of GNUPG.
2134 *
2135 * GNUPG is free software; you can redistribute it and/or modify
2136 * it under the terms of the GNU General Public License as published by
2137 * the Free Software Foundation; either version 3 of the License, or
2138 * (at your option) any later version.
2139 *
2140 * GNUPG is distributed in the hope that it will be useful,
2141 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2142 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2143 * GNU General Public License for more details.
2144 *
2145 * You should have received a copy of the GNU General Public License
2146 * along with this program; if not, see <http://www.gnu.org/licenses/>.
2147 */
2148 #ifndef G10_TTYIO_H
2149 #define G10_TTYIO_H
2150
2151 #ifdef HAVE_LIBREADLINE
2152 #include <stdio.h>
2153 #include <readline/readline.h>
2154 #endif
2155
2156 const char *tty_get_ttyname (void);
2157 int tty_batchmode( int onoff );
2158 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
2159 void tty_printf (const char *fmt, ... ) __attribute__ ((format (printf,1,2)));
2160 void tty_fprintf (FILE *fp, const char *fmt, ... )
2161 __attribute__ ((format (printf,2,3)));
2162 #else
2163 void tty_printf (const char *fmt, ... );
2164 void tty_fprintf (FILE *fp, const char *fmt, ... );
2165 #endif
2166 void tty_print_string( const byte *p, size_t n );
2167 void tty_print_utf8_string( const byte *p, size_t n );
2168 void tty_print_utf8_string2( const byte *p, size_t n, size_t max_n );
2169 char *tty_get( const char *prompt );
2170 char *tty_get_hidden( const char *prompt );
2171 void tty_kill_prompt(void);
2172 int tty_get_answer_is_yes( const char *prompt );
2173 int tty_no_terminal(int onoff);
2174
2175 #ifdef HAVE_LIBREADLINE
2176 void tty_enable_completion(rl_completion_func_t *completer);
2177 void tty_disable_completion(void);
2178 #else
2179 /* Use a macro to stub out these functions since a macro has no need
2180 to typedef a "rl_completion_func_t" which would be undefined
2181 without readline. */
2182 #define tty_enable_completion(x)
2183 #define tty_disable_completion()
2184 #endif
2185 void tty_cleanup_after_signal (void);
2186
2187 #endif /*G10_TTYIO_H*/
-
+ D355F8BB711647E95451CF2D53F8C496013D9C797ACC81560FAE155C5850823C880D647347426A4562DA568A6CDE708FDCCBD1E881568816156C0801C7E47FD7
mpi/include/types.h
(0 . 0)(1 . 142)
2192 /* types.h - some common typedefs
2193 * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
2194 *
2195 * This file is part of GNUPG.
2196 *
2197 * GNUPG is free software; you can redistribute it and/or modify
2198 * it under the terms of the GNU General Public License as published by
2199 * the Free Software Foundation; either version 3 of the License, or
2200 * (at your option) any later version.
2201 *
2202 * GNUPG is distributed in the hope that it will be useful,
2203 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2204 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2205 * GNU General Public License for more details.
2206 *
2207 * You should have received a copy of the GNU General Public License
2208 * along with this program; if not, see <http://www.gnu.org/licenses/>.
2209 */
2210
2211 #ifndef G10_TYPES_H
2212 #define G10_TYPES_H
2213
2214 #ifdef HAVE_INTTYPES_H
2215 /* For uint64_t */
2216 #include <inttypes.h>
2217 #endif
2218
2219 /* The AC_CHECK_SIZEOF() in configure fails for some machines.
2220 * we provide some fallback values here */
2221 #if !SIZEOF_UNSIGNED_SHORT
2222 #undef SIZEOF_UNSIGNED_SHORT
2223 #define SIZEOF_UNSIGNED_SHORT 2
2224 #endif
2225 #if !SIZEOF_UNSIGNED_INT
2226 #undef SIZEOF_UNSIGNED_INT
2227 #define SIZEOF_UNSIGNED_INT 4
2228 #endif
2229 #if !SIZEOF_UNSIGNED_LONG
2230 #undef SIZEOF_UNSIGNED_LONG
2231 #define SIZEOF_UNSIGNED_LONG 4
2232 #endif
2233
2234
2235 #include <sys/types.h>
2236
2237
2238 #ifndef HAVE_BYTE_TYPEDEF
2239 #undef byte /* maybe there is a macro with this name */
2240 #ifndef __riscos__
2241 typedef unsigned char byte;
2242 #else
2243 /* Norcroft treats char = unsigned char as legal assignment
2244 but char* = unsigned char* as illegal assignment
2245 and the same applies to the signed variants as well */
2246 typedef char byte;
2247 #endif
2248 #define HAVE_BYTE_TYPEDEF
2249 #endif
2250
2251 #ifndef HAVE_USHORT_TYPEDEF
2252 #undef ushort /* maybe there is a macro with this name */
2253 typedef unsigned short ushort;
2254 #define HAVE_USHORT_TYPEDEF
2255 #endif
2256
2257 #ifndef HAVE_ULONG_TYPEDEF
2258 #undef ulong /* maybe there is a macro with this name */
2259 typedef unsigned long ulong;
2260 #define HAVE_ULONG_TYPEDEF
2261 #endif
2262
2263 #ifndef HAVE_U16_TYPEDEF
2264 #undef u16 /* maybe there is a macro with this name */
2265 #if SIZEOF_UNSIGNED_INT == 2
2266 typedef unsigned int u16;
2267 #elif SIZEOF_UNSIGNED_SHORT == 2
2268 typedef unsigned short u16;
2269 #else
2270 #error no typedef for u16
2271 #endif
2272 #define HAVE_U16_TYPEDEF
2273 #endif
2274
2275 #ifndef HAVE_U32_TYPEDEF
2276 #undef u32 /* maybe there is a macro with this name */
2277 #if SIZEOF_UNSIGNED_INT == 4
2278 typedef unsigned int u32;
2279 #elif SIZEOF_UNSIGNED_LONG == 4
2280 typedef unsigned long u32;
2281 #else
2282 #error no typedef for u32
2283 #endif
2284 #define HAVE_U32_TYPEDEF
2285 #endif
2286
2287 /****************
2288 * Warning: Some systems segfault when this u64 typedef and
2289 * the dummy code in cipher/md.c is not available. Examples are
2290 * Solaris and IRIX.
2291 */
2292 #ifndef HAVE_U64_TYPEDEF
2293 #undef u64 /* maybe there is a macro with this name */
2294 #if SIZEOF_UINT64_T == 8
2295 typedef uint64_t u64;
2296 #define U64_C(c) (UINT64_C(c))
2297 #define HAVE_U64_TYPEDEF
2298 #elif SIZEOF_UNSIGNED_INT == 8
2299 typedef unsigned int u64;
2300 #define U64_C(c) (c ## U)
2301 #define HAVE_U64_TYPEDEF
2302 #elif SIZEOF_UNSIGNED_LONG == 8
2303 typedef unsigned long u64;
2304 #define U64_C(c) (c ## UL)
2305 #define HAVE_U64_TYPEDEF
2306 #elif SIZEOF_UNSIGNED_LONG_LONG == 8
2307 typedef unsigned long long u64;
2308 #define U64_C(c) (c ## ULL)
2309 #define HAVE_U64_TYPEDEF
2310 #endif
2311 #endif
2312
2313 typedef union {
2314 int a;
2315 short b;
2316 char c[1];
2317 long d;
2318 #ifdef HAVE_U64_TYPEDEF
2319 u64 e;
2320 #endif
2321 float f;
2322 double g;
2323 } PROPERLY_ALIGNED_TYPE;
2324
2325 struct string_list {
2326 struct string_list *next;
2327 unsigned int flags;
2328 char d[1];
2329 };
2330 typedef struct string_list *STRLIST;
2331 typedef struct string_list *strlist_t;
2332
2333 #endif /*G10_TYPES_H*/
-
+ 5B4ADEDB0DDA25D37413FD81037EF2D94722CEE3B58B5A5314DA3816308540588319A280819E272845D154B6F2FDBDCECE3A73C15B2802F33BC6BFE484F0B4A5
mpi/include/util.h
(0 . 0)(1 . 334)
2338 /* util.h
2339 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
2340 * 2006 Free Software Foundation, Inc.
2341 *
2342 * This file is part of GNUPG.
2343 *
2344 * GNUPG is free software; you can redistribute it and/or modify
2345 * it under the terms of the GNU General Public License as published by
2346 * the Free Software Foundation; either version 3 of the License, or
2347 * (at your option) any later version.
2348 *
2349 * GNUPG is distributed in the hope that it will be useful,
2350 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2351 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2352 * GNU General Public License for more details.
2353 *
2354 * You should have received a copy of the GNU General Public License
2355 * along with this program; if not, see <http://www.gnu.org/licenses/>.
2356 */
2357 #ifndef G10_UTIL_H
2358 #define G10_UTIL_H
2359
2360 #if defined (_WIN32) || defined (__CYGWIN32__)
2361 #include <stdarg.h>
2362 #endif
2363
2364 #include "types.h"
2365 #include "errors.h"
2366 #include "types.h"
2367 #include "mpi.h"
2368 #include "compat.h"
2369
2370 typedef struct {
2371 int *argc; /* pointer to argc (value subject to change) */
2372 char ***argv; /* pointer to argv (value subject to change) */
2373 unsigned flags; /* Global flags (DO NOT CHANGE) */
2374 int err; /* print error about last option */
2375 /* 1 = warning, 2 = abort */
2376 int r_opt; /* return option */
2377 int r_type; /* type of return value (0 = no argument found)*/
2378 union {
2379 int ret_int;
2380 long ret_long;
2381 ulong ret_ulong;
2382 char *ret_str;
2383 } r; /* Return values */
2384 struct {
2385 int idx;
2386 int inarg;
2387 int stopped;
2388 const char *last;
2389 void *aliases;
2390 const void *cur_alias;
2391 } internal; /* DO NOT CHANGE */
2392 } ARGPARSE_ARGS;
2393
2394 typedef struct {
2395 int short_opt;
2396 const char *long_opt;
2397 unsigned flags;
2398 const char *description; /* optional option description */
2399 } ARGPARSE_OPTS;
2400
2401 /*-- logger.c --*/
2402 void log_set_logfile( const char *name, int fd );
2403 FILE *log_stream(void);
2404 void g10_log_print_prefix(const char *text);
2405 void log_set_name( const char *name );
2406 const char *log_get_name(void);
2407 void log_set_pid( int pid );
2408 int log_get_errorcount( int clear );
2409 void log_inc_errorcount(void);
2410 int log_set_strict(int val);
2411 void g10_log_hexdump( const char *text, const char *buf, size_t len );
2412
2413 #if defined (__riscos__) \
2414 || (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ))
2415 void g10_log_bug( const char *fmt, ... )
2416 __attribute__ ((noreturn, format (printf,1,2)));
2417 void g10_log_bug0( const char *, int, const char * ) __attribute__ ((noreturn));
2418 void g10_log_fatal( const char *fmt, ... )
2419 __attribute__ ((noreturn, format (printf,1,2)));
2420 void g10_log_error( const char *fmt, ... ) __attribute__ ((format (printf,1,2)));
2421 void g10_log_info( const char *fmt, ... ) __attribute__ ((format (printf,1,2)));
2422 void g10_log_warning( const char *fmt, ... ) __attribute__ ((format (printf,1,2)));
2423 void g10_log_debug( const char *fmt, ... ) __attribute__ ((format (printf,1,2)));
2424 #ifndef __riscos__
2425 #define BUG() g10_log_bug0( __FILE__ , __LINE__, __FUNCTION__ )
2426 #else
2427 #define BUG() g10_log_bug0( __FILE__ , __LINE__, __func__ )
2428 #endif
2429 #else
2430 void g10_log_bug( const char *fmt, ... );
2431 void g10_log_bug0( const char *, int );
2432 void g10_log_fatal( const char *fmt, ... );
2433 void g10_log_error( const char *fmt, ... );
2434 void g10_log_info( const char *fmt, ... );
2435 void g10_log_warning( const char *fmt, ... );
2436 void g10_log_debug( const char *fmt, ... );
2437 #define BUG() g10_log_bug0( __FILE__ , __LINE__ )
2438 #endif
2439
2440 #define log_hexdump g10_log_hexdump
2441 #define log_bug g10_log_bug
2442 #define log_bug0 g10_log_bug0
2443 #define log_fatal g10_log_fatal
2444 #define log_error g10_log_error
2445 #define log_info g10_log_info
2446 #define log_warning g10_log_warning
2447 #define log_debug g10_log_debug
2448
2449
2450 /*-- errors.c --*/
2451 const char * g10_errstr( int no );
2452
2453 /*-- argparse.c --*/
2454 int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts);
2455 int optfile_parse( FILE *fp, const char *filename, unsigned *lineno,
2456 ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts);
2457 void usage( int level );
2458 const char *default_strusage( int level );
2459
2460
2461 /*-- (main program) --*/
2462 const char *strusage( int level );
2463
2464
2465 /*-- dotlock.c --*/
2466 struct dotlock_handle;
2467 typedef struct dotlock_handle *DOTLOCK;
2468
2469 void disable_dotlock(void);
2470 DOTLOCK create_dotlock( const char *file_to_lock );
2471 void destroy_dotlock ( DOTLOCK h );
2472 int make_dotlock( DOTLOCK h, long timeout );
2473 int release_dotlock( DOTLOCK h );
2474 void remove_lockfiles (void);
2475
2476 /*-- fileutil.c --*/
2477 char * make_basename(const char *filepath, const char *inputpath);
2478 char * make_dirname(const char *filepath);
2479 char *make_filename( const char *first_part, ... );
2480 int compare_filenames( const char *a, const char *b );
2481 int same_file_p (const char *name1, const char *name2);
2482 const char *print_fname_stdin( const char *s );
2483 const char *print_fname_stdout( const char *s );
2484 int is_file_compressed(const char *s, int *r_status);
2485
2486 /*-- miscutil.c --*/
2487 u32 make_timestamp(void);
2488 u32 scan_isodatestr( const char *string );
2489 u32 isotime2seconds (const char *string);
2490 const char *strtimevalue( u32 stamp );
2491 const char *strtimestamp( u32 stamp ); /* GMT */
2492 const char *isotimestamp( u32 stamp ); /* GMT with hh:mm:ss */
2493 const char *asctimestamp( u32 stamp ); /* localized */
2494 void print_string( FILE *fp, const byte *p, size_t n, int delim );
2495 void print_string2( FILE *fp, const byte *p, size_t n, int delim, int delim2 );
2496 void print_utf8_string( FILE *fp, const byte *p, size_t n );
2497 void print_utf8_string2( FILE *fp, const byte *p, size_t n, int delim);
2498 char *make_printable_string( const byte *p, size_t n, int delim );
2499 int answer_is_yes_no_default( const char *s, int def_answer );
2500 int answer_is_yes( const char *s );
2501 int answer_is_yes_no_quit( const char *s );
2502 int answer_is_okay_cancel (const char *s, int def_answer);
2503 int match_multistr(const char *multistr,const char *match);
2504
2505 /*-- strgutil.c --*/
2506 void free_strlist( STRLIST sl );
2507 #define FREE_STRLIST(a) do { free_strlist((a)); (a) = NULL ; } while(0)
2508 STRLIST add_to_strlist( STRLIST *list, const char *string );
2509 STRLIST add_to_strlist2( STRLIST *list, const char *string, int is_utf8 );
2510 STRLIST append_to_strlist( STRLIST *list, const char *string );
2511 STRLIST append_to_strlist2( STRLIST *list, const char *string, int is_utf8 );
2512 STRLIST strlist_prev( STRLIST head, STRLIST node );
2513 STRLIST strlist_last( STRLIST node );
2514 char *pop_strlist( STRLIST *list );
2515 const char *memistr( const char *buf, size_t buflen, const char *sub );
2516 const char *ascii_memistr( const char *buf, size_t buflen, const char *sub );
2517 char *mem2str( char *, const void *, size_t);
2518 char *trim_spaces( char *string );
2519 unsigned int trim_trailing_chars( byte *line, unsigned int len,
2520 const char *trimchars);
2521 unsigned int trim_trailing_ws( byte *line, unsigned len );
2522 unsigned int check_trailing_chars( const byte *line, unsigned int len,
2523 const char *trimchars );
2524 unsigned int check_trailing_ws( const byte *line, unsigned int len );
2525 int string_count_chr( const char *string, int c );
2526 int set_native_charset( const char *newset );
2527 const char* get_native_charset(void);
2528 char *native_to_utf8( const char *string );
2529 char *utf8_to_native( const char *string, size_t length, int delim);
2530 char *string_to_utf8 (const char *string);
2531
2532 int ascii_isupper (int c);
2533 int ascii_islower (int c);
2534 int ascii_memcasecmp( const char *a, const char *b, size_t n);
2535
2536 #ifndef HAVE_STPCPY
2537 char *stpcpy(char *a,const char *b);
2538 #endif
2539 #ifndef HAVE_STRLWR
2540 char *strlwr(char *a);
2541 #endif
2542 #ifndef HAVE_STRCASECMP
2543 int strcasecmp( const char *, const char *b);
2544 #endif
2545 #ifndef HAVE_STRNCASECMP
2546 int strncasecmp (const char *, const char *b, size_t n);
2547 #endif
2548 #ifndef HAVE_STRTOUL
2549 #define strtoul(a,b,c) ((unsigned long)strtol((a),(b),(c)))
2550 #endif
2551 #ifndef HAVE_MEMMOVE
2552 #define memmove(d, s, n) bcopy((s), (d), (n))
2553 #endif
2554
2555 /*-- membuf.c --*/
2556 /* The definition of the structure is private, we only need it here,
2557 so it can be allocated on the stack. */
2558 struct private_membuf_s {
2559 size_t len;
2560 size_t size;
2561 char *buf;
2562 int out_of_core;
2563 };
2564
2565 typedef struct private_membuf_s membuf_t;
2566
2567 void init_membuf (membuf_t *mb, int initiallen);
2568 void put_membuf (membuf_t *mb, const void *buf, size_t len);
2569 void *get_membuf (membuf_t *mb, size_t *len);
2570
2571
2572
2573 #if defined (_WIN32)
2574 /*-- w32reg.c --*/
2575 char *read_w32_registry_string( const char *root,
2576 const char *dir, const char *name );
2577 int write_w32_registry_string(const char *root, const char *dir,
2578 const char *name, const char *value);
2579
2580 #endif /*_WIN32*/
2581
2582 /*-- strgutil.c --*/
2583 char *xasprintf (const char *fmt, ...);
2584 char *xtryasprintf (const char *fmt, ...);
2585
2586
2587 /*-- pka.c --*/
2588 char *get_pka_info (const char *address, unsigned char *fpr);
2589
2590 /*-- cert.c --*/
2591 int get_cert(const char *name,size_t max_size,IOBUF *iobuf,
2592 unsigned char **fpr,size_t *fpr_len,char **url);
2593
2594 /*-- convert.c --*/
2595 int hex2bin (const char *string, void *buffer, size_t length);
2596 int hexcolon2bin (const char *string, void *buffer, size_t length);
2597 char *bin2hex (const void *buffer, size_t length, char *stringbuf);
2598 char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf);
2599 const char *hex2str (const char *hexstring,
2600 char *buffer, size_t bufsize, size_t *buflen);
2601 char *hex2str_alloc (const char *hexstring, size_t *r_count);
2602
2603
2604 /**** other missing stuff ****/
2605 #ifndef HAVE_ATEXIT /* For SunOS */
2606 #define atexit(a) (on_exit((a),0))
2607 #endif
2608
2609 #ifndef HAVE_RAISE
2610 #define raise(a) kill(getpid(), (a))
2611 #endif
2612
2613 /*-- Replacement functions from funcname.c --*/
2614
2615
2616
2617 /******** some macros ************/
2618 #ifndef STR
2619 #define STR(v) #v
2620 #endif
2621 #define STR2(v) STR(v)
2622 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
2623 #define DIMof(type,member) DIM(((type *)0)->member)
2624
2625 #define wipememory2(_ptr,_set,_len) do { volatile char *_vptr=(volatile char *)(_ptr); size_t _vlen=(_len); while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } } while(0)
2626 #define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
2627
2628 /*-- macros to replace ctype ones and avoid locale problems --*/
2629 #define spacep(p) (*(p) == ' ' || *(p) == '\t')
2630 #define digitp(p) (*(p) >= '0' && *(p) <= '9')
2631 #define hexdigitp(a) (digitp (a) \
2632 || (*(a) >= 'A' && *(a) <= 'F') \
2633 || (*(a) >= 'a' && *(a) <= 'f'))
2634 /* the atoi macros assume that the buffer has only valid digits */
2635 #define atoi_1(p) (*(p) - '0' )
2636 #define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1))
2637 #define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2))
2638 #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
2639 *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
2640 #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
2641
2642 /******* RISC OS stuff ***********/
2643 #ifdef __riscos__
2644 int riscos_load_module(const char *name, const char * const path[], int fatal);
2645 int riscos_get_filetype_from_string(const char *string, int len);
2646 int riscos_get_filetype(const char *filename);
2647 void riscos_set_filetype_by_number(const char *filename, int type);
2648 void riscos_set_filetype_by_mimetype(const char *filename, const char *mimetype);
2649 pid_t riscos_getpid(void);
2650 int riscos_kill(pid_t pid, int sig);
2651 int riscos_access(const char *path, int amode);
2652 int riscos_getchar(void);
2653 char *riscos_make_basename(const char *filepath, const char *inputpath);
2654 int riscos_check_regexp(const char *exp, const char *string, int debug);
2655 int riscos_fdopenfile(const char *filename, const int allow_write);
2656 void riscos_close_fds(void);
2657 int riscos_renamefile(const char *old, const char *new);
2658 char *riscos_gstrans(const char *old);
2659 void riscos_not_implemented(const char *feature);
2660 #ifdef DEBUG
2661 void riscos_dump_fdlist(void);
2662 void riscos_list_openfiles(void);
2663 #endif
2664 #ifndef __RISCOS__C__
2665 #define getpid riscos_getpid
2666 #define kill(a,b) riscos_kill((a),(b))
2667 #define access(a,b) riscos_access((a),(b))
2668 #endif /* !__RISCOS__C__ */
2669 #endif /* __riscos__ */
2670
2671 #endif /*G10_UTIL_H*/
-
+ C5DDDD9D52900BA3D847422F9DBA2799BE2954AD9CCA3B9AA6FB1654DD89EE00575C52D15BD65E98D3054D4646943372CA8AD591F610EA7761D21FE4C3AE6187
mpi/iobuf.c
(0 . 0)(1 . 2326)
2676 /* iobuf.c - file handling
2677 * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2008,
2678 * 2009 Free Software Foundation, Inc.
2679 *
2680 * This file is part of GnuPG.
2681 *
2682 * GnuPG is free software; you can redistribute it and/or modify
2683 * it under the terms of the GNU General Public License as published by
2684 * the Free Software Foundation; either version 3 of the License, or
2685 * (at your option) any later version.
2686 *
2687 * GnuPG is distributed in the hope that it will be useful,
2688 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2689 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2690 * GNU General Public License for more details.
2691 *
2692 * You should have received a copy of the GNU General Public License
2693 * along with this program; if not, see <http://www.gnu.org/licenses/>.
2694 */
2695
2696 #include <config.h>
2697 #include <stdio.h>
2698 #include <stdlib.h>
2699 #include <string.h>
2700 #include <errno.h>
2701 #include <ctype.h>
2702 #include <assert.h>
2703 #include <sys/types.h>
2704 #include <sys/stat.h>
2705 #include <fcntl.h>
2706 #include <unistd.h>
2707 #ifdef HAVE_DOSISH_SYSTEM
2708 #include <windows.h>
2709 #endif
2710 #ifdef __riscos__
2711 #include <kernel.h>
2712 #include <swis.h>
2713 #endif /* __riscos__ */
2714
2715 #include "memory.h"
2716 #include "util.h"
2717 #include "iobuf.h"
2718
2719 /* The size of the internal buffers.
2720 NOTE: If you change this value you MUST also adjust the regression
2721 test "armored_key_8192" in armor.test! */
2722 #define IOBUF_BUFFER_SIZE 8192
2723
2724
2725 #undef FILE_FILTER_USES_STDIO
2726
2727 #ifdef HAVE_DOSISH_SYSTEM
2728 #define USE_SETMODE 1
2729 #endif
2730
2731 #ifdef FILE_FILTER_USES_STDIO
2732 #define my_fileno(a) fileno ((a))
2733 #define my_fopen_ro(a,b) fopen ((a),(b))
2734 #define my_fopen(a,b) fopen ((a),(b))
2735 typedef FILE *FILEP_OR_FD;
2736 #define INVALID_FP NULL
2737 #define FILEP_OR_FD_FOR_STDIN (stdin)
2738 #define FILEP_OR_FD_FOR_STDOUT (stdout)
2739 typedef struct {
2740 FILE *fp; /* open file handle */
2741 int keep_open;
2742 int no_cache;
2743 int print_only_name; /* flags indicating that fname is not a real file*/
2744 char fname[1]; /* name of the file */
2745 } file_filter_ctx_t ;
2746 #else
2747 #define my_fileno(a) (a)
2748 #define my_fopen_ro(a,b) fd_cache_open ((a),(b))
2749 #define my_fopen(a,b) direct_open ((a),(b))
2750 #ifdef HAVE_DOSISH_SYSTEM
2751 typedef HANDLE FILEP_OR_FD;
2752 #define INVALID_FP ((HANDLE)-1)
2753 #define FILEP_OR_FD_FOR_STDIN (GetStdHandle (STD_INPUT_HANDLE))
2754 #define FILEP_OR_FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE))
2755 #undef USE_SETMODE
2756 #else
2757 typedef int FILEP_OR_FD;
2758 #define INVALID_FP (-1)
2759 #define FILEP_OR_FD_FOR_STDIN (0)
2760 #define FILEP_OR_FD_FOR_STDOUT (1)
2761 #endif
2762 typedef struct {
2763 FILEP_OR_FD fp; /* open file handle */
2764 int keep_open;
2765 int no_cache;
2766 int eof_seen;
2767 int print_only_name; /* flags indicating that fname is not a real file*/
2768 char fname[1]; /* name of the file */
2769 } file_filter_ctx_t ;
2770
2771 struct close_cache_s {
2772 struct close_cache_s *next;
2773 FILEP_OR_FD fp;
2774 char fname[1];
2775 };
2776 typedef struct close_cache_s *CLOSE_CACHE;
2777 static CLOSE_CACHE close_cache;
2778 #endif
2779
2780 #ifdef _WIN32
2781 typedef struct {
2782 int sock;
2783 int keep_open;
2784 int no_cache;
2785 int eof_seen;
2786 int print_only_name; /* flags indicating that fname is not a real file*/
2787 char fname[1]; /* name of the file */
2788 } sock_filter_ctx_t ;
2789 #endif /*_WIN32*/
2790
2791 /* The first partial length header block must be of size 512
2792 * to make it easier (and efficienter) we use a min. block size of 512
2793 * for all chunks (but the last one) */
2794 #define OP_MIN_PARTIAL_CHUNK 512
2795 #define OP_MIN_PARTIAL_CHUNK_2POW 9
2796
2797 typedef struct {
2798 int use;
2799 size_t size;
2800 size_t count;
2801 int partial; /* 1 = partial header, 2 in last partial packet */
2802 char *buffer; /* used for partial header */
2803 size_t buflen; /* used size of buffer */
2804 int first_c; /* of partial header (which is > 0)*/
2805 int eof;
2806 } block_filter_ctx_t;
2807
2808 static int special_names_enabled;
2809
2810 static int underflow(IOBUF a);
2811 static int translate_file_handle ( int fd, int for_write );
2812
2813
2814
2815 #ifndef FILE_FILTER_USES_STDIO
2816
2817 /* This is a replacement for strcmp. Under W32 it does not
2818 distinguish between backslash and slash. */
2819 static int
2820 fd_cache_strcmp (const char *a, const char *b)
2821 {
2822 #ifdef HAVE_DOSISH_SYSTEM
2823 for (; *a && *b; a++, b++)
2824 {
2825 if (*a != *b && !((*a == '/' && *b == '\\')
2826 || (*a == '\\' && *b == '/')) )
2827 break;
2828 }
2829 return *(const unsigned char *)a - *(const unsigned char *)b;
2830 #else
2831 return strcmp (a, b);
2832 #endif
2833 }
2834
2835 /*
2836 * Invalidate (i.e. close) a cached iobuf or all iobufs if NULL is
2837 * used for FNAME.
2838 */
2839 static int
2840 fd_cache_invalidate (const char *fname)
2841 {
2842 CLOSE_CACHE cc;
2843 int err=0;
2844
2845 if (!fname) {
2846 if( DBG_IOBUF )
2847 log_debug ("fd_cache_invalidate (all)\n");
2848
2849 for (cc=close_cache; cc; cc = cc->next ) {
2850 if ( cc->fp != INVALID_FP ) {
2851 #ifdef HAVE_DOSISH_SYSTEM
2852 CloseHandle (cc->fp);
2853 #else
2854 close(cc->fp);
2855 #endif
2856 cc->fp = INVALID_FP;
2857 }
2858 }
2859 return err;
2860 }
2861
2862 if( DBG_IOBUF )
2863 log_debug ("fd_cache_invalidate (%s)\n", fname);
2864
2865 for (cc=close_cache; cc; cc = cc->next ) {
2866 if ( cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname) ) {
2867 if( DBG_IOBUF )
2868 log_debug (" did (%s)\n", cc->fname);
2869 #ifdef HAVE_DOSISH_SYSTEM
2870 if(CloseHandle (cc->fp)==0)
2871 err=-1;
2872 #else
2873 err=close(cc->fp);
2874 #endif
2875 cc->fp = INVALID_FP;
2876 }
2877 }
2878
2879 return err;
2880 }
2881
2882 static int
2883 fd_cache_synchronize(const char *fname)
2884 {
2885 int err=0;
2886
2887 #ifndef HAVE_DOSISH_SYSTEM
2888 CLOSE_CACHE cc;
2889
2890 if( DBG_IOBUF )
2891 log_debug ("fd_cache_synchronize (%s)\n", fname);
2892
2893 for (cc=close_cache; cc; cc = cc->next )
2894 {
2895 if ( cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname) )
2896 {
2897 if( DBG_IOBUF )
2898 log_debug (" did (%s)\n", cc->fname);
2899
2900 err=fsync(cc->fp);
2901 }
2902 }
2903 #endif
2904
2905 return err;
2906 }
2907
2908 static FILEP_OR_FD
2909 direct_open (const char *fname, const char *mode)
2910 {
2911 #ifdef HAVE_DOSISH_SYSTEM
2912 unsigned long da, cd, sm;
2913 HANDLE hfile;
2914
2915 /* Note, that we do not handle all mode combinations */
2916
2917 /* According to the ReactOS source it seems that open() of the
2918 * standard MSW32 crt does open the file in share mode which is
2919 * something new for MS applications ;-)
2920 */
2921 if ( strchr (mode, '+') ) {
2922 fd_cache_invalidate (fname);
2923 da = GENERIC_READ|GENERIC_WRITE;
2924 cd = OPEN_EXISTING;
2925 sm = FILE_SHARE_READ | FILE_SHARE_WRITE;
2926 }
2927 else if ( strchr (mode, 'w') ) {
2928 fd_cache_invalidate (fname);
2929 da = GENERIC_WRITE;
2930 cd = CREATE_ALWAYS;
2931 sm = FILE_SHARE_WRITE;
2932 }
2933 else {
2934 da = GENERIC_READ;
2935 cd = OPEN_EXISTING;
2936 sm = FILE_SHARE_READ;
2937 }
2938
2939 hfile = CreateFile (fname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL);
2940 return hfile;
2941 #else
2942 int oflag;
2943 int cflag = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
2944
2945 /* Note, that we do not handle all mode combinations */
2946 if ( strchr (mode, '+') ) {
2947 fd_cache_invalidate (fname);
2948 oflag = O_RDWR;
2949 }
2950 else if ( strchr (mode, 'w') ) {
2951 fd_cache_invalidate (fname);
2952 oflag = O_WRONLY | O_CREAT | O_TRUNC;
2953 }
2954 else {
2955 oflag = O_RDONLY;
2956 }
2957 #ifdef O_BINARY
2958 if (strchr (mode, 'b'))
2959 oflag |= O_BINARY;
2960 #endif
2961 #ifndef __riscos__
2962 return open (fname, oflag, cflag );
2963 #else
2964 {
2965 struct stat buf;
2966 int rc = stat( fname, &buf );
2967
2968 /* Don't allow iobufs on directories */
2969 if( !rc && S_ISDIR(buf.st_mode) && !S_ISREG(buf.st_mode) )
2970 return __set_errno( EISDIR );
2971 else
2972 return open( fname, oflag, cflag );
2973 }
2974 #endif
2975 #endif
2976 }
2977
2978
2979 /*
2980 * Instead of closing an FD we keep it open and cache it for later reuse
2981 * Note that this caching strategy only works if the process does not chdir.
2982 */
2983 static void
2984 fd_cache_close (const char *fname, FILEP_OR_FD fp)
2985 {
2986 CLOSE_CACHE cc;
2987
2988 assert (fp);
2989 if ( !fname || !*fname ) {
2990 #ifdef HAVE_DOSISH_SYSTEM
2991 CloseHandle (fp);
2992 #else
2993 close(fp);
2994 #endif
2995 if( DBG_IOBUF )
2996 log_debug ("fd_cache_close (%d) real\n", (int)fp);
2997 return;
2998 }
2999 /* try to reuse a slot */
3000 for (cc=close_cache; cc; cc = cc->next ) {
3001 if ( cc->fp == INVALID_FP && !fd_cache_strcmp (cc->fname, fname) ) {
3002 cc->fp = fp;
3003 if( DBG_IOBUF )
3004 log_debug ("fd_cache_close (%s) used existing slot\n", fname);
3005 return;
3006 }
3007 }
3008 /* add a new one */
3009 if( DBG_IOBUF )
3010 log_debug ("fd_cache_close (%s) new slot created\n", fname);
3011 cc = xmalloc_clear (sizeof *cc + strlen (fname));
3012 strcpy (cc->fname, fname);
3013 cc->fp = fp;
3014 cc->next = close_cache;
3015 close_cache = cc;
3016 }
3017
3018 /*
3019 * Do an direct_open on FNAME but first try to reuse one from the fd_cache
3020 */
3021 static FILEP_OR_FD
3022 fd_cache_open (const char *fname, const char *mode)
3023 {
3024 CLOSE_CACHE cc;
3025
3026 assert (fname);
3027 for (cc=close_cache; cc; cc = cc->next ) {
3028 if ( cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname) ) {
3029 FILEP_OR_FD fp = cc->fp;
3030 cc->fp = INVALID_FP;
3031 if( DBG_IOBUF )
3032 log_debug ("fd_cache_open (%s) using cached fp\n", fname);
3033 #ifdef HAVE_DOSISH_SYSTEM
3034 if (SetFilePointer (fp, 0, NULL, FILE_BEGIN) == 0xffffffff ) {
3035 log_error ("rewind file failed on handle %p: %s\n",
3036 fp, w32_strerror (errno));
3037 fp = INVALID_FP;
3038 }
3039 #else
3040 if ( lseek (fp, 0, SEEK_SET) == (off_t)-1 ) {
3041 log_error("can't rewind fd %d: %s\n", fp, strerror(errno) );
3042 fp = INVALID_FP;
3043 }
3044 #endif
3045 return fp;
3046 }
3047 }
3048 if( DBG_IOBUF )
3049 log_debug ("fd_cache_open (%s) not cached\n", fname);
3050 return direct_open (fname, mode);
3051 }
3052
3053
3054 #endif /*FILE_FILTER_USES_STDIO*/
3055
3056
3057 /****************
3058 * Read data from a file into buf which has an allocated length of *LEN.
3059 * return the number of read bytes in *LEN. OPAQUE is the FILE * of
3060 * the stream. A is not used.
3061 * control may be:
3062 * IOBUFCTRL_INIT: called just before the function is linked into the
3063 * list of function. This can be used to prepare internal
3064 * data structures of the function.
3065 * IOBUFCTRL_FREE: called just before the function is removed from the
3066 * list of functions and can be used to release internal
3067 * data structures or close a file etc.
3068 * IOBUFCTRL_UNDERFLOW: called by iobuf_underflow to fill the buffer
3069 * with new stuff. *RET_LEN is the available size of the
3070 * buffer, and should be set to the number of bytes
3071 * which were put into the buffer. The function
3072 * returns 0 to indicate success, -1 on EOF and
3073 * G10ERR_xxxxx for other errors.
3074 *
3075 * IOBUFCTRL_FLUSH: called by iobuf_flush() to write out the collected stuff.
3076 * *RET_LAN is the number of bytes in BUF.
3077 *
3078 * IOBUFCTRL_CANCEL: send to all filters on behalf of iobuf_cancel. The
3079 * filter may take appropriate action on this message.
3080 */
3081 static int
3082 file_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
3083 {
3084 file_filter_ctx_t *a = opaque;
3085 FILEP_OR_FD f = a->fp;
3086 size_t size = *ret_len;
3087 size_t nbytes = 0;
3088 int rc = 0;
3089
3090 #ifdef FILE_FILTER_USES_STDIO
3091 if( control == IOBUFCTRL_UNDERFLOW ) {
3092 assert( size ); /* need a buffer */
3093 if ( feof(f)) { /* On terminals you could easiely read as many EOFs as you call */
3094 rc = -1; /* fread() or fgetc() repeatly. Every call will block until you press */
3095 *ret_len = 0; /* CTRL-D. So we catch this case before we call fread() again. */
3096 }
3097 else {
3098 clearerr( f );
3099 nbytes = fread( buf, 1, size, f );
3100 if( feof(f) && !nbytes ) {
3101 rc = -1; /* okay: we can return EOF now. */
3102 }
3103 else if( ferror(f) && errno != EPIPE ) {
3104 log_error("%s: read error: %s\n",
3105 a->fname, strerror(errno));
3106 rc = G10ERR_READ_FILE;
3107 }
3108 *ret_len = nbytes;
3109 }
3110 }
3111 else if( control == IOBUFCTRL_FLUSH ) {
3112 if( size ) {
3113 clearerr( f );
3114 nbytes = fwrite( buf, 1, size, f );
3115 if( ferror(f) ) {
3116 log_error("%s: write error: %s\n", a->fname, strerror(errno));
3117 rc = G10ERR_WRITE_FILE;
3118 }
3119 }
3120 *ret_len = nbytes;
3121 }
3122 else if( control == IOBUFCTRL_INIT ) {
3123 a->keep_open = a->no_cache = 0;
3124 }
3125 else if( control == IOBUFCTRL_DESC ) {
3126 *(char**)buf = "file_filter";
3127 }
3128 else if( control == IOBUFCTRL_FREE ) {
3129 if( f != stdin && f != stdout ) {
3130 if( DBG_IOBUF )
3131 log_debug("%s: close fd %d\n", a->fname, fileno(f) );
3132 if (!a->keep_open)
3133 fclose(f);
3134 }
3135 f = NULL;
3136 xfree(a); /* we can free our context now */
3137 }
3138 #else /* !stdio implementation */
3139
3140 if( control == IOBUFCTRL_UNDERFLOW ) {
3141 assert( size ); /* need a buffer */
3142 if ( a->eof_seen) {
3143 rc = -1;
3144 *ret_len = 0;
3145 }
3146 else {
3147 #ifdef HAVE_DOSISH_SYSTEM
3148 unsigned long nread;
3149
3150 nbytes = 0;
3151 if ( !ReadFile ( f, buf, size, &nread, NULL ) ) {
3152 if ((int)GetLastError () != ERROR_BROKEN_PIPE) {
3153 log_error ("%s: read error: %s\n", a->fname,
3154 w32_strerror (0));
3155 rc = G10ERR_READ_FILE;
3156 }
3157 }
3158 else if ( !nread ) {
3159 a->eof_seen = 1;
3160 rc = -1;
3161 }
3162 else {
3163 nbytes = nread;
3164 }
3165
3166 #else
3167
3168 int n;
3169
3170 nbytes = 0;
3171 do {
3172 n = read ( f, buf, size );
3173 } while (n == -1 && errno == EINTR );
3174 if ( n == -1 ) { /* error */
3175 if (errno != EPIPE) {
3176 log_error("%s: read error: %s\n",
3177 a->fname, strerror(errno));
3178 rc = G10ERR_READ_FILE;
3179 }
3180 }
3181 else if ( !n ) { /* eof */
3182 a->eof_seen = 1;
3183 rc = -1;
3184 }
3185 else {
3186 nbytes = n;
3187 }
3188 #endif
3189 *ret_len = nbytes;
3190 }
3191 }
3192 else if( control == IOBUFCTRL_FLUSH ) {
3193 if( size ) {
3194 #ifdef HAVE_DOSISH_SYSTEM
3195 byte *p = buf;
3196 unsigned long n;
3197
3198 nbytes = size;
3199 do {
3200 if (size && !WriteFile (f, p, nbytes, &n, NULL)) {
3201 log_error ("%s: write error: %s\n", a->fname,
3202 w32_strerror (0));
3203 rc = G10ERR_WRITE_FILE;
3204 break;
3205 }
3206 p += n;
3207 nbytes -= n;
3208 } while ( nbytes );
3209 nbytes = p - buf;
3210 #else
3211 byte *p = buf;
3212 int n;
3213
3214 nbytes = size;
3215 do {
3216 do {
3217 n = write ( f, p, nbytes );
3218 } while ( n == -1 && errno == EINTR );
3219 if ( n > 0 ) {
3220 p += n;
3221 nbytes -= n;
3222 }
3223 } while ( n != -1 && nbytes );
3224 if( n == -1 ) {
3225 log_error("%s: write error: %s\n", a->fname, strerror(errno));
3226 rc = G10ERR_WRITE_FILE;
3227 }
3228 nbytes = p - buf;
3229 #endif
3230 }
3231 *ret_len = nbytes;
3232 }
3233 else if ( control == IOBUFCTRL_INIT ) {
3234 a->eof_seen = 0;
3235 a->keep_open = 0;
3236 a->no_cache = 0;
3237 }
3238 else if ( control == IOBUFCTRL_DESC ) {
3239 *(char**)buf = "file_filter(fd)";
3240 }
3241 else if ( control == IOBUFCTRL_FREE ) {
3242 #ifdef HAVE_DOSISH_SYSTEM
3243 if ( f != FILEP_OR_FD_FOR_STDIN && f != FILEP_OR_FD_FOR_STDOUT ) {
3244 if( DBG_IOBUF )
3245 log_debug("%s: close handle %p\n", a->fname, f );
3246 if (!a->keep_open)
3247 fd_cache_close (a->no_cache?NULL:a->fname, f);
3248 }
3249 #else
3250 if ( (int)f != 0 && (int)f != 1 ) {
3251 if( DBG_IOBUF )
3252 log_debug("%s: close fd %d\n", a->fname, f );
3253 if (!a->keep_open)
3254 fd_cache_close (a->no_cache?NULL:a->fname, f);
3255 }
3256 f = INVALID_FP;
3257 #endif
3258 xfree (a); /* we can free our context now */
3259 }
3260 #endif /* !stdio implementation */
3261 return rc;
3262 }
3263
3264 #ifdef _WIN32
3265 /* Becuase sockets are an special object under Lose32 we have to
3266 * use a special filter */
3267 static int
3268 sock_filter (void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
3269 {
3270 sock_filter_ctx_t *a = opaque;
3271 size_t size = *ret_len;
3272 size_t nbytes = 0;
3273 int rc = 0;
3274
3275 if( control == IOBUFCTRL_UNDERFLOW ) {
3276 assert( size ); /* need a buffer */
3277 if ( a->eof_seen) {
3278 rc = -1;
3279 *ret_len = 0;
3280 }
3281 else {
3282 int nread;
3283
3284 nread = recv ( a->sock, buf, size, 0 );
3285 if ( nread == SOCKET_ERROR ) {
3286 int ec = (int)WSAGetLastError ();
3287 log_error("socket read error: ec=%d\n", ec);
3288 rc = G10ERR_READ_FILE;
3289 }
3290 else if ( !nread ) {
3291 a->eof_seen = 1;
3292 rc = -1;
3293 }
3294 else {
3295 nbytes = nread;
3296 }
3297 *ret_len = nbytes;
3298 }
3299 }
3300 else if( control == IOBUFCTRL_FLUSH ) {
3301 if( size ) {
3302 byte *p = buf;
3303 int n;
3304
3305 nbytes = size;
3306 do {
3307 n = send (a->sock, p, nbytes, 0);
3308 if ( n == SOCKET_ERROR ) {
3309 int ec = (int)WSAGetLastError ();
3310 log_error("socket write error: ec=%d\n", ec);
3311 rc = G10ERR_WRITE_FILE;
3312 break;
3313 }
3314 p += n;
3315 nbytes -= n;
3316 } while ( nbytes );
3317 nbytes = p - buf;
3318 }
3319 *ret_len = nbytes;
3320 }
3321 else if ( control == IOBUFCTRL_INIT ) {
3322 a->eof_seen = 0;
3323 a->keep_open = 0;
3324 a->no_cache = 0;
3325 }
3326 else if ( control == IOBUFCTRL_DESC ) {
3327 *(char**)buf = "sock_filter";
3328 }
3329 else if ( control == IOBUFCTRL_FREE ) {
3330 if (!a->keep_open)
3331 closesocket (a->sock);
3332 xfree (a); /* we can free our context now */
3333 }
3334 return rc;
3335 }
3336 #endif /*_WIN32*/
3337
3338 /****************
3339 * This is used to implement the block write mode.
3340 * Block reading is done on a byte by byte basis in readbyte(),
3341 * without a filter
3342 */
3343 static int
3344 block_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
3345 {
3346 block_filter_ctx_t *a = opaque;
3347 size_t size = *ret_len;
3348 int c, needed, rc = 0;
3349 char *p;
3350
3351 if( control == IOBUFCTRL_UNDERFLOW ) {
3352 size_t n=0;
3353
3354 p = buf;
3355 assert( size ); /* need a buffer */
3356 if( a->eof ) /* don't read any further */
3357 rc = -1;
3358 while( !rc && size ) {
3359 if( !a->size ) { /* get the length bytes */
3360 if( a->partial == 2 ) {
3361 a->eof = 1;
3362 if( !n )
3363 rc = -1;
3364 break;
3365 }
3366 else if( a->partial ) {
3367 /* These OpenPGP introduced huffman like encoded length
3368 * bytes are really a mess :-( */
3369 if( a->first_c ) {
3370 c = a->first_c;
3371 a->first_c = 0;
3372 }
3373 else if( (c = iobuf_get(chain)) == -1 ) {
3374 log_error("block_filter: 1st length byte missing\n");
3375 rc = G10ERR_READ_FILE;
3376 break;
3377 }
3378 if( c < 192 ) {
3379 a->size = c;
3380 a->partial = 2;
3381 if( !a->size ) {
3382 a->eof = 1;
3383 if( !n )
3384 rc = -1;
3385 break;
3386 }
3387 }
3388 else if( c < 224 ) {
3389 a->size = (c - 192) * 256;
3390 if( (c = iobuf_get(chain)) == -1 ) {
3391 log_error("block_filter: 2nd length byte missing\n");
3392 rc = G10ERR_READ_FILE;
3393 break;
3394 }
3395 a->size += c + 192;
3396 a->partial = 2;
3397 if( !a->size ) {
3398 a->eof = 1;
3399 if( !n )
3400 rc = -1;
3401 break;
3402 }
3403 }
3404 else if( c == 255 ) {
3405 a->size = iobuf_get(chain) << 24;
3406 a->size |= iobuf_get(chain) << 16;
3407 a->size |= iobuf_get(chain) << 8;
3408 if( (c = iobuf_get(chain)) == -1 ) {
3409 log_error("block_filter: invalid 4 byte length\n");
3410 rc = G10ERR_READ_FILE;
3411 break;
3412 }
3413 a->size |= c;
3414 a->partial = 2;
3415 if( !a->size ) {
3416 a->eof = 1;
3417 if( !n )
3418 rc = -1;
3419 break;
3420 }
3421 }
3422 else { /* next partial body length */
3423 a->size = 1 << (c & 0x1f);
3424 }
3425 /* log_debug("partial: ctx=%p c=%02x size=%u\n", a, c, a->size);*/
3426 }
3427 else
3428 BUG();
3429 }
3430
3431 while( !rc && size && a->size ) {
3432 needed = size < a->size ? size : a->size;
3433 c = iobuf_read( chain, p, needed );
3434 if( c < needed ) {
3435 if( c == -1 ) c = 0;
3436 log_error("block_filter %p: read error (size=%lu,a->size=%lu)\n",
3437 a, (ulong)size+c, (ulong)a->size+c);
3438 rc = G10ERR_READ_FILE;
3439 }
3440 else {
3441 size -= c;
3442 a->size -= c;
3443 p += c;
3444 n += c;
3445 }
3446 }
3447 }
3448 *ret_len = n;
3449 }
3450 else if( control == IOBUFCTRL_FLUSH ) {
3451 if( a->partial ) { /* the complicated openpgp scheme */
3452 size_t blen, n, nbytes = size + a->buflen;
3453
3454 assert( a->buflen <= OP_MIN_PARTIAL_CHUNK );
3455 if( nbytes < OP_MIN_PARTIAL_CHUNK ) {
3456 /* not enough to write a partial block out; so we store it*/
3457 if( !a->buffer )
3458 a->buffer = xmalloc( OP_MIN_PARTIAL_CHUNK );
3459 memcpy( a->buffer + a->buflen, buf, size );
3460 a->buflen += size;
3461 }
3462 else { /* okay, we can write out something */
3463 /* do this in a loop to use the most efficient block lengths */
3464 p = buf;
3465 do {
3466 /* find the best matching block length - this is limited
3467 * by the size of the internal buffering */
3468 for( blen=OP_MIN_PARTIAL_CHUNK*2,
3469 c=OP_MIN_PARTIAL_CHUNK_2POW+1; blen <= nbytes;
3470 blen *=2, c++ )
3471 ;
3472 blen /= 2; c--;
3473 /* write the partial length header */
3474 assert( c <= 0x1f ); /*;-)*/
3475 c |= 0xe0;
3476 iobuf_put( chain, c );
3477 if( (n=a->buflen) ) { /* write stuff from the buffer */
3478 assert( n == OP_MIN_PARTIAL_CHUNK);
3479 if( iobuf_write(chain, a->buffer, n ) )
3480 rc = G10ERR_WRITE_FILE;
3481 a->buflen = 0;
3482 nbytes -= n;
3483 }
3484 if( (n = nbytes) > blen )
3485 n = blen;
3486 if( n && iobuf_write(chain, p, n ) )
3487 rc = G10ERR_WRITE_FILE;
3488 p += n;
3489 nbytes -= n;
3490 } while( !rc && nbytes >= OP_MIN_PARTIAL_CHUNK );
3491 /* store the rest in the buffer */
3492 if( !rc && nbytes ) {
3493 assert( !a->buflen );
3494 assert( nbytes < OP_MIN_PARTIAL_CHUNK );
3495 if( !a->buffer )
3496 a->buffer = xmalloc( OP_MIN_PARTIAL_CHUNK );
3497 memcpy( a->buffer, p, nbytes );
3498 a->buflen = nbytes;
3499 }
3500 }
3501 }
3502 else
3503 BUG();
3504 }
3505 else if( control == IOBUFCTRL_INIT ) {
3506 if( DBG_IOBUF )
3507 log_debug("init block_filter %p\n", a );
3508 if( a->partial )
3509 a->count = 0;
3510 else if( a->use == 1 )
3511 a->count = a->size = 0;
3512 else
3513 a->count = a->size; /* force first length bytes */
3514 a->eof = 0;
3515 a->buffer = NULL;
3516 a->buflen = 0;
3517 }
3518 else if( control == IOBUFCTRL_DESC ) {
3519 *(char**)buf = "block_filter";
3520 }
3521 else if( control == IOBUFCTRL_FREE ) {
3522 if( a->use == 2 ) { /* write the end markers */
3523 if( a->partial ) {
3524 u32 len;
3525 /* write out the remaining bytes without a partial header
3526 * the length of this header may be 0 - but if it is
3527 * the first block we are not allowed to use a partial header
3528 * and frankly we can't do so, because this length must be
3529 * a power of 2. This is _really_ complicated because we
3530 * have to check the possible length of a packet prior
3531 * to it's creation: a chain of filters becomes complicated
3532 * and we need a lot of code to handle compressed packets etc.
3533 * :-(((((((
3534 */
3535 /* construct header */
3536 len = a->buflen;
3537 /*log_debug("partial: remaining length=%u\n", len );*/
3538 if( len < 192 )
3539 rc = iobuf_put(chain, len );
3540 else if( len < 8384 ) {
3541 if( !(rc=iobuf_put( chain, ((len-192) / 256) + 192)) )
3542 rc = iobuf_put( chain, ((len-192) % 256));
3543 }
3544 else { /* use a 4 byte header */
3545 if( !(rc=iobuf_put( chain, 0xff )) )
3546 if( !(rc=iobuf_put( chain, (len >> 24)&0xff )) )
3547 if( !(rc=iobuf_put( chain, (len >> 16)&0xff )) )
3548 if( !(rc=iobuf_put( chain, (len >> 8)&0xff )))
3549 rc=iobuf_put( chain, len & 0xff );
3550 }
3551 if( !rc && len )
3552 rc = iobuf_write(chain, a->buffer, len );
3553 if( rc ) {
3554 log_error("block_filter: write error: %s\n",strerror(errno));
3555 rc = G10ERR_WRITE_FILE;
3556 }
3557 xfree( a->buffer ); a->buffer = NULL; a->buflen = 0;
3558 }
3559 else
3560 BUG();
3561 }
3562 else if( a->size ) {
3563 log_error("block_filter: pending bytes!\n");
3564 }
3565 if( DBG_IOBUF )
3566 log_debug("free block_filter %p\n", a );
3567 xfree(a); /* we can free our context now */
3568 }
3569
3570 return rc;
3571 }
3572
3573
3574 static void
3575 print_chain( IOBUF a )
3576 {
3577 if( !DBG_IOBUF )
3578 return;
3579 for(; a; a = a->chain ) {
3580 size_t dummy_len = 0;
3581 const char *desc = "[none]";
3582
3583 if( a->filter )
3584 a->filter( a->filter_ov, IOBUFCTRL_DESC, NULL,
3585 (byte*)&desc, &dummy_len );
3586
3587 log_debug("iobuf chain: %d.%d `%s' filter_eof=%d start=%d len=%d\n",
3588 a->no, a->subno, desc?desc:"?", a->filter_eof,
3589 (int)a->d.start, (int)a->d.len );
3590 }
3591 }
3592
3593 int
3594 iobuf_print_chain( IOBUF a )
3595 {
3596 print_chain(a);
3597 return 0;
3598 }
3599
3600 /****************
3601 * Allocate a new io buffer, with no function assigned.
3602 * Use is the desired usage: 1 for input, 2 for output, 3 for temp buffer
3603 * BUFSIZE is a suggested buffer size.
3604 */
3605 IOBUF
3606 iobuf_alloc(int use, size_t bufsize)
3607 {
3608 IOBUF a;
3609 static int number=0;
3610
3611 a = xmalloc_clear(sizeof *a);
3612 a->use = use;
3613 a->d.buf = xmalloc( bufsize );
3614 a->d.size = bufsize;
3615 a->no = ++number;
3616 a->subno = 0;
3617 a->opaque = NULL;
3618 a->real_fname = NULL;
3619 return a;
3620 }
3621
3622 int
3623 iobuf_close ( IOBUF a )
3624 {
3625 IOBUF a2;
3626 size_t dummy_len=0;
3627 int rc=0;
3628
3629 if( a && a->directfp ) {
3630 fclose( a->directfp );
3631 xfree( a->real_fname );
3632 if( DBG_IOBUF )
3633 log_debug("iobuf_close -> %p\n", a->directfp );
3634 return 0;
3635 }
3636
3637 for( ; a && !rc ; a = a2 ) {
3638 a2 = a->chain;
3639 if( a->use == 2 && (rc=iobuf_flush(a)) )
3640 log_error("iobuf_flush failed on close: %s\n", g10_errstr(rc));
3641
3642 if( DBG_IOBUF )
3643 log_debug("iobuf-%d.%d: close `%s'\n", a->no, a->subno,
3644 a->desc?a->desc:"?");
3645 if( a->filter && (rc = a->filter(a->filter_ov, IOBUFCTRL_FREE,
3646 a->chain, NULL, &dummy_len)) )
3647 log_error("IOBUFCTRL_FREE failed on close: %s\n", g10_errstr(rc) );
3648 xfree(a->real_fname);
3649 if (a->d.buf) {
3650 memset (a->d.buf, 0, a->d.size); /* erase the buffer */
3651 xfree(a->d.buf);
3652 }
3653 xfree(a);
3654 }
3655 return rc;
3656 }
3657
3658 int
3659 iobuf_cancel( IOBUF a )
3660 {
3661 const char *s;
3662 IOBUF a2;
3663 int rc;
3664 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
3665 char *remove_name = NULL;
3666 #endif
3667
3668 if( a && a->use == 2 ) {
3669 s = iobuf_get_real_fname(a);
3670 if( s && *s ) {
3671 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
3672 remove_name = xstrdup ( s );
3673 #else
3674 remove(s);
3675 #endif
3676 }
3677 }
3678
3679 /* send a cancel message to all filters */
3680 for( a2 = a; a2 ; a2 = a2->chain ) {
3681 size_t dummy;
3682 if( a2->filter )
3683 a2->filter( a2->filter_ov, IOBUFCTRL_CANCEL, a2->chain,
3684 NULL, &dummy );
3685 }
3686
3687 rc = iobuf_close(a);
3688 #if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__)
3689 if ( remove_name ) {
3690 /* Argg, MSDOS does not allow to remove open files. So
3691 * we have to do it here */
3692 remove ( remove_name );
3693 xfree ( remove_name );
3694 }
3695 #endif
3696 return rc;
3697 }
3698
3699
3700 /****************
3701 * create a temporary iobuf, which can be used to collect stuff
3702 * in an iobuf and later be written by iobuf_write_temp() to another
3703 * iobuf.
3704 */
3705 IOBUF
3706 iobuf_temp()
3707 {
3708 IOBUF a;
3709
3710 a = iobuf_alloc(3, IOBUF_BUFFER_SIZE );
3711
3712 return a;
3713 }
3714
3715 IOBUF
3716 iobuf_temp_with_content( const char *buffer, size_t length )
3717 {
3718 IOBUF a;
3719
3720 a = iobuf_alloc(3, length );
3721 memcpy( a->d.buf, buffer, length );
3722 a->d.len = length;
3723
3724 return a;
3725 }
3726
3727 void
3728 iobuf_enable_special_filenames ( int yes )
3729 {
3730 special_names_enabled = yes;
3731 }
3732
3733 /*
3734 * see whether the filename has the for "-&nnnn", where n is a
3735 * non-zero number.
3736 * Returns this number or -1 if it is not the case.
3737 */
3738 static int
3739 check_special_filename ( const char *fname )
3740 {
3741 if ( special_names_enabled
3742 && fname && *fname == '-' && fname[1] == '&' ) {
3743 int i;
3744
3745 fname += 2;
3746 for (i=0; digitp (fname+i); i++ )
3747 ;
3748 if ( !fname[i] )
3749 return atoi (fname);
3750 }
3751 return -1;
3752 }
3753
3754 /* This fucntion returns true if FNAME indicates a PIPE (stdout or
3755 stderr) or a special file name if those are enabled. */
3756 int
3757 iobuf_is_pipe_filename (const char *fname)
3758 {
3759 if (!fname || (*fname=='-' && !fname[1]) )
3760 return 1;
3761 return check_special_filename (fname) != -1;
3762 }
3763
3764 /****************
3765 * Create a head iobuf for reading from a file
3766 * returns: NULL if an error occures and sets errno
3767 */
3768 IOBUF
3769 iobuf_open( const char *fname )
3770 {
3771 IOBUF a;
3772 FILEP_OR_FD fp;
3773 file_filter_ctx_t *fcx;
3774 size_t len;
3775 int print_only = 0;
3776 int fd;
3777
3778 if( !fname || (*fname=='-' && !fname[1]) ) {
3779 fp = FILEP_OR_FD_FOR_STDIN;
3780 #ifdef USE_SETMODE
3781 setmode ( my_fileno(fp) , O_BINARY );
3782 #endif
3783 fname = "[stdin]";
3784 print_only = 1;
3785 }
3786 else if ( (fd = check_special_filename ( fname )) != -1 )
3787 return iobuf_fdopen ( translate_file_handle (fd,0), "rb" );
3788 else if( (fp = my_fopen_ro(fname, "rb")) == INVALID_FP )
3789 return NULL;
3790 a = iobuf_alloc(1, IOBUF_BUFFER_SIZE );
3791 fcx = xmalloc( sizeof *fcx + strlen(fname) );
3792 fcx->fp = fp;
3793 fcx->print_only_name = print_only;
3794 strcpy(fcx->fname, fname );
3795 if( !print_only )
3796 a->real_fname = xstrdup( fname );
3797 a->filter = file_filter;
3798 a->filter_ov = fcx;
3799 file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
3800 file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
3801 if( DBG_IOBUF )
3802 log_debug("iobuf-%d.%d: open `%s' fd=%d\n",
3803 a->no, a->subno, fname, (int)my_fileno(fcx->fp) );
3804
3805 return a;
3806 }
3807
3808 /****************
3809 * Create a head iobuf for reading from a file
3810 * returns: NULL if an error occures and sets errno
3811 */
3812 IOBUF
3813 iobuf_fdopen( int fd, const char *mode )
3814 {
3815 IOBUF a;
3816 FILEP_OR_FD fp;
3817 file_filter_ctx_t *fcx;
3818 size_t len;
3819
3820 #ifdef FILE_FILTER_USES_STDIO
3821 if( !(fp = fdopen(fd, mode)) )
3822 return NULL;
3823 #else
3824 fp = (FILEP_OR_FD)fd;
3825 #endif
3826 a = iobuf_alloc( strchr( mode, 'w')? 2:1, IOBUF_BUFFER_SIZE );
3827 fcx = xmalloc( sizeof *fcx + 20 );
3828 fcx->fp = fp;
3829 fcx->print_only_name = 1;
3830 sprintf(fcx->fname, "[fd %d]", fd );
3831 a->filter = file_filter;
3832 a->filter_ov = fcx;
3833 file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
3834 file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
3835 if( DBG_IOBUF )
3836 log_debug("iobuf-%d.%d: fdopen `%s'\n", a->no, a->subno, fcx->fname );
3837 iobuf_ioctl (a,3,1,NULL); /* disable fd caching */
3838 return a;
3839 }
3840
3841
3842 IOBUF
3843 iobuf_sockopen ( int fd, const char *mode )
3844 {
3845 IOBUF a;
3846 #ifdef _WIN32
3847 sock_filter_ctx_t *scx;
3848 size_t len;
3849
3850 a = iobuf_alloc( strchr( mode, 'w')? 2:1, IOBUF_BUFFER_SIZE );
3851 scx = xmalloc( sizeof *scx + 25 );
3852 scx->sock = fd;
3853 scx->print_only_name = 1;
3854 sprintf(scx->fname, "[sock %d]", fd );
3855 a->filter = sock_filter;
3856 a->filter_ov = scx;
3857 sock_filter( scx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
3858 sock_filter( scx, IOBUFCTRL_INIT, NULL, NULL, &len );
3859 if( DBG_IOBUF )
3860 log_debug("iobuf-%d.%d: sockopen `%s'\n", a->no, a->subno, scx->fname);
3861 iobuf_ioctl (a,3,1,NULL); /* disable fd caching */
3862 #else
3863 a = iobuf_fdopen (fd, mode);
3864 #endif
3865 return a;
3866 }
3867
3868 /****************
3869 * create an iobuf for writing to a file; the file will be created.
3870 */
3871 IOBUF
3872 iobuf_create( const char *fname )
3873 {
3874 IOBUF a;
3875 FILEP_OR_FD fp;
3876 file_filter_ctx_t *fcx;
3877 size_t len;
3878 int print_only = 0;
3879 int fd;
3880
3881 if( !fname || (*fname=='-' && !fname[1]) ) {
3882 fp = FILEP_OR_FD_FOR_STDOUT;
3883 #ifdef USE_SETMODE
3884 setmode ( my_fileno(fp) , O_BINARY );
3885 #endif
3886 fname = "[stdout]";
3887 print_only = 1;
3888 }
3889 else if ( (fd = check_special_filename ( fname )) != -1 )
3890 return iobuf_fdopen ( translate_file_handle (fd, 1), "wb" );
3891 else if( (fp = my_fopen(fname, "wb")) == INVALID_FP )
3892 return NULL;
3893 a = iobuf_alloc(2, IOBUF_BUFFER_SIZE );
3894 fcx = xmalloc( sizeof *fcx + strlen(fname) );
3895 fcx->fp = fp;
3896 fcx->print_only_name = print_only;
3897 strcpy(fcx->fname, fname );
3898 if( !print_only )
3899 a->real_fname = xstrdup( fname );
3900 a->filter = file_filter;
3901 a->filter_ov = fcx;
3902 file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
3903 file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
3904 if( DBG_IOBUF )
3905 log_debug("iobuf-%d.%d: create `%s'\n", a->no, a->subno,
3906 a->desc?a->desc:"?" );
3907
3908 return a;
3909 }
3910
3911 /****************
3912 * append to an iobuf; if the file does not exist, create it.
3913 * cannot be used for stdout.
3914 * Note: This is not used.
3915 */
3916 #if 0 /* not used */
3917 IOBUF
3918 iobuf_append( const char *fname )
3919 {
3920 IOBUF a;
3921 FILE *fp;
3922 file_filter_ctx_t *fcx;
3923 size_t len;
3924
3925 if( !fname )
3926 return NULL;
3927 else if( !(fp = my_fopen(fname, "ab")) )
3928 return NULL;
3929 a = iobuf_alloc(2, IOBUF_BUFFER_SIZE );
3930 fcx = xmalloc( sizeof *fcx + strlen(fname) );
3931 fcx->fp = fp;
3932 strcpy(fcx->fname, fname );
3933 a->real_fname = xstrdup( fname );
3934 a->filter = file_filter;
3935 a->filter_ov = fcx;
3936 file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
3937 file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
3938 if( DBG_IOBUF )
3939 log_debug("iobuf-%d.%d: append `%s'\n", a->no, a->subno,
3940 a->desc?a->desc:"?" );
3941
3942 return a;
3943 }
3944 #endif
3945
3946 IOBUF
3947 iobuf_openrw( const char *fname )
3948 {
3949 IOBUF a;
3950 FILEP_OR_FD fp;
3951 file_filter_ctx_t *fcx;
3952 size_t len;
3953
3954 if( !fname )
3955 return NULL;
3956 else if( (fp = my_fopen(fname, "r+b")) == INVALID_FP )
3957 return NULL;
3958 a = iobuf_alloc(2, IOBUF_BUFFER_SIZE );
3959 fcx = xmalloc( sizeof *fcx + strlen(fname) );
3960 fcx->fp = fp;
3961 strcpy(fcx->fname, fname );
3962 a->real_fname = xstrdup( fname );
3963 a->filter = file_filter;
3964 a->filter_ov = fcx;
3965 file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
3966 file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
3967 if( DBG_IOBUF )
3968 log_debug("iobuf-%d.%d: openrw `%s'\n", a->no, a->subno,
3969 a->desc?a->desc:"?");
3970
3971 return a;
3972 }
3973
3974
3975 int
3976 iobuf_ioctl ( IOBUF a, int cmd, int intval, void *ptrval )
3977 {
3978 if ( cmd == 1 ) { /* keep system filepointer/descriptor open */
3979 if( DBG_IOBUF )
3980 log_debug("iobuf-%d.%d: ioctl `%s' keep=%d\n",
3981 a? a->no:-1, a?a->subno:-1,
3982 a&&a->desc?a->desc:"?", intval );
3983 for( ; a; a = a->chain )
3984 if( !a->chain && a->filter == file_filter ) {
3985 file_filter_ctx_t *b = a->filter_ov;
3986 b->keep_open = intval;
3987 return 0;
3988 }
3989 #ifdef _WIN32
3990 else if( !a->chain && a->filter == sock_filter ) {
3991 sock_filter_ctx_t *b = a->filter_ov;
3992 b->keep_open = intval;
3993 return 0;
3994 }
3995 #endif
3996 }
3997 else if ( cmd == 2 ) { /* invalidate cache */
3998 if( DBG_IOBUF )
3999 log_debug("iobuf-*.*: ioctl `%s' invalidate\n",
4000 ptrval? (char*)ptrval:"[all]");
4001 if ( !a && !intval ) {
4002 #ifndef FILE_FILTER_USES_STDIO
4003 return fd_cache_invalidate (ptrval);
4004 #endif
4005 return 0;
4006 }
4007 }
4008 else if ( cmd == 3 ) { /* disallow/allow caching */
4009 if( DBG_IOBUF )
4010 log_debug("iobuf-%d.%d: ioctl `%s' no_cache=%d\n",
4011 a? a->no:-1, a?a->subno:-1,
4012 a&&a->desc?a->desc:"?", intval );
4013 for( ; a; a = a->chain )
4014 if( !a->chain && a->filter == file_filter ) {
4015 file_filter_ctx_t *b = a->filter_ov;
4016 b->no_cache = intval;
4017 return 0;
4018 }
4019 #ifdef _WIN32
4020 else if( !a->chain && a->filter == sock_filter ) {
4021 sock_filter_ctx_t *b = a->filter_ov;
4022 b->no_cache = intval;
4023 return 0;
4024 }
4025 #endif
4026 }
4027 else if(cmd==4)
4028 {
4029 /* Do a fsync on the open fd and return any errors to the
4030 caller of iobuf_ioctl */
4031 if( DBG_IOBUF )
4032 log_debug("iobuf-*.*: ioctl `%s' fsync\n",
4033 ptrval? (char*)ptrval:"<null>");
4034
4035 if(!a && !intval && ptrval)
4036 {
4037 #ifndef FILE_FILTER_USES_STDIO
4038 return fd_cache_synchronize (ptrval);
4039 #else
4040 return 0;
4041 #endif
4042 }
4043 }
4044
4045 return -1;
4046 }
4047
4048
4049 /****************
4050 * Register an i/o filter.
4051 */
4052 int
4053 iobuf_push_filter( IOBUF a,
4054 int (*f)(void *opaque, int control,
4055 IOBUF chain, byte *buf, size_t *len), void *ov )
4056 {
4057 return iobuf_push_filter2( a, f, ov, 0 );
4058 }
4059
4060 int
4061 iobuf_push_filter2( IOBUF a,
4062 int (*f)(void *opaque, int control,
4063 IOBUF chain, byte *buf, size_t *len),
4064 void *ov, int rel_ov )
4065 {
4066 IOBUF b;
4067 size_t dummy_len=0;
4068 int rc=0;
4069
4070 if( a->directfp )
4071 BUG();
4072
4073 if( a->use == 2 && (rc=iobuf_flush(a)) )
4074 return rc;
4075 /* make a copy of the current stream, so that
4076 * A is the new stream and B the original one.
4077 * The contents of the buffers are transferred to the
4078 * new stream.
4079 */
4080 b = xmalloc(sizeof *b);
4081 memcpy(b, a, sizeof *b );
4082 /* fixme: it is stupid to keep a copy of the name at every level
4083 * but we need the name somewhere because the name known by file_filter
4084 * may have been released when we need the name of the file */
4085 b->real_fname = a->real_fname? xstrdup(a->real_fname):NULL;
4086 /* remove the filter stuff from the new stream */
4087 a->filter = NULL;
4088 a->filter_ov = NULL;
4089 a->filter_ov_owner = 0;
4090 a->filter_eof = 0;
4091 if( a->use == 3 )
4092 a->use = 2; /* make a write stream from a temp stream */
4093
4094 if( a->use == 2 ) { /* allocate a fresh buffer for the original stream */
4095 b->d.buf = xmalloc( a->d.size );
4096 b->d.len = 0;
4097 b->d.start = 0;
4098 }
4099 else { /* allocate a fresh buffer for the new stream */
4100 a->d.buf = xmalloc( a->d.size );
4101 a->d.len = 0;
4102 a->d.start = 0;
4103 }
4104 /* disable nlimit for the new stream */
4105 a->ntotal = b->ntotal + b->nbytes;
4106 a->nlimit = a->nbytes = 0;
4107 a->nofast &= ~1;
4108 /* make a link from the new stream to the original stream */
4109 a->chain = b;
4110 a->opaque = b->opaque;
4111
4112 /* setup the function on the new stream */
4113 a->filter = f;
4114 a->filter_ov = ov;
4115 a->filter_ov_owner = rel_ov;
4116
4117 a->subno = b->subno + 1;
4118 f( ov, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &dummy_len );
4119
4120 if( DBG_IOBUF ) {
4121 log_debug("iobuf-%d.%d: push `%s'\n", a->no, a->subno,
4122 a->desc?a->desc:"?" );
4123 print_chain( a );
4124 }
4125
4126 /* now we can initialize the new function if we have one */
4127 if( a->filter && (rc = a->filter(a->filter_ov, IOBUFCTRL_INIT, a->chain,
4128 NULL, &dummy_len)) )
4129 log_error("IOBUFCTRL_INIT failed: %s\n", g10_errstr(rc) );
4130 return rc;
4131 }
4132
4133 /****************
4134 * Remove an i/o filter.
4135 */
4136 static int
4137 pop_filter( IOBUF a, int (*f)(void *opaque, int control,
4138 IOBUF chain, byte *buf, size_t *len), void *ov )
4139 {
4140 IOBUF b;
4141 size_t dummy_len=0;
4142 int rc=0;
4143
4144 if( a->directfp )
4145 BUG();
4146
4147 if( DBG_IOBUF )
4148 log_debug("iobuf-%d.%d: pop `%s'\n", a->no, a->subno,
4149 a->desc?a->desc:"?" );
4150 if( !a->filter ) { /* this is simple */
4151 b = a->chain;
4152 assert(b);
4153 xfree(a->d.buf);
4154 xfree(a->real_fname);
4155 memcpy(a,b, sizeof *a);
4156 xfree(b);
4157 return 0;
4158 }
4159 for(b=a ; b; b = b->chain )
4160 if( b->filter == f && (!ov || b->filter_ov == ov) )
4161 break;
4162 if( !b )
4163 log_bug("pop_filter(): filter function not found\n");
4164
4165 /* flush this stream if it is an output stream */
4166 if( a->use == 2 && (rc=iobuf_flush(b)) ) {
4167 log_error("iobuf_flush failed in pop_filter: %s\n", g10_errstr(rc));
4168 return rc;
4169 }
4170 /* and tell the filter to free it self */
4171 if( b->filter && (rc = b->filter(b->filter_ov, IOBUFCTRL_FREE, b->chain,
4172 NULL, &dummy_len)) ) {
4173 log_error("IOBUFCTRL_FREE failed: %s\n", g10_errstr(rc) );
4174 return rc;
4175 }
4176 if( b->filter_ov && b->filter_ov_owner ) {
4177 xfree( b->filter_ov );
4178 b->filter_ov = NULL;
4179 }
4180
4181
4182 /* and see how to remove it */
4183 if( a == b && !b->chain )
4184 log_bug("can't remove the last filter from the chain\n");
4185 else if( a == b ) { /* remove the first iobuf from the chain */
4186 /* everything from b is copied to a. This is save because
4187 * a flush has been done on the to be removed entry
4188 */
4189 b = a->chain;
4190 xfree(a->d.buf);
4191 xfree(a->real_fname);
4192 memcpy(a,b, sizeof *a);
4193 xfree(b);
4194 if( DBG_IOBUF )
4195 log_debug("iobuf-%d.%d: popped filter\n", a->no, a->subno );
4196 }
4197 else if( !b->chain ) { /* remove the last iobuf from the chain */
4198 log_bug("Ohh jeee, trying to remove a head filter\n");
4199 }
4200 else { /* remove an intermediate iobuf from the chain */
4201 log_bug("Ohh jeee, trying to remove an intermediate filter\n");
4202 }
4203
4204 return rc;
4205 }
4206
4207
4208 /****************
4209 * read underflow: read more bytes into the buffer and return
4210 * the first byte or -1 on EOF.
4211 */
4212 static int
4213 underflow(IOBUF a)
4214 {
4215 size_t len;
4216 int rc;
4217
4218 assert( a->d.start == a->d.len );
4219 if( a->use == 3 )
4220 return -1; /* EOF because a temp buffer can't do an underflow */
4221
4222 if( a->filter_eof ) {
4223 if( a->chain ) {
4224 IOBUF b = a->chain;
4225 if( DBG_IOBUF )
4226 log_debug("iobuf-%d.%d: pop `%s' in underflow\n",
4227 a->no, a->subno, a->desc?a->desc:"?" );
4228 xfree(a->d.buf);
4229 xfree(a->real_fname);
4230 memcpy(a, b, sizeof *a);
4231 xfree(b);
4232 print_chain(a);
4233 }
4234 else
4235 a->filter_eof = 0; /* for the top level filter */
4236 if( DBG_IOBUF )
4237 log_debug("iobuf-%d.%d: underflow: eof (due to filter eof)\n",
4238 a->no, a->subno );
4239 return -1; /* return one(!) EOF */
4240 }
4241 if( a->error ) {
4242 if( DBG_IOBUF )
4243 log_debug("iobuf-%d.%d: error\n", a->no, a->subno );
4244 return -1;
4245 }
4246
4247 if( a->directfp ) {
4248 FILE *fp = a->directfp;
4249
4250 len = fread( a->d.buf, 1, a->d.size, fp);
4251 if( len < a->d.size ) {
4252 if( ferror(fp) )
4253 a->error = 1;
4254 }
4255 a->d.len = len;
4256 a->d.start = 0;
4257 return len? a->d.buf[a->d.start++] : -1;
4258 }
4259
4260
4261 if( a->filter ) {
4262 len = a->d.size;
4263 if( DBG_IOBUF )
4264 log_debug("iobuf-%d.%d: underflow: req=%lu\n",
4265 a->no, a->subno, (ulong)len );
4266 rc = a->filter( a->filter_ov, IOBUFCTRL_UNDERFLOW, a->chain,
4267 a->d.buf, &len );
4268 if( DBG_IOBUF ) {
4269 log_debug("iobuf-%d.%d: underflow: got=%lu rc=%d\n",
4270 a->no, a->subno, (ulong)len, rc );
4271 /* if( a->no == 1 ) */
4272 /* log_hexdump (" data:", a->d.buf, len); */
4273 }
4274 if( a->use == 1 && rc == -1 ) { /* EOF: we can remove the filter */
4275 size_t dummy_len=0;
4276
4277 /* and tell the filter to free itself */
4278 if( (rc = a->filter(a->filter_ov, IOBUFCTRL_FREE, a->chain,
4279 NULL, &dummy_len)) )
4280 log_error("IOBUFCTRL_FREE failed: %s\n", g10_errstr(rc) );
4281 if( a->filter_ov && a->filter_ov_owner ) {
4282 xfree( a->filter_ov );
4283 a->filter_ov = NULL;
4284 }
4285 a->filter = NULL;
4286 a->desc = NULL;
4287 a->filter_ov = NULL;
4288 a->filter_eof = 1;
4289 if( !len && a->chain ) {
4290 IOBUF b = a->chain;
4291 if( DBG_IOBUF )
4292 log_debug("iobuf-%d.%d: pop in underflow (!len)\n",
4293 a->no, a->subno);
4294 xfree(a->d.buf);
4295 xfree(a->real_fname);
4296 memcpy(a,b, sizeof *a);
4297 xfree(b);
4298 print_chain(a);
4299 }
4300 }
4301 else if( rc )
4302 a->error = 1;
4303
4304 if( !len ) {
4305 if( DBG_IOBUF )
4306 log_debug("iobuf-%d.%d: underflow: eof\n", a->no, a->subno );
4307 return -1;
4308 }
4309 a->d.len = len;
4310 a->d.start = 0;
4311 return a->d.buf[a->d.start++];
4312 }
4313 else {
4314 if( DBG_IOBUF )
4315 log_debug("iobuf-%d.%d: underflow: eof (no filter)\n",
4316 a->no, a->subno );
4317 return -1; /* no filter; return EOF */
4318 }
4319 }
4320
4321
4322 int
4323 iobuf_flush(IOBUF a)
4324 {
4325 size_t len;
4326 int rc;
4327
4328 if( a->directfp )
4329 return 0;
4330
4331 if( a->use == 3 ) { /* increase the temp buffer */
4332 char *newbuf;
4333 size_t newsize = a->d.size + IOBUF_BUFFER_SIZE;
4334
4335 if( DBG_IOBUF )
4336 log_debug("increasing temp iobuf from %lu to %lu\n",
4337 (ulong)a->d.size, (ulong)newsize );
4338 newbuf = xmalloc( newsize );
4339 memcpy( newbuf, a->d.buf, a->d.len );
4340 xfree(a->d.buf);
4341 a->d.buf = newbuf;
4342 a->d.size = newsize;
4343 return 0;
4344 }
4345 else if( a->use != 2 )
4346 log_bug("flush on non-output iobuf\n");
4347 else if( !a->filter )
4348 log_bug("iobuf_flush: no filter\n");
4349 len = a->d.len;
4350 rc = a->filter( a->filter_ov, IOBUFCTRL_FLUSH, a->chain, a->d.buf, &len );
4351 if( !rc && len != a->d.len ) {
4352 log_info("iobuf_flush did not write all!\n");
4353 rc = G10ERR_WRITE_FILE;
4354 }
4355 else if( rc )
4356 a->error = 1;
4357 a->d.len = 0;
4358
4359 return rc;
4360 }
4361
4362
4363 /****************
4364 * Read a byte from the iobuf; returns -1 on EOF
4365 */
4366 int
4367 iobuf_readbyte(IOBUF a)
4368 {
4369 int c;
4370
4371 /* nlimit does not work together with unget */
4372 /* nbytes is also not valid! */
4373 if( a->unget.buf ) {
4374 if( a->unget.start < a->unget.len )
4375 return a->unget.buf[a->unget.start++];
4376 xfree(a->unget.buf);
4377 a->unget.buf = NULL;
4378 a->nofast &= ~2;
4379 }
4380
4381 if( a->nlimit && a->nbytes >= a->nlimit )
4382 return -1; /* forced EOF */
4383
4384 if( a->d.start < a->d.len ) {
4385 c = a->d.buf[a->d.start++];
4386 }
4387 else if( (c=underflow(a)) == -1 )
4388 return -1; /* EOF */
4389
4390 a->nbytes++;
4391 return c;
4392 }
4393
4394
4395 int
4396 iobuf_read(IOBUF a, byte *buf, unsigned buflen )
4397 {
4398 int c, n;
4399
4400 if( a->unget.buf || a->nlimit ) {
4401 /* handle special cases */
4402 for(n=0 ; n < buflen; n++ ) {
4403 if( (c = iobuf_readbyte(a)) == -1 ) {
4404 if( !n )
4405 return -1; /* eof */
4406 break;
4407 }
4408 else
4409 if( buf ) *buf = c;
4410 if( buf ) buf++;
4411 }
4412 return n;
4413 }
4414
4415 n = 0;
4416 do {
4417 if( n < buflen && a->d.start < a->d.len ) {
4418 unsigned size = a->d.len - a->d.start;
4419 if( size > buflen - n )
4420 size = buflen - n;
4421 if( buf )
4422 memcpy( buf, a->d.buf + a->d.start, size );
4423 n += size;
4424 a->d.start += size;
4425 if( buf )
4426 buf += size;
4427 }
4428 if( n < buflen ) {
4429 if( (c=underflow(a)) == -1 ) {
4430 a->nbytes += n;
4431 return n? n : -1/*EOF*/;
4432 }
4433 if( buf )
4434 *buf++ = c;
4435 n++;
4436 }
4437 } while( n < buflen );
4438 a->nbytes += n;
4439 return n;
4440 }
4441
4442
4443 /****************
4444 * Have a look at the iobuf.
4445 * NOTE: This only works in special cases.
4446 */
4447 int
4448 iobuf_peek(IOBUF a, byte *buf, unsigned buflen )
4449 {
4450 int n=0;
4451
4452 if( a->filter_eof )
4453 return -1;
4454
4455 if( !(a->d.start < a->d.len) ) {
4456 if( underflow(a) == -1 )
4457 return -1;
4458 /* and unget this character */
4459 assert(a->d.start == 1);
4460 a->d.start = 0;
4461 }
4462
4463 for(n=0 ; n < buflen && (a->d.start+n) < a->d.len ; n++, buf++ )
4464 *buf = a->d.buf[n];
4465 return n;
4466 }
4467
4468
4469
4470
4471 int
4472 iobuf_writebyte(IOBUF a, unsigned c)
4473 {
4474
4475 if( a->directfp )
4476 BUG();
4477
4478 if( a->d.len == a->d.size )
4479 if( iobuf_flush(a) )
4480 return -1;
4481
4482 assert( a->d.len < a->d.size );
4483 a->d.buf[a->d.len++] = c;
4484 return 0;
4485 }
4486
4487
4488 int
4489 iobuf_write(IOBUF a, byte *buf, unsigned buflen )
4490 {
4491
4492 if( a->directfp )
4493 BUG();
4494
4495 do {
4496 if( buflen && a->d.len < a->d.size ) {
4497 unsigned size = a->d.size - a->d.len;
4498 if( size > buflen ) size = buflen;
4499 memcpy( a->d.buf + a->d.len, buf, size );
4500 buflen -= size;
4501 buf += size;
4502 a->d.len += size;
4503 }
4504 if( buflen ) {
4505 if( iobuf_flush(a) )
4506 return -1;
4507 }
4508 } while( buflen );
4509 return 0;
4510 }
4511
4512
4513 int
4514 iobuf_writestr(IOBUF a, const char *buf )
4515 {
4516 for( ; *buf; buf++ )
4517 if( iobuf_writebyte(a, *buf) )
4518 return -1;
4519 return 0;
4520 }
4521
4522
4523
4524 /****************
4525 * copy the contents of TEMP to A.
4526 */
4527 int
4528 iobuf_write_temp( IOBUF a, IOBUF temp )
4529 {
4530 while( temp->chain )
4531 pop_filter( temp, temp->filter, NULL );
4532 return iobuf_write(a, temp->d.buf, temp->d.len );
4533 }
4534
4535 /****************
4536 * copy the contents of the temp io stream to BUFFER.
4537 */
4538 size_t
4539 iobuf_temp_to_buffer( IOBUF a, byte *buffer, size_t buflen )
4540 {
4541 size_t n = a->d.len;
4542
4543 if( n > buflen )
4544 n = buflen;
4545 memcpy( buffer, a->d.buf, n );
4546 return n;
4547 }
4548
4549
4550 /****************
4551 * Call this function to terminate processing of the temp stream
4552 * without closing it. This removes all filters from the stream
4553 * makes sure that iobuf_get_temp_{buffer,length}() returns correct
4554 * values.
4555 */
4556 void
4557 iobuf_flush_temp( IOBUF temp )
4558 {
4559 while( temp->chain )
4560 pop_filter( temp, temp->filter, NULL );
4561 }
4562
4563
4564 /****************
4565 * Set a limit on how many bytes may be read from the input stream A.
4566 * Setting the limit to 0 disables this feature.
4567 */
4568 void
4569 iobuf_set_limit( IOBUF a, off_t nlimit )
4570 {
4571 if( nlimit )
4572 a->nofast |= 1;
4573 else
4574 a->nofast &= ~1;
4575 a->nlimit = nlimit;
4576 a->ntotal += a->nbytes;
4577 a->nbytes = 0;
4578 }
4579
4580
4581
4582 /* Return the length of an open file A. IF OVERFLOW is not NULL it
4583 will be set to true if the file is larger than what off_t can cope
4584 with. The function return 0 on error or on overflow condition. */
4585 off_t
4586 iobuf_get_filelength (IOBUF a, int *overflow )
4587 {
4588 struct stat st;
4589
4590 if (overflow)
4591 *overflow = 0;
4592
4593 if( a->directfp ) {
4594 FILE *fp = a->directfp;
4595
4596 if( !fstat(fileno(fp), &st) )
4597 return st.st_size;
4598 log_error("fstat() failed: %s\n", strerror(errno) );
4599 return 0;
4600 }
4601
4602 /* Hmmm: file_filter may have already been removed */
4603 for( ; a; a = a->chain )
4604 if( !a->chain && a->filter == file_filter ) {
4605 file_filter_ctx_t *b = a->filter_ov;
4606 FILEP_OR_FD fp = b->fp;
4607
4608 #if defined(HAVE_DOSISH_SYSTEM) && !defined(FILE_FILTER_USES_STDIO)
4609 ulong size;
4610 static int (* __stdcall get_file_size_ex)
4611 (void *handle, LARGE_INTEGER *size);
4612 static int get_file_size_ex_initialized;
4613
4614 if (!get_file_size_ex_initialized)
4615 {
4616 void *handle;
4617
4618 handle = dlopen ("kernel32.dll", RTLD_LAZY);
4619 if (handle)
4620 {
4621 get_file_size_ex = dlsym (handle, "GetFileSizeEx");
4622 if (!get_file_size_ex)
4623 dlclose (handle);
4624 }
4625 get_file_size_ex_initialized = 1;
4626 }
4627
4628 if (get_file_size_ex)
4629 {
4630 /* This is a newer system with GetFileSizeEx; we use
4631 this then becuase it seem that GetFileSize won't
4632 return a proper error in case a file is larger than
4633 4GB. */
4634 LARGE_INTEGER size;
4635
4636 if (get_file_size_ex (fp, &size))
4637 {
4638 if (!size.u.HighPart)
4639 return size.u.LowPart;
4640 if (overflow)
4641 *overflow = 1;
4642 return 0;
4643 }
4644 }
4645 else
4646 {
4647 if ((size=GetFileSize (fp, NULL)) != 0xffffffff)
4648 return size;
4649 }
4650 log_error ("GetFileSize for handle %p failed: %s\n",
4651 fp, w32_strerror (0));
4652 #else
4653 if( !fstat(my_fileno(fp), &st) )
4654 return st.st_size;
4655 log_error("fstat() failed: %s\n", strerror(errno) );
4656 #endif
4657 break;
4658 }
4659
4660 return 0;
4661 }
4662
4663
4664 /* Return the file descriptor of the underlying file or -1 if it is
4665 not available. */
4666 int
4667 iobuf_get_fd (IOBUF a)
4668 {
4669 if (a->directfp)
4670 return fileno ( (FILE*)a->directfp );
4671
4672 for ( ; a; a = a->chain )
4673 if (!a->chain && a->filter == file_filter)
4674 {
4675 file_filter_ctx_t *b = a->filter_ov;
4676 FILEP_OR_FD fp = b->fp;
4677
4678 return my_fileno (fp);
4679 }
4680
4681 return -1;
4682 }
4683
4684
4685 /****************
4686 * Tell the file position, where the next read will take place
4687 */
4688 off_t
4689 iobuf_tell( IOBUF a )
4690 {
4691 return a->ntotal + a->nbytes;
4692 }
4693
4694
4695 #if !defined(HAVE_FSEEKO) && !defined(fseeko)
4696
4697 #ifdef HAVE_LIMITS_H
4698 # include <limits.h>
4699 #endif
4700 #ifndef LONG_MAX
4701 # define LONG_MAX ((long) ((unsigned long) -1 >> 1))
4702 #endif
4703 #ifndef LONG_MIN
4704 # define LONG_MIN (-1 - LONG_MAX)
4705 #endif
4706
4707 /****************
4708 * A substitute for fseeko, for hosts that don't have it.
4709 */
4710 static int
4711 fseeko( FILE *stream, off_t newpos, int whence )
4712 {
4713 while( newpos != (long) newpos ) {
4714 long pos = newpos < 0 ? LONG_MIN : LONG_MAX;
4715 if( fseek( stream, pos, whence ) != 0 )
4716 return -1;
4717 newpos -= pos;
4718 whence = SEEK_CUR;
4719 }
4720 return fseek( stream, (long)newpos, whence );
4721 }
4722 #endif
4723
4724 /****************
4725 * This is a very limited implementation. It simply discards all internal
4726 * buffering and removes all filters but the first one.
4727 */
4728 int
4729 iobuf_seek( IOBUF a, off_t newpos )
4730 {
4731 file_filter_ctx_t *b = NULL;
4732
4733 if( a->directfp ) {
4734 FILE *fp = a->directfp;
4735 if( fseeko( fp, newpos, SEEK_SET ) ) {
4736 log_error("can't seek: %s\n", strerror(errno) );
4737 return -1;
4738 }
4739 clearerr(fp);
4740 }
4741 else {
4742 for( ; a; a = a->chain ) {
4743 if( !a->chain && a->filter == file_filter ) {
4744 b = a->filter_ov;
4745 break;
4746 }
4747 }
4748 if( !a )
4749 return -1;
4750 #ifdef FILE_FILTER_USES_STDIO
4751 if( fseeko( b->fp, newpos, SEEK_SET ) ) {
4752 log_error("can't fseek: %s\n", strerror(errno) );
4753 return -1;
4754 }
4755 #else
4756 #ifdef HAVE_DOSISH_SYSTEM
4757 if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff ) {
4758 log_error ("SetFilePointer failed on handle %p: %s\n",
4759 b->fp, w32_strerror (0));
4760 return -1;
4761 }
4762 #else
4763 if ( lseek (b->fp, newpos, SEEK_SET) == (off_t)-1 ) {
4764 log_error("can't lseek: %s\n", strerror(errno) );
4765 return -1;
4766 }
4767 #endif
4768 #endif
4769 }
4770 a->d.len = 0; /* discard buffer */
4771 a->d.start = 0;
4772 a->nbytes = 0;
4773 a->nlimit = 0;
4774 a->nofast &= ~1;
4775 a->ntotal = newpos;
4776 a->error = 0;
4777 /* remove filters, but the last */
4778 if( a->chain )
4779 log_debug("pop_filter called in iobuf_seek - please report\n");
4780 while( a->chain )
4781 pop_filter( a, a->filter, NULL );
4782
4783 return 0;
4784 }
4785
4786
4787
4788
4789
4790
4791 /****************
4792 * Retrieve the real filename
4793 */
4794 const char *
4795 iobuf_get_real_fname( IOBUF a )
4796 {
4797 if( a->real_fname )
4798 return a->real_fname;
4799
4800 /* the old solution */
4801 for( ; a; a = a->chain )
4802 if( !a->chain && a->filter == file_filter ) {
4803 file_filter_ctx_t *b = a->filter_ov;
4804 return b->print_only_name? NULL : b->fname;
4805 }
4806
4807 return NULL;
4808 }
4809
4810
4811 /****************
4812 * Retrieve the filename
4813 */
4814 const char *
4815 iobuf_get_fname( IOBUF a )
4816 {
4817 for( ; a; a = a->chain )
4818 if( !a->chain && a->filter == file_filter ) {
4819 file_filter_ctx_t *b = a->filter_ov;
4820 return b->fname;
4821 }
4822
4823 return NULL;
4824 }
4825
4826
4827 /****************
4828 * enable partial block mode as described in the OpenPGP draft.
4829 * LEN is the first length byte on read, but ignored on writes.
4830 */
4831 void
4832 iobuf_set_partial_block_mode( IOBUF a, size_t len )
4833 {
4834 block_filter_ctx_t *ctx = xmalloc_clear( sizeof *ctx );
4835
4836 assert( a->use == 1 || a->use == 2 );
4837 ctx->use = a->use;
4838 if( !len ) {
4839 if( a->use == 1 )
4840 log_debug("pop_filter called in set_partial_block_mode"
4841 " - please report\n");
4842 pop_filter(a, block_filter, NULL );
4843 }
4844 else {
4845 ctx->partial = 1;
4846 ctx->size = 0;
4847 ctx->first_c = len;
4848 iobuf_push_filter(a, block_filter, ctx );
4849 }
4850 }
4851
4852
4853 /****************
4854 * Same as fgets() but if the buffer is too short a larger one will
4855 * be allocated up to some limit *max_length.
4856 * A line is considered a byte stream ending in a LF.
4857 * Returns the length of the line. EOF is indicated by a line of
4858 * length zero. The last LF may be missing due to an EOF.
4859 * is max_length is zero on return, the line has been truncated.
4860 *
4861 * Note: The buffer is allocated with enough space to append a CR,LF,EOL
4862 */
4863 unsigned
4864 iobuf_read_line( IOBUF a, byte **addr_of_buffer,
4865 unsigned *length_of_buffer, unsigned *max_length )
4866 {
4867 int c;
4868 char *buffer = *addr_of_buffer;
4869 unsigned length = *length_of_buffer;
4870 unsigned nbytes = 0;
4871 unsigned maxlen = *max_length;
4872 char *p;
4873
4874 if( !buffer ) { /* must allocate a new buffer */
4875 length = 256;
4876 buffer = xmalloc( length );
4877 *addr_of_buffer = buffer;
4878 *length_of_buffer = length;
4879 }
4880
4881 length -= 3; /* reserve 3 bytes (cr,lf,eol) */
4882 p = buffer;
4883 while( (c=iobuf_get(a)) != -1 ) {
4884 if( nbytes == length ) { /* increase the buffer */
4885 if( length > maxlen ) { /* this is out limit */
4886 /* skip the rest of the line */
4887 while( c != '\n' && (c=iobuf_get(a)) != -1 )
4888 ;
4889 *p++ = '\n'; /* always append a LF (we have reserved space) */
4890 nbytes++;
4891 *max_length = 0; /* indicate truncation */
4892 break;
4893 }
4894 length += 3; /* correct for the reserved byte */
4895 length += length < 1024? 256 : 1024;
4896 buffer = xrealloc( buffer, length );
4897 *addr_of_buffer = buffer;
4898 *length_of_buffer = length;
4899 length -= 3; /* and reserve again */
4900 p = buffer + nbytes;
4901 }
4902 *p++ = c;
4903 nbytes++;
4904 if( c == '\n' )
4905 break;
4906 }
4907 *p = 0; /* make sure the line is a string */
4908
4909 return nbytes;
4910 }
4911
4912 /* This is the non iobuf specific function */
4913 int
4914 iobuf_translate_file_handle ( int fd, int for_write )
4915 {
4916 #ifdef _WIN32
4917 {
4918 int x;
4919
4920 if ( fd <= 2 )
4921 return fd; /* do not do this for error, stdin, stdout, stderr */
4922
4923 x = _open_osfhandle ( fd, for_write? 1:0 );
4924 if (x==-1 )
4925 log_error ("failed to translate osfhandle %p\n", (void*)fd );
4926 else {
4927 /*log_info ("_open_osfhandle %p yields %d%s\n",
4928 (void*)fd, x, for_write? " for writing":"" );*/
4929 fd = x;
4930 }
4931 }
4932 #endif
4933 return fd;
4934 }
4935
4936 static int
4937 translate_file_handle ( int fd, int for_write )
4938 {
4939 #ifdef _WIN32
4940 #ifdef FILE_FILTER_USES_STDIO
4941 fd = iobuf_translate_file_handle (fd, for_write);
4942 #else
4943 {
4944 int x;
4945
4946 if ( fd == 0 )
4947 x = (int)GetStdHandle (STD_INPUT_HANDLE);
4948 else if (fd == 1)
4949 x = (int)GetStdHandle (STD_OUTPUT_HANDLE);
4950 else if (fd == 2)
4951 x = (int)GetStdHandle (STD_ERROR_HANDLE);
4952 else
4953 x = fd;
4954
4955 if (x == -1)
4956 log_debug ("GetStdHandle(%d) failed: %s\n",
4957 fd, w32_strerror (0));
4958
4959 fd = x;
4960 }
4961 #endif
4962 #endif
4963 return fd;
4964 }
4965
4966
4967 void
4968 iobuf_skip_rest(IOBUF a, unsigned long n, int partial)
4969 {
4970 if ( partial ) {
4971 for (;;) {
4972 if (a->nofast || a->d.start >= a->d.len) {
4973 if (iobuf_readbyte (a) == -1) {
4974 break;
4975 }
4976 } else {
4977 unsigned long count = a->d.len - a->d.start;
4978 a->nbytes += count;
4979 a->d.start = a->d.len;
4980 }
4981 }
4982 } else {
4983 unsigned long remaining = n;
4984 while (remaining > 0) {
4985 if (a->nofast || a->d.start >= a->d.len) {
4986 if (iobuf_readbyte (a) == -1) {
4987 break;
4988 }
4989 --remaining;
4990 } else {
4991 unsigned long count = a->d.len - a->d.start;
4992 if (count > remaining) {
4993 count = remaining;
4994 }
4995 a->nbytes += count;
4996 a->d.start += count;
4997 remaining -= count;
4998 }
4999 }
5000 }
5001 }
-
+ A4CA272E00EBA069786CB1EDFB3F7054C5B31630A22AE66C012878D4BCEE96B11298141730589F0A0DDB04EEFF1C2F4EEF5A25D88447226F32EAA5346595EA96
mpi/logger.c
(0 . 0)(1 . 262)
5006 /* logger.c - log functions
5007 * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
5008 *
5009 * This file is part of GnuPG.
5010 *
5011 * GnuPG is free software; you can redistribute it and/or modify
5012 * it under the terms of the GNU General Public License as published by
5013 * the Free Software Foundation; either version 3 of the License, or
5014 * (at your option) any later version.
5015 *
5016 * GnuPG is distributed in the hope that it will be useful,
5017 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5019 * GNU General Public License for more details.
5020 *
5021 * You should have received a copy of the GNU General Public License
5022 * along with this program; if not, see <http://www.gnu.org/licenses/>.
5023 */
5024
5025 #include <config.h>
5026 #include <stdio.h>
5027 #include <stdlib.h>
5028 #include <stdarg.h>
5029 #include <string.h>
5030 #include <errno.h>
5031
5032 #include "util.h"
5033
5034 static char pidstring[15];
5035 static char *pgm_name;
5036 static int errorcount;
5037 static int strict;
5038 static FILE *logfp;
5039
5040 /****************
5041 * Set the logfile to use (not yet implemneted) or, if logfile is NULL,
5042 * the Fd where logoutputs should go.
5043 */
5044 void
5045 log_set_logfile( const char *name, int fd )
5046 {
5047 if( name )
5048 BUG();
5049
5050 if( logfp && logfp != stderr && logfp != stdout )
5051 fclose( logfp );
5052 if( fd == 1 )
5053 logfp = stdout;
5054 else if( fd == 2 )
5055 logfp = stderr;
5056 else
5057 logfp = fdopen( fd, "a" );
5058 if( !logfp ) {
5059 logfp = stderr;
5060 log_fatal("can't open fd %d for logging: %s\n", fd, strerror(errno));
5061 }
5062 }
5063
5064 FILE *
5065 log_stream()
5066 {
5067 if( !logfp )
5068 logfp = stderr;
5069 return logfp;
5070 }
5071
5072
5073 void
5074 log_set_name( const char *name )
5075 {
5076 xfree(pgm_name);
5077 if( name )
5078 pgm_name = xstrdup(name);
5079 else
5080 pgm_name = NULL;
5081 }
5082
5083 const char *
5084 log_get_name(void)
5085 {
5086 return pgm_name? pgm_name : "";
5087 }
5088
5089
5090 void
5091 log_set_pid( int pid )
5092 {
5093 if( pid )
5094 sprintf(pidstring,"[%u]", (unsigned)pid );
5095 else
5096 *pidstring = 0;
5097 }
5098
5099 int
5100 log_get_errorcount( int clear)
5101 {
5102 int n = errorcount;
5103 if( clear )
5104 errorcount = 0;
5105 return n;
5106 }
5107
5108 void
5109 log_inc_errorcount()
5110 {
5111 errorcount++;
5112 }
5113
5114 int
5115 log_set_strict(int val)
5116 {
5117 int old=strict;
5118 strict=val;
5119 return old;
5120 }
5121
5122 void
5123 g10_log_print_prefix(const char *text)
5124 {
5125 if( !logfp )
5126 logfp = stderr;
5127 if( pgm_name )
5128 fprintf(logfp, "%s%s: %s", pgm_name, pidstring, text );
5129 else
5130 fprintf(logfp, "?%s: %s", pidstring, text );
5131 #ifdef __riscos__
5132 fflush( logfp );
5133 #endif /* __riscos__ */
5134 }
5135
5136
5137 void
5138 g10_log_info( const char *fmt, ... )
5139 {
5140 va_list arg_ptr ;
5141
5142 g10_log_print_prefix("");
5143 va_start( arg_ptr, fmt ) ;
5144 vfprintf(logfp,fmt,arg_ptr) ;
5145 va_end(arg_ptr);
5146 #ifdef __riscos__
5147 fflush( logfp );
5148 #endif /* __riscos__ */
5149 }
5150
5151
5152 void
5153 g10_log_warning( const char *fmt, ... )
5154 {
5155 va_list arg_ptr ;
5156
5157 if(strict)
5158 {
5159 errorcount++;
5160 g10_log_print_prefix(_("ERROR: "));
5161 }
5162 else
5163 g10_log_print_prefix(_("WARNING: "));
5164
5165 va_start( arg_ptr, fmt ) ;
5166 vfprintf(logfp,fmt,arg_ptr) ;
5167 va_end(arg_ptr);
5168 #ifdef __riscos__
5169 fflush( logfp );
5170 #endif /* __riscos__ */
5171 }
5172
5173
5174 void
5175 g10_log_error( const char *fmt, ... )
5176 {
5177 va_list arg_ptr ;
5178
5179 g10_log_print_prefix("");
5180 va_start( arg_ptr, fmt ) ;
5181 vfprintf(logfp,fmt,arg_ptr) ;
5182 va_end(arg_ptr);
5183 errorcount++;
5184 #ifdef __riscos__
5185 fflush( logfp );
5186 #endif /* __riscos__ */
5187 }
5188
5189
5190 void
5191 g10_log_fatal( const char *fmt, ... )
5192 {
5193 va_list arg_ptr ;
5194
5195 g10_log_print_prefix("fatal: ");
5196 va_start( arg_ptr, fmt ) ;
5197 vfprintf(logfp,fmt,arg_ptr) ;
5198 va_end(arg_ptr);
5199 secmem_dump_stats();
5200 #ifdef __riscos__
5201 fflush( logfp );
5202 #endif /* __riscos__ */
5203 exit(2);
5204 }
5205
5206 void
5207 g10_log_bug( const char *fmt, ... )
5208 {
5209 va_list arg_ptr ;
5210
5211 putc('\n', stderr );
5212 g10_log_print_prefix("Ohhhh jeeee: ");
5213 va_start( arg_ptr, fmt ) ;
5214 vfprintf(stderr,fmt,arg_ptr) ;
5215 va_end(arg_ptr);
5216 fflush(stderr);
5217 secmem_dump_stats();
5218 abort();
5219 }
5220
5221 #if defined (__riscos__) \
5222 || ( __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ))
5223 void
5224 g10_log_bug0( const char *file, int line, const char *func )
5225 {
5226 log_bug(_("... this is a bug (%s:%d:%s)\n"), file, line, func );
5227 }
5228 #else
5229 void
5230 g10_log_bug0( const char *file, int line )
5231 {
5232 log_bug(_("you found a bug ... (%s:%d)\n"), file, line);
5233 }
5234 #endif
5235
5236 void
5237 g10_log_debug( const char *fmt, ... )
5238 {
5239 va_list arg_ptr ;
5240
5241 g10_log_print_prefix("DBG: ");
5242 va_start( arg_ptr, fmt ) ;
5243 vfprintf(logfp,fmt,arg_ptr) ;
5244 va_end(arg_ptr);
5245 #ifdef __riscos__
5246 fflush( logfp );
5247 #endif /* __riscos__ */
5248 }
5249
5250
5251
5252 void
5253 g10_log_hexdump( const char *text, const char *buf, size_t len )
5254 {
5255 int i;
5256
5257 g10_log_print_prefix(text);
5258 for(i=0; i < len; i++ )
5259 fprintf(logfp, " %02X", ((const byte*)buf)[i] );
5260 fputc('\n', logfp);
5261 #ifdef __riscos__
5262 fflush( logfp );
5263 #endif /* __riscos__ */
5264 }
5265
5266
5267
-
+ D946187EDC8013ACEC997499092EB30464487922925230FBFE5D21EA6CD76320625E947B8F47CF19EC4C47987CC5DCD0C22E6DBFB4B40E4B0F93189C29B5BFC9
mpi/Makefile
(0 . 0)(1 . 25)
5272 PROGRAM = mpi.a
5273
5274 BUILD=obj
5275 DIST=bin
5276
5277 CXX = gcc
5278 OBJECTS = $(addprefix $(BUILD)/, $(patsubst %.c,%.o,$(wildcard *.c)))
5279 FLAGS = -g -Wall
5280 INCLUDE = -I include
5281
5282 .SUFFIXES: .o .c
5283
5284 $(BUILD)/%.o:
5285 $(CXX) $(FLAGS) $(INCLUDE) -c $*.c -o $@
5286
5287 all: $(PROGRAM)
5288
5289 $(PROGRAM): $(OBJECTS)
5290 ar rcs $(DIST)/$(PROGRAM) $(OBJECTS)
5291
5292 clean :
5293 rm -rf nul core *flymake* $(BUILD)/*.o $(DIST)/$(PROGRAM) *~ bin/*
5294
5295 check-syntax:
5296 $(CXX) -c $(FLAGS) $(INCLUDE) -o nul -Wall -S $(CHK_SOURCES)
-
+ 9DEA2170DE57AC92123D3DAC0FD5930BC5C1A5AC88CA1C2FDA88C8555091A38E5862FD7AC5BCED9393349F66AB970707B27D759FE0041F358A0D205E066ECDE0
mpi/memory.c
(0 . 0)(1 . 681)
5301 /* memory.c - memory allocation
5302 * Copyright (C) 1998, 1999, 2001, 2005 Free Software Foundation, Inc.
5303 *
5304 * This file is part of GnuPG.
5305 *
5306 * GnuPG is free software; you can redistribute it and/or modify
5307 * it under the terms of the GNU General Public License as published by
5308 * the Free Software Foundation; either version 3 of the License, or
5309 * (at your option) any later version.
5310 *
5311 * GnuPG is distributed in the hope that it will be useful,
5312 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5313 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5314 * GNU General Public License for more details.
5315 *
5316 * You should have received a copy of the GNU General Public License
5317 * along with this program; if not, see <http://www.gnu.org/licenses/>.
5318 *
5319 *
5320 * We use our own memory allocation functions instead of plain malloc(),
5321 * so that we can provide some special enhancements:
5322 * a) functions to provide memory from a secure memory.
5323 * b) by looking at the requested allocation size we
5324 * can reuse memory very quickly (e.g. MPI storage)
5325 * (really needed?)
5326 * c) memory usage reporting if compiled with M_DEBUG
5327 * d) memory checking if compiled with M_GUARD
5328 */
5329
5330 #include <config.h>
5331 #include <stdio.h>
5332 #include <stdlib.h>
5333 #include <string.h>
5334 #include <stdarg.h>
5335
5336 #include "types.h"
5337 #include "memory.h"
5338 #include "util.h"
5339
5340
5341 #define MAGIC_NOR_BYTE 0x55
5342 #define MAGIC_SEC_BYTE 0xcc
5343 #define MAGIC_END_BYTE 0xaa
5344
5345 /* This is a very crude alignment check which does not work on all CPUs
5346 * IIRC, I once introduced it for testing on an Alpha. We should better
5347 * replace this guard stuff with one provided by a modern malloc library
5348 */
5349 #if SIZEOF_UNSIGNED_LONG == 8
5350 #define EXTRA_ALIGN 4
5351 #else
5352 #define EXTRA_ALIGN 0
5353 #endif
5354
5355 #if defined(M_DEBUG) || defined(M_GUARD)
5356 static void membug( const char *fmt, ... );
5357 #endif
5358
5359 #ifdef M_DEBUG
5360
5361 #ifndef M_GUARD
5362 #define M_GUARD 1
5363 #endif
5364 #undef xmalloc
5365 #undef xtrymalloc
5366 #undef xmalloc_clear
5367 #undef xmalloc_secure
5368 #undef xmalloc_secure_clear
5369 #undef xrealloc
5370 #undef xfree
5371 #undef m_check
5372 #undef xstrdup
5373 #undef xtrystrdup
5374 #define FNAME(a) m_debug_ ##a
5375 #define FNAMEX(a) m_debug_ ##a
5376 #define FNAMEXM(a) m_debug_ ##a
5377 #define FNAMEPRT , const char *info
5378 #define FNAMEARG , info
5379 #ifndef __riscos__
5380 #define store_len(p,n,m) do { add_entry(p,n,m, \
5381 info, __FUNCTION__); } while(0)
5382 #else
5383 #define store_len(p,n,m) do { add_entry(p,n,m, \
5384 info, __func__ ); } while(0)
5385 #endif
5386 #else
5387 #define FNAME(a) m_ ##a
5388 #define FNAMEX(a) x ##a
5389 #define FNAMEXM(a) xm ##a
5390 #define FNAMEPRT
5391 #define FNAMEARG
5392 #define store_len(p,n,m) do { ((byte*)p)[EXTRA_ALIGN+0] = n; \
5393 ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ; \
5394 ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ; \
5395 ((byte*)p)[EXTRA_ALIGN+3] = m? MAGIC_SEC_BYTE \
5396 : MAGIC_NOR_BYTE; \
5397 } while(0)
5398 #endif
5399
5400
5401 #ifdef M_GUARD
5402 static long used_memory;
5403 #endif
5404
5405 #ifdef M_DEBUG /* stuff used for memory debuging */
5406
5407 struct info_entry {
5408 struct info_entry *next;
5409 unsigned count; /* call count */
5410 const char *info; /* the reference to the info string */
5411 };
5412
5413 struct memtbl_entry {
5414 const void *user_p; /* for reference: the pointer given to the user */
5415 size_t user_n; /* length requested by the user */
5416 struct memtbl_entry *next; /* to build a list of unused entries */
5417 const struct info_entry *info; /* points into the table with */
5418 /* the info strings */
5419 unsigned inuse:1; /* this entry is in use */
5420 unsigned count:31;
5421 };
5422
5423
5424 #define INFO_BUCKETS 53
5425 #define info_hash(p) ( *(u32*)((p)) % INFO_BUCKETS )
5426 static struct info_entry *info_strings[INFO_BUCKETS]; /* hash table */
5427
5428 static struct memtbl_entry *memtbl; /* the table with the memory info */
5429 static unsigned memtbl_size; /* number of allocated entries */
5430 static unsigned memtbl_len; /* number of used entries */
5431 static struct memtbl_entry *memtbl_unused;/* to keep track of unused entries */
5432
5433 static void dump_table_at_exit(void);
5434 static void dump_table(void);
5435 static void check_allmem( const char *info );
5436
5437 /****************
5438 * Put the new P into the debug table and return a pointer to the table entry.
5439 * mode is true for security. BY is the name of the function which called us.
5440 */
5441 static void
5442 add_entry( byte *p, unsigned n, int mode, const char *info, const char *by )
5443 {
5444 unsigned index;
5445 struct memtbl_entry *e;
5446 struct info_entry *ie;
5447
5448 if( memtbl_len < memtbl_size )
5449 index = memtbl_len++;
5450 else {
5451 struct memtbl_entry *e;
5452 /* look for a used entry in the table. We take the first one,
5453 * so that freed entries remain as long as possible in the table
5454 * (free appends a new one)
5455 */
5456 if( (e = memtbl_unused) ) {
5457 index = e - memtbl;
5458 memtbl_unused = e->next;
5459 e->next = NULL;
5460 }
5461 else { /* no free entries in the table: extend the table */
5462 if( !memtbl_size ) { /* first time */
5463 memtbl_size = 100;
5464 if( !(memtbl = calloc( memtbl_size, sizeof *memtbl )) )
5465 membug("memory debug table malloc failed\n");
5466 index = 0;
5467 memtbl_len = 1;
5468 atexit( dump_table_at_exit );
5469 }
5470 else { /* realloc */
5471 unsigned n = memtbl_size / 4; /* enlarge by 25% */
5472 if(!(memtbl = realloc(memtbl, (memtbl_size+n)*sizeof *memtbl)))
5473 membug("memory debug table realloc failed\n");
5474 memset(memtbl+memtbl_size, 0, n*sizeof *memtbl );
5475 memtbl_size += n;
5476 index = memtbl_len++;
5477 }
5478 }
5479 }
5480 e = memtbl+index;
5481 if( e->inuse )
5482 membug("Ooops: entry %u is flagged as in use\n", index);
5483 e->user_p = p + EXTRA_ALIGN + 4;
5484 e->user_n = n;
5485 e->count++;
5486 if( e->next )
5487 membug("Ooops: entry is in free entry list\n");
5488 /* do we already have this info string */
5489 for( ie = info_strings[info_hash(info)]; ie; ie = ie->next )
5490 if( ie->info == info )
5491 break;
5492 if( !ie ) { /* no: make a new entry */
5493 if( !(ie = malloc( sizeof *ie )) )
5494 membug("can't allocate info entry\n");
5495 ie->next = info_strings[info_hash(info)];
5496 info_strings[info_hash(info)] = ie;
5497 ie->info = info;
5498 ie->count = 0;
5499 }
5500 ie->count++;
5501 e->info = ie;
5502 e->inuse = 1;
5503
5504 /* put the index at the start of the memory */
5505 p[EXTRA_ALIGN+0] = index;
5506 p[EXTRA_ALIGN+1] = index >> 8 ;
5507 p[EXTRA_ALIGN+2] = index >> 16 ;
5508 p[EXTRA_ALIGN+3] = mode? MAGIC_SEC_BYTE : MAGIC_NOR_BYTE ;
5509 if( DBG_MEMORY )
5510 log_debug( "%s allocates %u bytes using %s\n", info, e->user_n, by );
5511 }
5512
5513
5514
5515 /****************
5516 * Check that the memory block is correct. The magic byte has already been
5517 * checked. Checks which are done here:
5518 * - see whether the index points into our memory table
5519 * - see whether P is the same as the one stored in the table
5520 * - see whether we have already freed this block.
5521 */
5522 struct memtbl_entry *
5523 check_mem( const byte *p, const char *info )
5524 {
5525 unsigned n;
5526 struct memtbl_entry *e;
5527
5528 n = p[EXTRA_ALIGN+0];
5529 n |= p[EXTRA_ALIGN+1] << 8;
5530 n |= p[EXTRA_ALIGN+2] << 16;
5531
5532 if( n >= memtbl_len )
5533 membug("memory at %p corrupted: index=%u table_len=%u (%s)\n",
5534 p+EXTRA_ALIGN+4, n, memtbl_len, info );
5535 e = memtbl+n;
5536
5537 if( e->user_p != p+EXTRA_ALIGN+4 )
5538 membug("memory at %p corrupted: reference mismatch (%s)\n",
5539 p+EXTRA_ALIGN+4, info );
5540 if( !e->inuse )
5541 membug("memory at %p corrupted: marked as free (%s)\n",
5542 p+EXTRA_ALIGN+4, info );
5543
5544 if( !(p[EXTRA_ALIGN+3] == MAGIC_NOR_BYTE
5545 || p[EXTRA_ALIGN+3] == MAGIC_SEC_BYTE) )
5546 membug("memory at %p corrupted: underflow=%02x (%s)\n",
5547 p+EXTRA_ALIGN+4, p[EXTRA_ALIGN+3], info );
5548 if( p[EXTRA_ALIGN+4+e->user_n] != MAGIC_END_BYTE )
5549 membug("memory at %p corrupted: overflow=%02x (%s)\n",
5550 p+EXTRA_ALIGN+4, p[EXTRA_ALIGN+4+e->user_n], info );
5551 return e;
5552 }
5553
5554
5555 /****************
5556 * free the entry and the memory (replaces free)
5557 */
5558 static void
5559 free_entry( byte *p, const char *info )
5560 {
5561 struct memtbl_entry *e, *e2;
5562
5563 check_allmem("add_entry");
5564
5565 e = check_mem(p, info);
5566 if( DBG_MEMORY )
5567 log_debug( "%s frees %u bytes alloced by %s\n",
5568 info, e->user_n, e->info->info );
5569 if( !e->inuse ) {
5570 if( e->user_p == p + EXTRA_ALIGN+ 4 )
5571 membug("freeing an already freed pointer at %p\n", p+EXTRA_ALIGN+4 );
5572 else
5573 membug("freeing pointer %p which is flagged as freed\n", p+EXTRA_ALIGN+4 );
5574 }
5575
5576 e->inuse = 0;
5577 e->next = NULL;
5578 if( !memtbl_unused )
5579 memtbl_unused = e;
5580 else {
5581 for(e2=memtbl_unused; e2->next; e2 = e2->next )
5582 ;
5583 e2->next = e;
5584 }
5585 if( m_is_secure(p+EXTRA_ALIGN+4) )
5586 secmem_free(p);
5587 else {
5588 memset(p,'f', e->user_n+5);
5589 free(p);
5590 }
5591 }
5592
5593 static void
5594 dump_entry(struct memtbl_entry *e )
5595 {
5596 unsigned n = e - memtbl;
5597
5598 fprintf(stderr, "mem %4u%c %5u %p %5u %s (%u)\n",
5599 n, e->inuse?'a':'u', e->count, e->user_p, e->user_n,
5600 e->info->info, e->info->count );
5601
5602
5603 }
5604
5605
5606 static void
5607 dump_table_at_exit( void)
5608 {
5609 if( DBG_MEMSTAT )
5610 dump_table();
5611 }
5612
5613 static void
5614 dump_table( void)
5615 {
5616 unsigned n;
5617 struct memtbl_entry *e;
5618 ulong sum = 0, chunks =0;
5619
5620 for( e = memtbl, n = 0; n < memtbl_len; n++, e++ ) {
5621 if(e->inuse) {
5622 dump_entry(e);
5623 sum += e->user_n;
5624 chunks++;
5625 }
5626 }
5627 fprintf(stderr, " memory used: %8lu bytes in %ld chunks\n",
5628 sum, chunks );
5629 }
5630
5631
5632 static void
5633 check_allmem( const char *info )
5634 {
5635 unsigned n;
5636 struct memtbl_entry *e;
5637
5638 for( e = memtbl, n = 0; n < memtbl_len; n++, e++ ) {
5639 if( e->inuse ) {
5640 #ifndef __riscos__
5641 check_mem(e->user_p-4-EXTRA_ALIGN, info);
5642 #else
5643 check_mem((const byte *) e->user_p-4-EXTRA_ALIGN, info);
5644 #endif
5645 }
5646 }
5647 }
5648
5649 #endif /* M_DEBUG */
5650
5651 #if defined(M_DEBUG) || defined(M_GUARD)
5652 static void
5653 membug( const char *fmt, ... )
5654 {
5655 va_list arg_ptr ;
5656
5657 fprintf(stderr, "\nMemory Error: " ) ;
5658 va_start( arg_ptr, fmt ) ;
5659 vfprintf(stderr,fmt,arg_ptr) ;
5660 va_end(arg_ptr);
5661 fflush(stderr);
5662 #ifdef M_DEBUG
5663 if( DBG_MEMSTAT )
5664 dump_table();
5665 #endif
5666 abort();
5667 }
5668 #endif
5669
5670 void
5671 m_print_stats( const char *prefix )
5672 {
5673 #ifdef M_DEBUG
5674 unsigned n;
5675 struct memtbl_entry *e;
5676 ulong sum = 0, chunks =0;
5677
5678 for( e = memtbl, n = 0; n < memtbl_len; n++, e++ ) {
5679 if(e->inuse) {
5680 sum += e->user_n;
5681 chunks++;
5682 }
5683 }
5684
5685 log_debug( "%s%smemstat: %8lu bytes in %ld chunks used\n",
5686 prefix? prefix:"", prefix? ": ":"", sum, chunks );
5687 #elif defined(M_GUARD)
5688 log_debug( "%s%smemstat: %8ld bytes\n",
5689 prefix? prefix:"", prefix? ": ":"", used_memory );
5690 #endif
5691 }
5692
5693 void
5694 m_dump_table( const char *prefix )
5695 {
5696 #ifdef M_DEBUG
5697 fprintf(stderr,"Memory-Table-Dump: %s\n", prefix);
5698 dump_table();
5699 #endif
5700 m_print_stats( prefix );
5701 }
5702
5703
5704 static void
5705 out_of_core(size_t n, int secure)
5706 {
5707 log_error ("out of %s memory while allocating %u bytes\n",
5708 secure? "secure":"" ,(unsigned)n );
5709 if (secure) {
5710 /*secmem_dump_stats ();*/
5711 log_info ("(this may be caused by too many secret keys used "
5712 "simultaneously or due to excessive large key sizes)\n");
5713 }
5714 #if defined(M_GUARD) && defined(__riscos__)
5715 abort();
5716 #endif
5717 exit (2);
5718 }
5719
5720 /****************
5721 * Allocate memory of size n.
5722 * This function gives up if we do not have enough memory
5723 */
5724 void *
5725 FNAMEXM(alloc)( size_t n FNAMEPRT )
5726 {
5727 char *p;
5728
5729 #ifdef M_GUARD
5730 if(!n)
5731 out_of_core(n,0); /* should never happen */
5732 if( !(p = malloc( n + EXTRA_ALIGN+5 )) )
5733 out_of_core(n,0);
5734 store_len(p,n,0);
5735 used_memory += n;
5736 p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
5737 return p+EXTRA_ALIGN+4;
5738 #else
5739 /* mallocing zero bytes is undefined by ISO-C, so we better make
5740 sure that it won't happen */
5741 if (!n)
5742 n = 1;
5743 if( !(p = malloc( n )) )
5744 out_of_core(n,0);
5745 return p;
5746 #endif
5747 }
5748
5749 /* Allocate memory of size n. This function returns NULL if we do not
5750 have enough memory. */
5751 void *
5752 FNAMEX(trymalloc)(size_t n FNAMEPRT)
5753 {
5754 #ifdef M_GUARD
5755 char *p;
5756
5757 if (!n)
5758 n = 1;
5759 p = malloc (n + EXTRA_ALIGN+5);
5760 if (!p)
5761 return NULL;
5762 store_len(p,n,0);
5763 used_memory += n;
5764 p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
5765 return p+EXTRA_ALIGN+4;
5766 #else
5767 /* Mallocing zero bytes is undefined by ISO-C, so we better make
5768 sure that it won't happen. */
5769 return malloc (n? n: 1);
5770 #endif
5771 }
5772
5773 /****************
5774 * Allocate memory of size n from the secure memory pool.
5775 * This function gives up if we do not have enough memory
5776 */
5777 void *
5778 FNAMEXM(alloc_secure)( size_t n FNAMEPRT )
5779 {
5780 char *p;
5781
5782 #ifdef M_GUARD
5783 if(!n)
5784 out_of_core(n,1); /* should never happen */
5785 if( !(p = secmem_malloc( n +EXTRA_ALIGN+ 5 )) )
5786 out_of_core(n,1);
5787 store_len(p,n,1);
5788 p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
5789 return p+EXTRA_ALIGN+4;
5790 #else
5791 /* mallocing zero bytes is undefined by ISO-C, so we better make
5792 sure that it won't happen */
5793 if (!n)
5794 n = 1;
5795 if( !(p = secmem_malloc( n )) )
5796 out_of_core(n,1);
5797 return p;
5798 #endif
5799 }
5800
5801 void *
5802 FNAMEXM(alloc_clear)( size_t n FNAMEPRT )
5803 {
5804 void *p;
5805 p = FNAMEXM(alloc)( n FNAMEARG );
5806 memset(p, 0, n );
5807 return p;
5808 }
5809
5810 void *
5811 FNAMEXM(alloc_secure_clear)( size_t n FNAMEPRT)
5812 {
5813 void *p;
5814 p = FNAMEXM(alloc_secure)( n FNAMEARG );
5815 memset(p, 0, n );
5816 return p;
5817 }
5818
5819
5820 /****************
5821 * realloc and clear the old space
5822 */
5823 void *
5824 FNAMEX(realloc)( void *a, size_t n FNAMEPRT )
5825 {
5826 void *b;
5827
5828 #ifdef M_GUARD
5829 if( a ) {
5830 #error "--enable-m-guard does not currently work"
5831 unsigned char *p = a;
5832 size_t len = m_size(a);
5833
5834 if( len >= n ) /* we don't shrink for now */
5835 return a;
5836 if( p[-1] == MAGIC_SEC_BYTE )
5837 b = FNAME(alloc_secure_clear)(n FNAMEARG);
5838 else
5839 b = FNAME(alloc_clear)(n FNAMEARG);
5840 FNAME(check)(NULL FNAMEARG);
5841 memcpy(b, a, len );
5842 FNAME(free)(p FNAMEARG);
5843 }
5844 else
5845 b = FNAME(alloc)(n FNAMEARG);
5846 #else
5847 if( m_is_secure(a) ) {
5848 if( !(b = secmexrealloc( a, n )) )
5849 out_of_core(n,1);
5850 }
5851 else {
5852 if( !(b = realloc( a, n )) )
5853 out_of_core(n,0);
5854 }
5855 #endif
5856
5857 return b;
5858 }
5859
5860
5861
5862 /****************
5863 * Free a pointer
5864 */
5865 void
5866 FNAMEX(free)( void *a FNAMEPRT )
5867 {
5868 byte *p = a;
5869
5870 if( !p )
5871 return;
5872 #ifdef M_DEBUG
5873 free_entry(p-EXTRA_ALIGN-4, info);
5874 #elif defined M_GUARD
5875 m_check(p);
5876 if( m_is_secure(a) )
5877 secmem_free(p-EXTRA_ALIGN-4);
5878 else {
5879 used_memory -= m_size(a);
5880 free(p-EXTRA_ALIGN-4);
5881 }
5882 #else
5883 if( m_is_secure(a) )
5884 secmem_free(p);
5885 else
5886 free(p);
5887 #endif
5888 }
5889
5890
5891 void
5892 FNAME(check)( const void *a FNAMEPRT )
5893 {
5894 #ifdef M_GUARD
5895 const byte *p = a;
5896
5897 #ifdef M_DEBUG
5898 if( p )
5899 check_mem(p-EXTRA_ALIGN-4, info);
5900 else
5901 check_allmem(info);
5902 #else
5903 if( !p )
5904 return;
5905 if( !(p[-1] == MAGIC_NOR_BYTE || p[-1] == MAGIC_SEC_BYTE) )
5906 membug("memory at %p corrupted (underflow=%02x)\n", p, p[-1] );
5907 else if( p[m_size(p)] != MAGIC_END_BYTE )
5908 membug("memory at %p corrupted (overflow=%02x)\n", p, p[-1] );
5909 #endif
5910 #endif
5911 }
5912
5913
5914 size_t
5915 m_size( const void *a )
5916 {
5917 #ifndef M_GUARD
5918 log_debug("dummy m_size called\n");
5919 return 0;
5920 #else
5921 const byte *p = a;
5922 size_t n;
5923
5924 #ifdef M_DEBUG
5925 n = check_mem(p-EXTRA_ALIGN-4, "m_size")->user_n;
5926 #else
5927 n = ((byte*)p)[-4];
5928 n |= ((byte*)p)[-3] << 8;
5929 n |= ((byte*)p)[-2] << 16;
5930 #endif
5931 return n;
5932 #endif
5933 }
5934
5935
5936 char *
5937 FNAMEX(strdup)( const char *a FNAMEPRT )
5938 {
5939 size_t n = strlen(a);
5940 char *p = FNAMEXM(alloc)(n+1 FNAMEARG);
5941 strcpy(p, a);
5942 return p;
5943 }
5944
5945 char *
5946 FNAMEX(trystrdup)(const char *a FNAMEPRT)
5947 {
5948 size_t n = strlen (a);
5949 char *p = FNAMEX(trymalloc)(n+1 FNAMEARG);
5950 if (p)
5951 strcpy (p, a);
5952 return p;
5953 }
5954
5955
5956 /* Wrapper around xmalloc_clear to take the usual 2 arguments of a
5957 calloc style function. */
5958 void *
5959 xcalloc (size_t n, size_t m)
5960 {
5961 size_t nbytes;
5962
5963 nbytes = n * m;
5964 if (m && nbytes / m != n)
5965 out_of_core (nbytes, 0);
5966 return xmalloc_clear (nbytes);
5967 }
5968
5969 /* Wrapper around xmalloc_csecure_lear to take the usual 2 arguments
5970 of a calloc style function. */
5971 void *
5972 xcalloc_secure (size_t n, size_t m)
5973 {
5974 size_t nbytes;
5975
5976 nbytes = n * m;
5977 if (m && nbytes / m != n)
5978 out_of_core (nbytes, 1);
5979 return xmalloc_secure_clear (nbytes);
5980 }
5981
-
+ FFCEA4F2389EB4919DF50FC60423606D2835E4BE6A853FA885754CF04C397FE96D4A688ECCD591C60BC687846AE1E230304D3554B3E504E2E53662270342C591
mpi/mpi-add.c
(0 . 0)(1 . 246)
5986 /* mpi-add.c - MPI functions
5987 * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
5988 * Copyright (C) 1994, 1996 Free Software Foundation, Inc.
5989 *
5990 * This file is part of GnuPG.
5991 *
5992 * GnuPG is free software; you can redistribute it and/or modify
5993 * it under the terms of the GNU General Public License as published by
5994 * the Free Software Foundation; either version 3 of the License, or
5995 * (at your option) any later version.
5996 *
5997 * GnuPG is distributed in the hope that it will be useful,
5998 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5999 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6000 * GNU General Public License for more details.
6001 *
6002 * You should have received a copy of the GNU General Public License
6003 * along with this program; if not, see <http://www.gnu.org/licenses/>.
6004 *
6005 * Note: This code is heavily based on the GNU MP Library.
6006 * Actually it's the same code with only minor changes in the
6007 * way the data is stored; this is to support the abstraction
6008 * of an optional secure memory allocation which may be used
6009 * to avoid revealing of sensitive data due to paging etc.
6010 * The GNU MP Library itself is published under the LGPL;
6011 * however I decided to publish this code under the plain GPL.
6012 */
6013
6014 #include <config.h>
6015 #include <stdio.h>
6016 #include <stdlib.h>
6017
6018 #include "mpi-internal.h"
6019
6020
6021 /****************
6022 * Add the unsigned integer V to the mpi-integer U and store the
6023 * result in W. U and V may be the same.
6024 */
6025 void
6026 mpi_add_ui(MPI w, MPI u, unsigned long v )
6027 {
6028 mpi_ptr_t wp, up;
6029 mpi_size_t usize, wsize;
6030 int usign, wsign;
6031
6032 usize = u->nlimbs;
6033 usign = u->sign;
6034 wsign = 0;
6035
6036 /* If not space for W (and possible carry), increase space. */
6037 wsize = usize + 1;
6038 if( w->alloced < wsize )
6039 mpi_resize(w, wsize);
6040
6041 /* These must be after realloc (U may be the same as W). */
6042 up = u->d;
6043 wp = w->d;
6044
6045 if( !usize ) { /* simple */
6046 wp[0] = v;
6047 wsize = v? 1:0;
6048 }
6049 else if( !usign ) { /* mpi is not negative */
6050 mpi_limb_t cy;
6051 cy = mpihelp_add_1(wp, up, usize, v);
6052 wp[usize] = cy;
6053 wsize = usize + cy;
6054 }
6055 else { /* The signs are different. Need exact comparison to determine
6056 * which operand to subtract from which. */
6057 if( usize == 1 && up[0] < v ) {
6058 wp[0] = v - up[0];
6059 wsize = 1;
6060 }
6061 else {
6062 mpihelp_sub_1(wp, up, usize, v);
6063 /* Size can decrease with at most one limb. */
6064 wsize = usize - (wp[usize-1]==0);
6065 wsign = 1;
6066 }
6067 }
6068
6069 w->nlimbs = wsize;
6070 w->sign = wsign;
6071 }
6072
6073
6074 void
6075 mpi_add(MPI w, MPI u, MPI v)
6076 {
6077 mpi_ptr_t wp, up, vp;
6078 mpi_size_t usize, vsize, wsize;
6079 int usign, vsign, wsign;
6080
6081 if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
6082 usize = v->nlimbs;
6083 usign = v->sign;
6084 vsize = u->nlimbs;
6085 vsign = u->sign;
6086 wsize = usize + 1;
6087 RESIZE_IF_NEEDED(w, wsize);
6088 /* These must be after realloc (u or v may be the same as w). */
6089 up = v->d;
6090 vp = u->d;
6091 }
6092 else {
6093 usize = u->nlimbs;
6094 usign = u->sign;
6095 vsize = v->nlimbs;
6096 vsign = v->sign;
6097 wsize = usize + 1;
6098 RESIZE_IF_NEEDED(w, wsize);
6099 /* These must be after realloc (u or v may be the same as w). */
6100 up = u->d;
6101 vp = v->d;
6102 }
6103 wp = w->d;
6104 wsign = 0;
6105
6106 if( !vsize ) { /* simple */
6107 MPN_COPY(wp, up, usize );
6108 wsize = usize;
6109 wsign = usign;
6110 }
6111 else if( usign != vsign ) { /* different sign */
6112 /* This test is right since USIZE >= VSIZE */
6113 if( usize != vsize ) {
6114 mpihelp_sub(wp, up, usize, vp, vsize);
6115 wsize = usize;
6116 MPN_NORMALIZE(wp, wsize);
6117 wsign = usign;
6118 }
6119 else if( mpihelp_cmp(up, vp, usize) < 0 ) {
6120 mpihelp_sub_n(wp, vp, up, usize);
6121 wsize = usize;
6122 MPN_NORMALIZE(wp, wsize);
6123 if( !usign )
6124 wsign = 1;
6125 }
6126 else {
6127 mpihelp_sub_n(wp, up, vp, usize);
6128 wsize = usize;
6129 MPN_NORMALIZE(wp, wsize);
6130 if( usign )
6131 wsign = 1;
6132 }
6133 }
6134 else { /* U and V have same sign. Add them. */
6135 mpi_limb_t cy = mpihelp_add(wp, up, usize, vp, vsize);
6136 wp[usize] = cy;
6137 wsize = usize + cy;
6138 if( usign )
6139 wsign = 1;
6140 }
6141
6142 w->nlimbs = wsize;
6143 w->sign = wsign;
6144 }
6145
6146
6147 /****************
6148 * Subtract the unsigned integer V from the mpi-integer U and store the
6149 * result in W.
6150 */
6151 void
6152 mpi_sub_ui(MPI w, MPI u, unsigned long v )
6153 {
6154 mpi_ptr_t wp, up;
6155 mpi_size_t usize, wsize;
6156 int usign, wsign;
6157
6158 usize = u->nlimbs;
6159 usign = u->sign;
6160 wsign = 0;
6161
6162 /* If not space for W (and possible carry), increase space. */
6163 wsize = usize + 1;
6164 if( w->alloced < wsize )
6165 mpi_resize(w, wsize);
6166
6167 /* These must be after realloc (U may be the same as W). */
6168 up = u->d;
6169 wp = w->d;
6170
6171 if( !usize ) { /* simple */
6172 wp[0] = v;
6173 wsize = v? 1:0;
6174 wsign = 1;
6175 }
6176 else if( usign ) { /* mpi and v are negative */
6177 mpi_limb_t cy;
6178 cy = mpihelp_add_1(wp, up, usize, v);
6179 wp[usize] = cy;
6180 wsize = usize + cy;
6181 }
6182 else { /* The signs are different. Need exact comparison to determine
6183 * which operand to subtract from which. */
6184 if( usize == 1 && up[0] < v ) {
6185 wp[0] = v - up[0];
6186 wsize = 1;
6187 wsign = 1;
6188 }
6189 else {
6190 mpihelp_sub_1(wp, up, usize, v);
6191 /* Size can decrease with at most one limb. */
6192 wsize = usize - (wp[usize-1]==0);
6193 }
6194 }
6195
6196 w->nlimbs = wsize;
6197 w->sign = wsign;
6198 }
6199
6200 void
6201 mpi_sub(MPI w, MPI u, MPI v)
6202 {
6203 if( w == v ) {
6204 MPI vv = mpi_copy(v);
6205 vv->sign = !vv->sign;
6206 mpi_add( w, u, vv );
6207 mpi_free(vv);
6208 }
6209 else {
6210 /* fixme: this is not thread-save (we temp. modify v) */
6211 v->sign = !v->sign;
6212 mpi_add( w, u, v );
6213 v->sign = !v->sign;
6214 }
6215 }
6216
6217
6218 void
6219 mpi_addm( MPI w, MPI u, MPI v, MPI m)
6220 {
6221 mpi_add(w, u, v);
6222 mpi_fdiv_r( w, w, m );
6223 }
6224
6225 void
6226 mpi_subm( MPI w, MPI u, MPI v, MPI m)
6227 {
6228 mpi_sub(w, u, v);
6229 mpi_fdiv_r( w, w, m );
6230 }
6231
-
+ A48F6DCD95712D600A89EFAE6DC7425B5CADE2869B48AA49D6D6FC5C42D63EC462E2A1FCB08CB1DF5468A9A5AD8C8DD419DC7FB8F5758AD0D93007960B19A153
mpi/mpi-bit.c
(0 . 0)(1 . 254)
6236 /* mpi-bit.c - MPI bit level fucntions
6237 * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
6238 *
6239 * This file is part of GnuPG.
6240 *
6241 * GnuPG is free software; you can redistribute it and/or modify
6242 * it under the terms of the GNU General Public License as published by
6243 * the Free Software Foundation; either version 3 of the License, or
6244 * (at your option) any later version.
6245 *
6246 * GnuPG is distributed in the hope that it will be useful,
6247 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6248 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6249 * GNU General Public License for more details.
6250 *
6251 * You should have received a copy of the GNU General Public License
6252 * along with this program; if not, see <http://www.gnu.org/licenses/>.
6253 */
6254
6255 #include <config.h>
6256 #include <stdio.h>
6257 #include <stdlib.h>
6258 #include <assert.h>
6259 #include "mpi-internal.h"
6260 #include "longlong.h"
6261
6262
6263 #ifdef MPI_INTERNAL_NEED_CLZ_TAB
6264 #ifdef __STDC__
6265 const
6266 #endif
6267 unsigned char
6268 __clz_tab[] =
6269 {
6270 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6271 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
6272 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
6273 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
6274 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
6275 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
6276 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
6277 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
6278 };
6279 #endif
6280
6281
6282 #define A_LIMB_1 ((mpi_limb_t)1)
6283
6284
6285 /****************
6286 * Sometimes we have MSL (most significant limbs) which are 0;
6287 * this is for some reasons not good, so this function removes them.
6288 */
6289 void
6290 mpi_normalize( MPI a )
6291 {
6292 if( mpi_is_opaque (a) )
6293 return;
6294
6295 for( ; a->nlimbs && !a->d[a->nlimbs-1]; a->nlimbs-- )
6296 ;
6297 }
6298
6299
6300
6301 /****************
6302 * Return the number of bits in A.
6303 */
6304 unsigned
6305 mpi_get_nbits( MPI a )
6306 {
6307 unsigned n;
6308
6309 mpi_normalize( a );
6310 if( a->nlimbs ) {
6311 mpi_limb_t alimb = a->d[a->nlimbs-1];
6312 if( alimb )
6313 count_leading_zeros( n, alimb );
6314 else
6315 n = BITS_PER_MPI_LIMB;
6316 n = BITS_PER_MPI_LIMB - n + (a->nlimbs-1) * BITS_PER_MPI_LIMB;
6317 }
6318 else
6319 n = 0;
6320 return n;
6321 }
6322
6323
6324 /****************
6325 * Test whether bit N is set.
6326 */
6327 int
6328 mpi_test_bit( MPI a, unsigned n )
6329 {
6330 unsigned limbno, bitno;
6331 mpi_limb_t limb;
6332
6333 limbno = n / BITS_PER_MPI_LIMB;
6334 bitno = n % BITS_PER_MPI_LIMB;
6335
6336 if( limbno >= a->nlimbs )
6337 return 0; /* too far left: this is a 0 */
6338 limb = a->d[limbno];
6339 return (limb & (A_LIMB_1 << bitno))? 1: 0;
6340 }
6341
6342
6343 /****************
6344 * Set bit N of A.
6345 */
6346 void
6347 mpi_set_bit( MPI a, unsigned n )
6348 {
6349 unsigned limbno, bitno;
6350
6351 limbno = n / BITS_PER_MPI_LIMB;
6352 bitno = n % BITS_PER_MPI_LIMB;
6353
6354 if( limbno >= a->nlimbs ) { /* resize */
6355 if( a->alloced >= limbno )
6356 mpi_resize(a, limbno+1 );
6357 a->nlimbs = limbno+1;
6358 }
6359 a->d[limbno] |= (A_LIMB_1<<bitno);
6360 }
6361
6362 /****************
6363 * Set bit N of A. and clear all bits above
6364 */
6365 void
6366 mpi_set_highbit( MPI a, unsigned n )
6367 {
6368 unsigned limbno, bitno;
6369
6370 limbno = n / BITS_PER_MPI_LIMB;
6371 bitno = n % BITS_PER_MPI_LIMB;
6372
6373 if( limbno >= a->nlimbs ) { /* resize */
6374 if( a->alloced >= limbno )
6375 mpi_resize(a, limbno+1 );
6376 a->nlimbs = limbno+1;
6377 }
6378 a->d[limbno] |= (A_LIMB_1<<bitno);
6379 for( bitno++; bitno < BITS_PER_MPI_LIMB; bitno++ )
6380 a->d[limbno] &= ~(A_LIMB_1 << bitno);
6381 a->nlimbs = limbno+1;
6382 }
6383
6384 /****************
6385 * clear bit N of A and all bits above
6386 */
6387 void
6388 mpi_clear_highbit( MPI a, unsigned n )
6389 {
6390 unsigned limbno, bitno;
6391
6392 limbno = n / BITS_PER_MPI_LIMB;
6393 bitno = n % BITS_PER_MPI_LIMB;
6394
6395 if( limbno >= a->nlimbs )
6396 return; /* not allocated, so need to clear bits :-) */
6397
6398 for( ; bitno < BITS_PER_MPI_LIMB; bitno++ )
6399 a->d[limbno] &= ~(A_LIMB_1 << bitno);
6400 a->nlimbs = limbno+1;
6401 }
6402
6403 /****************
6404 * Clear bit N of A.
6405 */
6406 void
6407 mpi_clear_bit( MPI a, unsigned n )
6408 {
6409 unsigned limbno, bitno;
6410
6411 limbno = n / BITS_PER_MPI_LIMB;
6412 bitno = n % BITS_PER_MPI_LIMB;
6413
6414 if( limbno >= a->nlimbs )
6415 return; /* don't need to clear this bit, it's to far to left */
6416 a->d[limbno] &= ~(A_LIMB_1 << bitno);
6417 }
6418
6419
6420 /****************
6421 * Shift A by N bits to the right
6422 * FIXME: should use alloc_limb if X and A are same.
6423 */
6424 void
6425 mpi_rshift( MPI x, MPI a, unsigned n )
6426 {
6427 mpi_ptr_t xp;
6428 mpi_size_t xsize;
6429
6430 xsize = a->nlimbs;
6431 x->sign = a->sign;
6432 RESIZE_IF_NEEDED(x, xsize);
6433 xp = x->d;
6434
6435 if( xsize ) {
6436 mpihelp_rshift( xp, a->d, xsize, n);
6437 MPN_NORMALIZE( xp, xsize);
6438 }
6439 x->nlimbs = xsize;
6440 }
6441
6442
6443 /****************
6444 * Shift A by COUNT limbs to the left
6445 * This is used only within the MPI library
6446 */
6447 void
6448 mpi_lshift_limbs( MPI a, unsigned int count )
6449 {
6450 mpi_ptr_t ap = a->d;
6451 int n = a->nlimbs;
6452 int i;
6453
6454 if( !count || !n )
6455 return;
6456
6457 RESIZE_IF_NEEDED( a, n+count );
6458
6459 for( i = n-1; i >= 0; i-- )
6460 ap[i+count] = ap[i];
6461 for(i=0; i < count; i++ )
6462 ap[i] = 0;
6463 a->nlimbs += count;
6464 }
6465
6466
6467 /****************
6468 * Shift A by COUNT limbs to the right
6469 * This is used only within the MPI library
6470 */
6471 void
6472 mpi_rshift_limbs( MPI a, unsigned int count )
6473 {
6474 mpi_ptr_t ap = a->d;
6475 mpi_size_t n = a->nlimbs;
6476 unsigned int i;
6477
6478 if( count >= n ) {
6479 a->nlimbs = 0;
6480 return;
6481 }
6482
6483 for( i = 0; i < n - count; i++ )
6484 ap[i] = ap[i+count];
6485 ap[i] = 0;
6486 a->nlimbs -= count;
6487 }
6488
6489
-
+ 83C978461CA2FC606EAB05035DB9A67D600396F013E5CE0DB8CC110D8881E9BE513D540B27DAECC8B0293178D7AB27EE52F5C947A0B9976863B9094F82EBD522
mpi/mpi-cmp.c
(0 . 0)(1 . 73)
6494 /* mpi-cmp.c - MPI functions
6495 * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
6496 *
6497 * This file is part of GnuPG.
6498 *
6499 * GnuPG is free software; you can redistribute it and/or modify
6500 * it under the terms of the GNU General Public License as published by
6501 * the Free Software Foundation; either version 3 of the License, or
6502 * (at your option) any later version.
6503 *
6504 * GnuPG is distributed in the hope that it will be useful,
6505 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6506 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6507 * GNU General Public License for more details.
6508 *
6509 * You should have received a copy of the GNU General Public License
6510 * along with this program; if not, see <http://www.gnu.org/licenses/>.
6511 */
6512
6513 #include <config.h>
6514 #include <stdio.h>
6515 #include <stdlib.h>
6516 #include "mpi-internal.h"
6517
6518 int
6519 mpi_cmp_ui( MPI u, unsigned long v )
6520 {
6521 mpi_limb_t limb = v;
6522
6523 mpi_normalize( u );
6524 if( !u->nlimbs && !limb )
6525 return 0;
6526 if( u->sign )
6527 return -1;
6528 if( u->nlimbs > 1 )
6529 return 1;
6530
6531 if( u->d[0] == limb )
6532 return 0;
6533 else if( u->d[0] > limb )
6534 return 1;
6535 else
6536 return -1;
6537 }
6538
6539 int
6540 mpi_cmp( MPI u, MPI v )
6541 {
6542 mpi_size_t usize, vsize;
6543 int cmp;
6544
6545 mpi_normalize( u );
6546 mpi_normalize( v );
6547 usize = u->nlimbs;
6548 vsize = v->nlimbs;
6549 if( !u->sign && v->sign )
6550 return 1;
6551 if( u->sign && !v->sign )
6552 return -1;
6553 if( usize != vsize && !u->sign && !v->sign )
6554 return usize - vsize;
6555 if( usize != vsize && u->sign && v->sign )
6556 return vsize + usize;
6557 if( !usize )
6558 return 0;
6559 if( !(cmp=mpihelp_cmp( u->d, v->d, usize )) )
6560 return 0;
6561 if( (cmp < 0?1:0) == (u->sign?1:0))
6562 return 1;
6563 return -1;
6564 }
6565
6566
-
+ 6A4860EA723098A2E2BA703D8748F6D26C22D1AE72647A5CCCA67AB93976390B0D992BA870796BE3DA3B736B1A11B36F700A93214AE5926EC2652D1EDEE390A3
mpi/mpicoder.c
(0 . 0)(1 . 472)
6571 /* mpicoder.c - Coder for the external representation of MPIs
6572 * Copyright (C) 1998, 1999, 2005 Free Software Foundation, Inc.
6573 *
6574 * This file is part of GnuPG.
6575 *
6576 * GnuPG is free software; you can redistribute it and/or modify
6577 * it under the terms of the GNU General Public License as published by
6578 * the Free Software Foundation; either version 3 of the License, or
6579 * (at your option) any later version.
6580 *
6581 * GnuPG is distributed in the hope that it will be useful,
6582 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6583 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6584 * GNU General Public License for more details.
6585 *
6586 * You should have received a copy of the GNU General Public License
6587 * along with this program; if not, see <http://www.gnu.org/licenses/>.
6588 */
6589
6590 #include <config.h>
6591 #include <stdio.h>
6592 #include <string.h>
6593 #include <stdlib.h>
6594 #include <assert.h>
6595
6596 #include "mpi.h"
6597 #include "mpi-internal.h"
6598 #include "iobuf.h"
6599 #include "memory.h"
6600 #include "util.h"
6601
6602 #ifdef M_DEBUG
6603 #undef mpi_read
6604 #endif
6605
6606 #define MAX_EXTERN_MPI_BITS 16384
6607
6608 /****************
6609 * write an mpi to out.
6610 */
6611 int
6612 mpi_write( IOBUF out, MPI a )
6613 {
6614 int rc;
6615 unsigned nbits = mpi_get_nbits(a);
6616 byte *p, *buf;
6617 unsigned n;
6618
6619 if( nbits > MAX_EXTERN_MPI_BITS )
6620 log_bug("mpi_encode: mpi too large (%u bits)\n", nbits);
6621
6622 iobuf_put(out, (nbits >>8) );
6623 iobuf_put(out, (nbits) );
6624
6625 p = buf = mpi_get_buffer( a, &n, NULL );
6626 rc = iobuf_write( out, p, n );
6627 xfree(buf);
6628 return rc;
6629 }
6630
6631
6632 /****************
6633 * Read an external representation of an mpi and return the MPI
6634 * The external format is a 16 bit unsigned value stored in network byte order,
6635 * giving the number of bits for the following integer. The integer is stored
6636 * with MSB first (left padded with zeroes to align on a byte boundary).
6637 */
6638 MPI
6639 #ifdef M_DEBUG
6640 mpi_debug_read(IOBUF inp, unsigned *ret_nread, int secure, const char *info)
6641 #else
6642 mpi_read(IOBUF inp, unsigned *ret_nread, int secure)
6643 #endif
6644 {
6645 int c, i, j;
6646 unsigned int nmax = *ret_nread;
6647 unsigned nbits, nbytes, nlimbs, nread=0;
6648 mpi_limb_t a;
6649 MPI val = NULL;
6650
6651 if (nread == nmax)
6652 goto overflow;
6653 if( (c = iobuf_get(inp)) == -1 )
6654 goto leave;
6655 nread++;
6656 nbits = c << 8;
6657
6658 if (nread == nmax)
6659 goto overflow;
6660 if( (c = iobuf_get(inp)) == -1 )
6661 goto leave;
6662 nread++;
6663 nbits |= c;
6664
6665 if( nbits > MAX_EXTERN_MPI_BITS ) {
6666 log_error("mpi too large for this implementation (%u bits)\n", nbits);
6667 goto leave;
6668 }
6669
6670 nbytes = (nbits+7) / 8;
6671 nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
6672 #ifdef M_DEBUG
6673 val = secure? mpi_debug_alloc_secure( nlimbs, info )
6674 : mpi_debug_alloc( nlimbs, info );
6675 #else
6676 val = secure? mpi_alloc_secure( nlimbs )
6677 : mpi_alloc( nlimbs );
6678 #endif
6679 i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
6680 i %= BYTES_PER_MPI_LIMB;
6681 val->nbits = nbits;
6682 j= val->nlimbs = nlimbs;
6683 val->sign = 0;
6684 for( ; j > 0; j-- ) {
6685 a = 0;
6686 for(; i < BYTES_PER_MPI_LIMB; i++ ) {
6687 if (nread == nmax) {
6688 #ifdef M_DEBUG
6689 mpi_debug_free (val);
6690 #else
6691 mpi_free (val);
6692 #endif
6693 val = NULL;
6694 goto overflow;
6695 }
6696 a <<= 8;
6697 a |= iobuf_get(inp) & 0xff; nread++;
6698 }
6699 i = 0;
6700 val->d[j-1] = a;
6701 }
6702
6703 leave:
6704 *ret_nread = nread;
6705 return val;
6706 overflow:
6707 log_error ("mpi larger than indicated length (%u bytes)\n", nmax);
6708 *ret_nread = nread;
6709 return val;
6710 }
6711
6712
6713 MPI
6714 mpi_read_from_buffer(byte *buffer, unsigned int *ret_nread, int secure)
6715 {
6716 int i, j;
6717 unsigned nbits, nbytes, nlimbs, nread=0;
6718 mpi_limb_t a;
6719 MPI val = NULL;
6720
6721 if( *ret_nread < 2 )
6722 goto leave;
6723 nbits = buffer[0] << 8 | buffer[1];
6724 if( nbits > MAX_EXTERN_MPI_BITS ) {
6725 log_info ("mpi too large (%u bits)\n", nbits);
6726 goto leave;
6727 }
6728 buffer += 2;
6729 nread = 2;
6730
6731 nbytes = (nbits+7) / 8;
6732 nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
6733 val = secure? mpi_alloc_secure( nlimbs )
6734 : mpi_alloc( nlimbs );
6735 i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
6736 i %= BYTES_PER_MPI_LIMB;
6737 val->nbits = nbits;
6738 j= val->nlimbs = nlimbs;
6739 val->sign = 0;
6740 for( ; j > 0; j-- ) {
6741 a = 0;
6742 for(; i < BYTES_PER_MPI_LIMB; i++ ) {
6743 if( ++nread > *ret_nread ) {
6744 /* This (as well as the above error condition) may
6745 happen if we use this function to parse a decrypted
6746 MPI which didn't turn out to be a real MPI - possible
6747 because the supplied key was wrong but the OpenPGP
6748 checksum didn't caught it. */
6749 log_info ("mpi larger than buffer\n");
6750 mpi_free (val);
6751 val = NULL;
6752 goto leave;
6753 }
6754 a <<= 8;
6755 a |= *buffer++;
6756 }
6757 i = 0;
6758 val->d[j-1] = a;
6759 }
6760
6761 leave:
6762 *ret_nread = nread;
6763 return val;
6764 }
6765
6766
6767 /****************
6768 * Make an mpi from a character string.
6769 */
6770 int
6771 mpi_fromstr(MPI val, const char *str)
6772 {
6773 int hexmode=0, sign=0, prepend_zero=0, i, j, c, c1, c2;
6774 unsigned nbits, nbytes, nlimbs;
6775 mpi_limb_t a;
6776
6777 if( *str == '-' ) {
6778 sign = 1;
6779 str++;
6780 }
6781 if( *str == '0' && str[1] == 'x' )
6782 hexmode = 1;
6783 else
6784 return 1; /* other bases are not yet supported */
6785 str += 2;
6786
6787 nbits = strlen(str)*4;
6788 if( nbits % 8 )
6789 prepend_zero = 1;
6790 nbytes = (nbits+7) / 8;
6791 nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
6792 if( val->alloced < nlimbs )
6793 mpi_resize(val, nlimbs );
6794 i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
6795 i %= BYTES_PER_MPI_LIMB;
6796 j= val->nlimbs = nlimbs;
6797 val->sign = sign;
6798 for( ; j > 0; j-- ) {
6799 a = 0;
6800 for(; i < BYTES_PER_MPI_LIMB; i++ ) {
6801 if( prepend_zero ) {
6802 c1 = '0';
6803 prepend_zero = 0;
6804 }
6805 else
6806 c1 = *str++;
6807 assert(c1);
6808 c2 = *str++;
6809 assert(c2);
6810 if( c1 >= '0' && c1 <= '9' )
6811 c = c1 - '0';
6812 else if( c1 >= 'a' && c1 <= 'f' )
6813 c = c1 - 'a' + 10;
6814 else if( c1 >= 'A' && c1 <= 'F' )
6815 c = c1 - 'A' + 10;
6816 else {
6817 mpi_clear(val);
6818 return 1;
6819 }
6820 c <<= 4;
6821 if( c2 >= '0' && c2 <= '9' )
6822 c |= c2 - '0';
6823 else if( c2 >= 'a' && c2 <= 'f' )
6824 c |= c2 - 'a' + 10;
6825 else if( c2 >= 'A' && c2 <= 'F' )
6826 c |= c2 - 'A' + 10;
6827 else {
6828 mpi_clear(val);
6829 return 1;
6830 }
6831 a <<= 8;
6832 a |= c;
6833 }
6834 i = 0;
6835 val->d[j-1] = a;
6836 }
6837
6838 return 0;
6839 }
6840
6841
6842 /****************
6843 * print an MPI to the given stream and return the number of characters
6844 * printed.
6845 */
6846 int
6847 mpi_print( FILE *fp, MPI a, int mode )
6848 {
6849 int i, n=0;
6850
6851 if( a == NULL )
6852 return fprintf(fp, "[MPI_NULL]");
6853 if( !mode ) {
6854 unsigned int n1;
6855
6856 n1 = mpi_get_nbits(a);
6857 n += fprintf(fp, "[%u bits]", n1);
6858 }
6859 else {
6860 if( a->sign )
6861 putc('-', fp);
6862 #if BYTES_PER_MPI_LIMB == 2
6863 #define X "4"
6864 #elif BYTES_PER_MPI_LIMB == 4
6865 #define X "8"
6866 #elif BYTES_PER_MPI_LIMB == 8
6867 #define X "16"
6868 #else
6869 #error please define the format here
6870 #endif
6871 for(i=a->nlimbs; i > 0 ; i-- ) {
6872 n += fprintf(fp, i!=a->nlimbs? "%0" X "lX":"%lX", (ulong)a->d[i-1]);
6873 #undef X
6874 }
6875 if( !a->nlimbs )
6876 putc('0', fp );
6877 }
6878 return n;
6879 }
6880
6881
6882 void
6883 g10_log_mpidump( const char *text, MPI a )
6884 {
6885 FILE *fp = log_stream();
6886
6887 g10_log_print_prefix(text);
6888 mpi_print(fp, a, 1 );
6889 fputc('\n', fp);
6890 }
6891
6892 /****************
6893 * Special function to get the low 8 bytes from an mpi.
6894 * This can be used as a keyid; KEYID is an 2 element array.
6895 * Return the low 4 bytes.
6896 */
6897 u32
6898 mpi_get_keyid( MPI a, u32 *keyid )
6899 {
6900 #if BYTES_PER_MPI_LIMB == 4
6901 if( keyid ) {
6902 keyid[0] = a->nlimbs >= 2? a->d[1] : 0;
6903 keyid[1] = a->nlimbs >= 1? a->d[0] : 0;
6904 }
6905 return a->nlimbs >= 1? a->d[0] : 0;
6906 #elif BYTES_PER_MPI_LIMB == 8
6907 if( keyid ) {
6908 keyid[0] = a->nlimbs? (u32)(a->d[0] >> 32) : 0;
6909 keyid[1] = a->nlimbs? (u32)(a->d[0] & 0xffffffff) : 0;
6910 }
6911 return a->nlimbs? (u32)(a->d[0] & 0xffffffff) : 0;
6912 #else
6913 #error Make this function work with other LIMB sizes
6914 #endif
6915 }
6916
6917
6918 /****************
6919 * Return an xmalloced buffer with the MPI (msb first).
6920 * NBYTES receives the length of this buffer. Caller must free the
6921 * return string (This function does return a 0 byte buffer with NBYTES
6922 * set to zero if the value of A is zero. If sign is not NULL, it will
6923 * be set to the sign of the A.
6924 */
6925 static byte *
6926 do_get_buffer( MPI a, unsigned *nbytes, int *sign, int force_secure )
6927 {
6928 byte *p, *buffer;
6929 mpi_limb_t alimb;
6930 int i;
6931 unsigned int n;
6932
6933 if( sign )
6934 *sign = a->sign;
6935 *nbytes = n = a->nlimbs * BYTES_PER_MPI_LIMB;
6936 if (!n)
6937 n++; /* avoid zero length allocation */
6938 p = buffer = force_secure || mpi_is_secure(a) ? xmalloc_secure(n)
6939 : xmalloc(n);
6940
6941 for(i=a->nlimbs-1; i >= 0; i-- ) {
6942 alimb = a->d[i];
6943 #if BYTES_PER_MPI_LIMB == 4
6944 *p++ = alimb >> 24;
6945 *p++ = alimb >> 16;
6946 *p++ = alimb >> 8;
6947 *p++ = alimb ;
6948 #elif BYTES_PER_MPI_LIMB == 8
6949 *p++ = alimb >> 56;
6950 *p++ = alimb >> 48;
6951 *p++ = alimb >> 40;
6952 *p++ = alimb >> 32;
6953 *p++ = alimb >> 24;
6954 *p++ = alimb >> 16;
6955 *p++ = alimb >> 8;
6956 *p++ = alimb ;
6957 #else
6958 #error please implement for this limb size.
6959 #endif
6960 }
6961
6962 /* this is sub-optimal but we need to do the shift operation
6963 * because the caller has to free the returned buffer */
6964 for(p=buffer; !*p && *nbytes; p++, --*nbytes )
6965 ;
6966 if( p != buffer )
6967 memmove(buffer,p, *nbytes);
6968
6969 return buffer;
6970 }
6971
6972
6973 byte *
6974 mpi_get_buffer( MPI a, unsigned *nbytes, int *sign )
6975 {
6976 return do_get_buffer( a, nbytes, sign, 0 );
6977 }
6978
6979 byte *
6980 mpi_get_secure_buffer( MPI a, unsigned *nbytes, int *sign )
6981 {
6982 return do_get_buffer( a, nbytes, sign, 1 );
6983 }
6984
6985 /****************
6986 * Use BUFFER to update MPI.
6987 */
6988 void
6989 mpi_set_buffer( MPI a, const byte *buffer, unsigned nbytes, int sign )
6990 {
6991 const byte *p;
6992 mpi_limb_t alimb;
6993 int nlimbs;
6994 int i;
6995
6996 nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
6997 RESIZE_IF_NEEDED(a, nlimbs);
6998 a->sign = sign;
6999
7000 for(i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; ) {
7001 #if BYTES_PER_MPI_LIMB == 4
7002 alimb = (mpi_limb_t)*p-- ;
7003 alimb |= (mpi_limb_t)*p-- << 8 ;
7004 alimb |= (mpi_limb_t)*p-- << 16 ;
7005 alimb |= (mpi_limb_t)*p-- << 24 ;
7006 #elif BYTES_PER_MPI_LIMB == 8
7007 alimb = (mpi_limb_t)*p-- ;
7008 alimb |= (mpi_limb_t)*p-- << 8 ;
7009 alimb |= (mpi_limb_t)*p-- << 16 ;
7010 alimb |= (mpi_limb_t)*p-- << 24 ;
7011 alimb |= (mpi_limb_t)*p-- << 32 ;
7012 alimb |= (mpi_limb_t)*p-- << 40 ;
7013 alimb |= (mpi_limb_t)*p-- << 48 ;
7014 alimb |= (mpi_limb_t)*p-- << 56 ;
7015 #else
7016 #error please implement for this limb size.
7017 #endif
7018 a->d[i++] = alimb;
7019 }
7020 if( p >= buffer ) {
7021 #if BYTES_PER_MPI_LIMB == 4
7022 alimb = *p-- ;
7023 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 8 ;
7024 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 16 ;
7025 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 24 ;
7026 #elif BYTES_PER_MPI_LIMB == 8
7027 alimb = (mpi_limb_t)*p-- ;
7028 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 8 ;
7029 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 16 ;
7030 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 24 ;
7031 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 32 ;
7032 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 40 ;
7033 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 48 ;
7034 if( p >= buffer ) alimb |= (mpi_limb_t)*p-- << 56 ;
7035 #else
7036 #error please implement for this limb size.
7037 #endif
7038 a->d[i++] = alimb;
7039 }
7040 a->nlimbs = i;
7041 assert( i == nlimbs );
7042 }
-
+ B320709B57B3CF0C00BC98277B037494C62FED93FD99BCA0412EA633F8662844D35ED62990CBE1FC02A47DEE5795D3A7B6B401440F6E80A8A00243868815C06A
mpi/mpi-div.c
(0 . 0)(1 . 321)
7047 /* mpi-div.c - MPI functions
7048 * Copyright (C) 1994, 1996 Free Software Foundation, Inc.
7049 * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
7050 *
7051 * This file is part of GnuPG.
7052 *
7053 * GnuPG is free software; you can redistribute it and/or modify
7054 * it under the terms of the GNU General Public License as published by
7055 * the Free Software Foundation; either version 3 of the License, or
7056 * (at your option) any later version.
7057 *
7058 * GnuPG is distributed in the hope that it will be useful,
7059 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7060 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7061 * GNU General Public License for more details.
7062 *
7063 * You should have received a copy of the GNU General Public License
7064 * along with this program; if not, see <http://www.gnu.org/licenses/>.
7065 *
7066 * Note: This code is heavily based on the GNU MP Library.
7067 * Actually it's the same code with only minor changes in the
7068 * way the data is stored; this is to support the abstraction
7069 * of an optional secure memory allocation which may be used
7070 * to avoid revealing of sensitive data due to paging etc.
7071 * The GNU MP Library itself is published under the LGPL;
7072 * however I decided to publish this code under the plain GPL.
7073 */
7074
7075 #include <config.h>
7076 #include <stdio.h>
7077 #include <stdlib.h>
7078 #include "mpi-internal.h"
7079 #include "longlong.h"
7080
7081
7082
7083 void
7084 mpi_fdiv_r( MPI rem, MPI dividend, MPI divisor )
7085 {
7086 int divisor_sign = divisor->sign;
7087 MPI temp_divisor = NULL;
7088
7089 /* We need the original value of the divisor after the remainder has been
7090 * preliminary calculated. We have to copy it to temporary space if it's
7091 * the same variable as REM. */
7092 if( rem == divisor ) {
7093 temp_divisor = mpi_copy( divisor );
7094 divisor = temp_divisor;
7095 }
7096
7097 mpi_tdiv_r( rem, dividend, divisor );
7098
7099 if( ((divisor_sign?1:0) ^ (dividend->sign?1:0)) && rem->nlimbs )
7100 mpi_add( rem, rem, divisor);
7101
7102 if( temp_divisor )
7103 mpi_free(temp_divisor);
7104 }
7105
7106
7107
7108 /****************
7109 * Division rounding the quotient towards -infinity.
7110 * The remainder gets the same sign as the denominator.
7111 * rem is optional
7112 */
7113
7114 ulong
7115 mpi_fdiv_r_ui( MPI rem, MPI dividend, ulong divisor )
7116 {
7117 mpi_limb_t rlimb;
7118
7119 rlimb = mpihelp_mod_1( dividend->d, dividend->nlimbs, divisor );
7120 if( rlimb && dividend->sign )
7121 rlimb = divisor - rlimb;
7122
7123 if( rem ) {
7124 rem->d[0] = rlimb;
7125 rem->nlimbs = rlimb? 1:0;
7126 }
7127 return rlimb;
7128 }
7129
7130
7131 void
7132 mpi_fdiv_q( MPI quot, MPI dividend, MPI divisor )
7133 {
7134 MPI tmp = mpi_alloc( mpi_get_nlimbs(quot) );
7135 mpi_fdiv_qr( quot, tmp, dividend, divisor);
7136 mpi_free(tmp);
7137 }
7138
7139 void
7140 mpi_fdiv_qr( MPI quot, MPI rem, MPI dividend, MPI divisor )
7141 {
7142 int divisor_sign = divisor->sign;
7143 MPI temp_divisor = NULL;
7144
7145 if( quot == divisor || rem == divisor ) {
7146 temp_divisor = mpi_copy( divisor );
7147 divisor = temp_divisor;
7148 }
7149
7150 mpi_tdiv_qr( quot, rem, dividend, divisor );
7151
7152 if( (divisor_sign ^ dividend->sign) && rem->nlimbs ) {
7153 mpi_sub_ui( quot, quot, 1 );
7154 mpi_add( rem, rem, divisor);
7155 }
7156
7157 if( temp_divisor )
7158 mpi_free(temp_divisor);
7159 }
7160
7161
7162 /* If den == quot, den needs temporary storage.
7163 * If den == rem, den needs temporary storage.
7164 * If num == quot, num needs temporary storage.
7165 * If den has temporary storage, it can be normalized while being copied,
7166 * i.e no extra storage should be allocated.
7167 */
7168
7169 void
7170 mpi_tdiv_r( MPI rem, MPI num, MPI den)
7171 {
7172 mpi_tdiv_qr(NULL, rem, num, den );
7173 }
7174
7175 void
7176 mpi_tdiv_qr( MPI quot, MPI rem, MPI num, MPI den)
7177 {
7178 mpi_ptr_t np, dp;
7179 mpi_ptr_t qp, rp;
7180 mpi_size_t nsize = num->nlimbs;
7181 mpi_size_t dsize = den->nlimbs;
7182 mpi_size_t qsize, rsize;
7183 mpi_size_t sign_remainder = num->sign;
7184 mpi_size_t sign_quotient = num->sign ^ den->sign;
7185 unsigned normalization_steps;
7186 mpi_limb_t q_limb;
7187 mpi_ptr_t marker[5];
7188 int markidx=0;
7189
7190 /* Ensure space is enough for quotient and remainder.
7191 * We need space for an extra limb in the remainder, because it's
7192 * up-shifted (normalized) below. */
7193 rsize = nsize + 1;
7194 mpi_resize( rem, rsize);
7195
7196 qsize = rsize - dsize; /* qsize cannot be bigger than this. */
7197 if( qsize <= 0 ) {
7198 if( num != rem ) {
7199 rem->nlimbs = num->nlimbs;
7200 rem->sign = num->sign;
7201 MPN_COPY(rem->d, num->d, nsize);
7202 }
7203 if( quot ) {
7204 /* This needs to follow the assignment to rem, in case the
7205 * numerator and quotient are the same. */
7206 quot->nlimbs = 0;
7207 quot->sign = 0;
7208 }
7209 return;
7210 }
7211
7212 if( quot )
7213 mpi_resize( quot, qsize);
7214
7215 /* Read pointers here, when reallocation is finished. */
7216 np = num->d;
7217 dp = den->d;
7218 rp = rem->d;
7219
7220 /* Optimize division by a single-limb divisor. */
7221 if( dsize == 1 ) {
7222 mpi_limb_t rlimb;
7223 if( quot ) {
7224 qp = quot->d;
7225 rlimb = mpihelp_divmod_1( qp, np, nsize, dp[0] );
7226 qsize -= qp[qsize - 1] == 0;
7227 quot->nlimbs = qsize;
7228 quot->sign = sign_quotient;
7229 }
7230 else
7231 rlimb = mpihelp_mod_1( np, nsize, dp[0] );
7232 rp[0] = rlimb;
7233 rsize = rlimb != 0?1:0;
7234 rem->nlimbs = rsize;
7235 rem->sign = sign_remainder;
7236 return;
7237 }
7238
7239
7240 if( quot ) {
7241 qp = quot->d;
7242 /* Make sure QP and NP point to different objects. Otherwise the
7243 * numerator would be gradually overwritten by the quotient limbs. */
7244 if(qp == np) { /* Copy NP object to temporary space. */
7245 np = marker[markidx++] = mpi_alloc_limb_space(nsize,
7246 mpi_is_secure(quot));
7247 MPN_COPY(np, qp, nsize);
7248 }
7249 }
7250 else /* Put quotient at top of remainder. */
7251 qp = rp + dsize;
7252
7253 count_leading_zeros( normalization_steps, dp[dsize - 1] );
7254
7255 /* Normalize the denominator, i.e. make its most significant bit set by
7256 * shifting it NORMALIZATION_STEPS bits to the left. Also shift the
7257 * numerator the same number of steps (to keep the quotient the same!).
7258 */
7259 if( normalization_steps ) {
7260 mpi_ptr_t tp;
7261 mpi_limb_t nlimb;
7262
7263 /* Shift up the denominator setting the most significant bit of
7264 * the most significant word. Use temporary storage not to clobber
7265 * the original contents of the denominator. */
7266 tp = marker[markidx++] = mpi_alloc_limb_space(dsize,mpi_is_secure(den));
7267 mpihelp_lshift( tp, dp, dsize, normalization_steps );
7268 dp = tp;
7269
7270 /* Shift up the numerator, possibly introducing a new most
7271 * significant word. Move the shifted numerator in the remainder
7272 * meanwhile. */
7273 nlimb = mpihelp_lshift(rp, np, nsize, normalization_steps);
7274 if( nlimb ) {
7275 rp[nsize] = nlimb;
7276 rsize = nsize + 1;
7277 }
7278 else
7279 rsize = nsize;
7280 }
7281 else {
7282 /* The denominator is already normalized, as required. Copy it to
7283 * temporary space if it overlaps with the quotient or remainder. */
7284 if( dp == rp || (quot && (dp == qp))) {
7285 mpi_ptr_t tp;
7286
7287 tp = marker[markidx++] = mpi_alloc_limb_space(dsize, mpi_is_secure(den));
7288 MPN_COPY( tp, dp, dsize );
7289 dp = tp;
7290 }
7291
7292 /* Move the numerator to the remainder. */
7293 if( rp != np )
7294 MPN_COPY(rp, np, nsize);
7295
7296 rsize = nsize;
7297 }
7298
7299 q_limb = mpihelp_divrem( qp, 0, rp, rsize, dp, dsize );
7300
7301 if( quot ) {
7302 qsize = rsize - dsize;
7303 if(q_limb) {
7304 qp[qsize] = q_limb;
7305 qsize += 1;
7306 }
7307
7308 quot->nlimbs = qsize;
7309 quot->sign = sign_quotient;
7310 }
7311
7312 rsize = dsize;
7313 MPN_NORMALIZE (rp, rsize);
7314
7315 if( normalization_steps && rsize ) {
7316 mpihelp_rshift(rp, rp, rsize, normalization_steps);
7317 rsize -= rp[rsize - 1] == 0?1:0;
7318 }
7319
7320 rem->nlimbs = rsize;
7321 rem->sign = sign_remainder;
7322 while( markidx )
7323 mpi_free_limb_space(marker[--markidx]);
7324 }
7325
7326 void
7327 mpi_tdiv_q_2exp( MPI w, MPI u, unsigned count )
7328 {
7329 mpi_size_t usize, wsize;
7330 mpi_size_t limb_cnt;
7331
7332 usize = u->nlimbs;
7333 limb_cnt = count / BITS_PER_MPI_LIMB;
7334 wsize = usize - limb_cnt;
7335 if( limb_cnt >= usize )
7336 w->nlimbs = 0;
7337 else {
7338 mpi_ptr_t wp;
7339 mpi_ptr_t up;
7340
7341 RESIZE_IF_NEEDED( w, wsize );
7342 wp = w->d;
7343 up = u->d;
7344
7345 count %= BITS_PER_MPI_LIMB;
7346 if( count ) {
7347 mpihelp_rshift( wp, up + limb_cnt, wsize, count );
7348 wsize -= !wp[wsize - 1];
7349 }
7350 else {
7351 MPN_COPY_INCR( wp, up + limb_cnt, wsize);
7352 }
7353
7354 w->nlimbs = wsize;
7355 }
7356 }
7357
7358 /****************
7359 * Check whether dividend is divisible by divisor
7360 * (note: divisor must fit into a limb)
7361 */
7362 int
7363 mpi_divisible_ui(MPI dividend, ulong divisor )
7364 {
7365 return !mpihelp_mod_1( dividend->d, dividend->nlimbs, divisor );
7366 }
7367
-
+ F582DE56EE9BC1D4CF2EEA35BDABDCD61E0CC93DD186950709E32FC707D2F769669BAFDCFBF2AD074596BA474BF1E7AF5E29EA81CFF2316ACBFCD27A0F93F185
mpi/mpi-gcd.c
(0 . 0)(1 . 53)
7372 /* mpi-gcd.c - MPI functions
7373 * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
7374 *
7375 * This file is part of GnuPG.
7376 *
7377 * GnuPG is free software; you can redistribute it and/or modify
7378 * it under the terms of the GNU General Public License as published by
7379 * the Free Software Foundation; either version 3 of the License, or
7380 * (at your option) any later version.
7381 *
7382 * GnuPG is distributed in the hope that it will be useful,
7383 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7384 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7385 * GNU General Public License for more details.
7386 *
7387 * You should have received a copy of the GNU General Public License
7388 * along with this program; if not, see <http://www.gnu.org/licenses/>.
7389 */
7390
7391 #include <config.h>
7392 #include <stdio.h>
7393 #include <stdlib.h>
7394 #include "mpi-internal.h"
7395
7396 /****************
7397 * Find the greatest common divisor G of A and B.
7398 * Return: true if this 1, false in all other cases
7399 */
7400 int
7401 mpi_gcd( MPI g, MPI xa, MPI xb )
7402 {
7403 MPI a, b;
7404
7405 a = mpi_copy(xa);
7406 b = mpi_copy(xb);
7407
7408 /* TAOCP Vol II, 4.5.2, Algorithm A */
7409 a->sign = 0;
7410 b->sign = 0;
7411 while( mpi_cmp_ui( b, 0 ) ) {
7412 mpi_fdiv_r( g, a, b ); /* g used as temorary variable */
7413 mpi_set(a,b);
7414 mpi_set(b,g);
7415 }
7416 mpi_set(g, a);
7417
7418 mpi_free(a);
7419 mpi_free(b);
7420 return !mpi_cmp_ui( g, 1);
7421 }
7422
7423
7424
-
+ FB06EA790BD2B2C18013B3FB51F05A5C1577F45FDD67644E7745C3373FA26FA90DE8F30FD9221E978BA9676423ED1C4C27C0407F22A50E10F216AE9BBF4AC3F3
mpi/mpih-add1.c
(0 . 0)(1 . 64)
7429 /* mpihelp-add_1.c - MPI helper functions
7430 * Copyright (C) 1994, 1996, 1997, 1998,
7431 * 2000 Free Software Foundation, Inc.
7432 *
7433 * This file is part of GnuPG.
7434 *
7435 * GnuPG is free software; you can redistribute it and/or modify
7436 * it under the terms of the GNU General Public License as published by
7437 * the Free Software Foundation; either version 3 of the License, or
7438 * (at your option) any later version.
7439 *
7440 * GnuPG is distributed in the hope that it will be useful,
7441 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7442 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7443 * GNU General Public License for more details.
7444 *
7445 * You should have received a copy of the GNU General Public License
7446 * along with this program; if not, see <http://www.gnu.org/licenses/>.
7447 *
7448 * Note: This code is heavily based on the GNU MP Library.
7449 * Actually it's the same code with only minor changes in the
7450 * way the data is stored; this is to support the abstraction
7451 * of an optional secure memory allocation which may be used
7452 * to avoid revealing of sensitive data due to paging etc.
7453 * The GNU MP Library itself is published under the LGPL;
7454 * however I decided to publish this code under the plain GPL.
7455 */
7456
7457 #include <config.h>
7458 #include <stdio.h>
7459 #include <stdlib.h>
7460 #include "mpi-internal.h"
7461 #include "longlong.h"
7462
7463 mpi_limb_t
7464 mpihelp_add_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
7465 mpi_ptr_t s2_ptr, mpi_size_t size)
7466 {
7467 mpi_limb_t x, y, cy;
7468 mpi_size_t j;
7469
7470 /* The loop counter and index J goes from -SIZE to -1. This way
7471 the loop becomes faster. */
7472 j = -size;
7473
7474 /* Offset the base pointers to compensate for the negative indices. */
7475 s1_ptr -= j;
7476 s2_ptr -= j;
7477 res_ptr -= j;
7478
7479 cy = 0;
7480 do {
7481 y = s2_ptr[j];
7482 x = s1_ptr[j];
7483 y += cy; /* add previous carry to one addend */
7484 cy = y < cy; /* get out carry from that addition */
7485 y += x; /* add other addend */
7486 cy += y < x; /* get out carry from that add, combine */
7487 res_ptr[j] = y;
7488 } while( ++j );
7489
7490 return cy;
7491 }
7492
-
+ 88A21583524C37A7FEBB2EEDAF38F0942183A201EE8DF8B9E04A8098E892DD88B7F8566E40CC8BF042D5713E2F78886526CC23DE79C61463E7763685F280C37E
mpi/mpih-cmp.c
(0 . 0)(1 . 61)
7497 /* mpihelp-sub.c - MPI helper functions
7498 * Copyright (C) 1994, 1996 Free Software Foundation, Inc.
7499 * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
7500 *
7501 * This file is part of GnuPG.
7502 *
7503 * GnuPG is free software; you can redistribute it and/or modify
7504 * it under the terms of the GNU General Public License as published by
7505 * the Free Software Foundation; either version 3 of the License, or
7506 * (at your option) any later version.
7507 *
7508 * GnuPG is distributed in the hope that it will be useful,
7509 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7510 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7511 * GNU General Public License for more details.
7512 *
7513 * You should have received a copy of the GNU General Public License
7514 * along with this program; if not, see <http://www.gnu.org/licenses/>.
7515 *
7516 * Note: This code is heavily based on the GNU MP Library.
7517 * Actually it's the same code with only minor changes in the
7518 * way the data is stored; this is to support the abstraction
7519 * of an optional secure memory allocation which may be used
7520 * to avoid revealing of sensitive data due to paging etc.
7521 * The GNU MP Library itself is published under the LGPL;
7522 * however I decided to publish this code under the plain GPL.
7523 */
7524
7525 #include <config.h>
7526 #include <stdio.h>
7527 #include <stdlib.h>
7528
7529 #include "mpi-internal.h"
7530
7531 /****************
7532 * Compare OP1_PTR/OP1_SIZE with OP2_PTR/OP2_SIZE.
7533 * There are no restrictions on the relative sizes of
7534 * the two arguments.
7535 * Return 1 if OP1 > OP2, 0 if they are equal, and -1 if OP1 < OP2.
7536 */
7537 int
7538 mpihelp_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size )
7539 {
7540 mpi_size_t i;
7541 mpi_limb_t op1_word, op2_word;
7542
7543 for( i = size - 1; i >= 0 ; i--) {
7544 op1_word = op1_ptr[i];
7545 op2_word = op2_ptr[i];
7546 if( op1_word != op2_word )
7547 goto diff;
7548 }
7549 return 0;
7550
7551 diff:
7552 /* This can *not* be simplified to
7553 * op2_word - op2_word
7554 * since that expression might give signed overflow. */
7555 return (op1_word > op2_word) ? 1 : -1;
7556 }
7557
-
+ AA4E2EFA1E53416AEDF9CBF7A73A00FBDE7A8266F532002DC046B0B995CF49D060496C45C74944EC3F41CF0DD441884FF6230260978FCBF227903EB7213B074A
mpi/mpih-div.c
(0 . 0)(1 . 534)
7562 /* mpihelp-div.c - MPI helper functions
7563 * Copyright (C) 1994, 1996 Free Software Foundation, Inc.
7564 * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
7565 *
7566 * This file is part of GnuPG.
7567 *
7568 * GnuPG is free software; you can redistribute it and/or modify
7569 * it under the terms of the GNU General Public License as published by
7570 * the Free Software Foundation; either version 3 of the License, or
7571 * (at your option) any later version.
7572 *
7573 * GnuPG is distributed in the hope that it will be useful,
7574 * but WITHOUT ANY WARRANTY; without even the implied warranty of
7575 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7576 * GNU General Public License for more details.
7577 *
7578 * You should have received a copy of the GNU General Public License
7579 * along with this program; if not, see <http://www.gnu.org/licenses/>.
7580 *
7581 * Note: This code is heavily based on the GNU MP Library.
7582 * Actually it's the same code with only minor changes in the
7583 * way the data is stored; this is to support the abstraction
7584 * of an optional secure memory allocation which may be used
7585 * to avoid revealing of sensitive data due to paging etc.
7586 * The GNU MP Library itself is published under the LGPL;
7587 * however I decided to publish this code under the plain GPL.
7588 */
7589
7590 #include <config.h>
7591 #include <stdio.h>
7592 #include <stdlib.h>
7593 #include "mpi-internal.h"
7594 #include "longlong.h"
7595
7596 #ifndef UMUL_TIME
7597 #define UMUL_TIME 1
7598 #endif
7599 #ifndef UDIV_TIME
7600 #define UDIV_TIME UMUL_TIME
7601 #endif
7602
7603 /* FIXME: We should be using invert_limb (or invert_normalized_limb)
7604 * here (not udiv_qrnnd).
7605 */
7606
7607 mpi_limb_t
7608 mpihelp_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
7609 mpi_limb_t divisor_limb)
7610 {
7611 mpi_size_t i;
7612 mpi_limb_t n1, n0, r;
7613 int dummy;
7614
7615 /* Botch: Should this be handled at all? Rely on callers? */
7616 if( !dividend_size )
7617 return 0;
7618
7619 /* If multiplication is much faster than division, and the
7620 * dividend is large, pre-invert the divisor, and use
7621 * only multiplications in the inner loop.
7622 *
7623 * This test should be read:
7624 * Does it ever help to use udiv_qrnnd_preinv?
7625 * && Does what we save compensate for the inversion overhead?
7626 */
7627 if( UDIV_TIME > (2 * UMUL_TIME + 6)
7628 && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME ) {
7629 int normalization_steps;
7630
7631 count_leading_zeros( normalization_steps, divisor_limb );
7632 if( normalization_steps ) {
7633 mpi_limb_t divisor_limb_inverted;
7634
7635 divisor_limb <<= normalization_steps;
7636
7637 /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
7638 * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
7639 * most significant bit (with weight 2**N) implicit.
7640 *
7641 * Special case for DIVISOR_LIMB == 100...000.
7642 */
7643 if( !(divisor_limb << 1) )
7644 divisor_limb_inverted = ~(mpi_limb_t)0;
7645 else
7646 udiv_qrnnd(divisor_limb_inverted, dummy,
7647 -divisor_limb, 0, divisor_limb);
7648
7649 n1 = dividend_ptr[dividend_size - 1];
7650 r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
7651
7652 /* Possible optimization:
7653 * if (r == 0
7654 * && divisor_limb > ((n1 << normalization_steps)
7655 * | (dividend_ptr[dividend_size - 2] >> ...)))
7656 * ...one division less...
7657 */
7658 for( i = dividend_size - 2; i >= 0; i--) {
7659 n0 = dividend_ptr[i];
7660 UDIV_QRNND_PREINV(dummy, r, r,
7661 ((n1 << normalization_steps)
7662 | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
7663 divisor_limb, divisor_limb_inverted);
7664 n1 = n0;
7665 }
7666 UDIV_QRNND_PREINV(dummy, r, r,
7667 n1 << normalization_steps,
7668 divisor_limb, divisor_limb_inverted);
7669 return r >> normalization_steps;
7670 }
7671 else {
7672 mpi_limb_t divisor_limb_inverted;
7673
7674 /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
7675 * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
7676 * most significant bit (with weight 2**N) implicit.
7677 *
7678 * Special case for DIVISOR_LIMB == 100...000.
7679 */
7680 if( !(divisor_limb << 1) )
7681 divisor_limb_inverted = ~(mpi_limb_t)0;
7682 else
7683 udiv_qrnnd(divisor_limb_inverted, dummy,
7684 -divisor_limb, 0, divisor_limb);
7685
7686 i = dividend_size - 1;
7687 r = dividend_ptr[i];
7688
7689 if( r >= divisor_limb )
7690 r = 0;
7691 else
7692 i--;
7693
7694 for( ; i >= 0; i--) {
7695 n0 = dividend_ptr[i];
7696 UDIV_QRNND_PREINV(dummy, r, r,
7697 n0, divisor_limb, divisor_limb_inverted);
7698 }
7699 return r;
7700 }
7701 }
7702 else {
7703 if( UDIV_NEEDS_NORMALIZATION ) {
7704 int normalization_steps;
7705
7706 count_leading_zeros(normalization_steps, divisor_limb);
7707 if( normalization_steps ) {
7708 divisor_limb <<= normalization_steps;
7709
7710 n1 = dividend_ptr[dividend_size - 1];
7711 r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
7712
7713 /* Possible optimization:
7714 * if (r == 0
7715 * && divisor_limb > ((n1 << normalization_steps)
7716 * | (dividend_ptr[dividend_size - 2] >> ...)))
7717 * ...one division less...
7718 */
7719 for(i = dividend_size - 2; i >= 0; i--) {
7720 n0 = dividend_ptr[i];
7721 udiv_qrnnd (dummy, r, r,
7722 ((n1 << normalization_steps)
7723 | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
7724 divisor_limb);
7725 n1 = n0;
7726 }
7727 udiv_qrnnd (dummy, r, r,
7728 n1 << normalization_steps,
7729 divisor_limb);
7730 return r >> normalization_steps;
7731 }
7732 }
7733 /* No normalization needed, either because udiv_qrnnd doesn't require
7734 * it, or because DIVISOR_LIMB is already normalized. */
7735 i = dividend_size - 1;
7736 r = dividend_ptr[i];
7737
7738 if(r >= divisor_limb)
7739 r = 0;
7740 else
7741 i--;
7742
7743 for(; i >= 0; i--) {
7744 n0 = dividend_ptr[i];
7745 udiv_qrnnd (dummy, r, r, n0, divisor_limb);
7746 }
7747 return r;
7748 }
7749 }
7750
7751 /* Divide num (NP/NSIZE) by den (DP/DSIZE) and write
7752 * the NSIZE-DSIZE least significant quotient limbs at QP
7753 * and the DSIZE long remainder at NP. If QEXTRA_LIMBS is
7754 * non-zero, generate that many fraction bits and append them after the
7755 * other quotient limbs.
7756 * Return the most significant limb of the quotient, this is always 0 or 1.
7757 *
7758 * Preconditions:
7759 * 0. NSIZE >= DSIZE.
7760 * 1. The most significant bit of the divisor must be set.
7761 * 2. QP must either not overlap with the input operands at all, or
7762 * QP + DSIZE >= NP must hold true. (This means that it's
7763 * possible to put the quotient in the high part of NUM, right after the
7764 * remainder in NUM.
7765 * 3. NSIZE >= DSIZE, even if QEXTRA_LIMBS is non-zero.
7766 */
7767
7768 mpi_limb_t
7769 mpihelp_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs,
7770 mpi_ptr_t np, mpi_size_t nsize,
7771 mpi_ptr_t dp, mpi_size_t dsize)
7772 {
7773 mpi_limb_t most_significant_q_limb = 0;
7774
7775 switch(dsize) {
7776 case 0:
7777 /* We are asked to divide by zero, so go ahead and do it! (To make
7778 the compiler not remove this statement, return the value.) */
7779 return 1 / dsize;
7780
7781 case 1:
7782 {
7783 mpi_size_t i;
7784 mpi_limb_t n1;
7785 mpi_limb_t d;
7786
7787 d = dp[0];
7788 n1 = np[nsize - 1];
7789
7790 if( n1 >= d ) {
7791 n1 -= d;
7792 most_significant_q_limb = 1;
7793 }
7794
7795 qp += qextra_limbs;
7796 for( i = nsize - 2; i >= 0; i--)
7797 udiv_qrnnd( qp[i], n1, n1, np[i], d );
7798 qp -= qextra_limbs;
7799
7800 for( i = qextra_limbs - 1; i >= 0; i-- )
7801 udiv_qrnnd (qp[i], n1, n1, 0, d);
7802
7803 np[0] = n1;
7804 }
7805 break;
7806
7807 case 2:
7808 {
7809 mpi_size_t i;
7810 mpi_limb_t n1, n0, n2;
7811 mpi_limb_t d1, d0;
7812
7813 np += nsize - 2;
7814 d1 = dp[1];
7815 d0 = dp[0];
7816 n1 = np[1];
7817 n0 = np[0];
7818
7819 if( n1 >= d1 && (n1 > d1 || n0 >= d0) ) {
7820 sub_ddmmss (n1, n0, n1, n0, d1, d0);
7821 most_significant_q_limb = 1;
7822 }
7823
7824 for( i = qextra_limbs + nsize - 2 - 1; i >= 0; i-- ) {
7825 mpi_limb_t q;
7826 mpi_limb_t r;
7827
7828 if( i >= qextra_limbs )
7829 np--;
7830 else
7831 np[0] = 0;
7832
7833 if( n1 == d1 ) {
7834 /* Q should be either 111..111 or 111..110. Need special
7835 * treatment of this rare case as normal division would
7836 * give overflow. */
7837 q = ~(mpi_limb_t)0;
7838
7839 r = n0 + d1;
7840 if( r < d1 ) { /* Carry in the addition? */
7841 add_ssaaaa( n1, n0, r - d0, np[0], 0, d0 );
7842 qp[i] = q;
7843 continue;
7844 }
7845 n1 = d0 - (d0 != 0?1:0);
7846 n0 = -d0;
7847 }
7848 else {
7849 udiv_qrnnd (q, r, n1, n0, d1);
7850 umul_ppmm (n1, n0, d0, q);
7851 }
7852
7853 n2 = np[0];
7854 q_test:
7855 if( n1 > r || (n1 == r && n0 > n2) ) {
7856 /* The estimated Q was too large. */
7857 q--;
7858 sub_ddmmss (n1, n0, n1, n0, 0, d0);
7859 r += d1;
7860 if( r >= d1 ) /* If not carry, test Q again. */
7861 goto q_test;
7862 }
7863
7864 qp[i] = q;
7865 sub_ddmmss (n1, n0, r, n2, n1, n0);
7866 }
7867 np[1] = n1;
7868 np[0] = n0;
7869 }
7870 break;
7871
7872 default:
7873 {
7874 mpi_size_t i;
7875 mpi_limb_t dX, d1, n0;
7876
7877 np += nsize - dsize;
7878 dX = dp[dsize - 1];
7879 d1 = dp[dsize - 2];
7880 n0 = np[dsize - 1];
7881
7882 if( n0 >= dX ) {
7883 if(n0 > dX || mpihelp_cmp(np, dp, dsize - 1) >= 0 ) {
7884 mpihelp_sub_n(np, np, dp, dsize);
7885 n0 = np[dsize - 1];
7886 most_significant_q_limb = 1;
7887 }
7888 }
7889
7890 for( i = qextra_limbs + nsize - dsize - 1; i >= 0; i--) {
7891 mpi_limb_t q;
7892 mpi_limb_t n1, n2;
7893 mpi_limb_t cy_limb;
7894
7895 if( i >= qextra_limbs ) {
7896 np--;
7897 n2 = np[dsize];
7898 }
7899 else {
7900 n2 = np[dsize - 1];
7901 MPN_COPY_DECR (np + 1, np, dsize - 1);
7902 np[0] = 0;
7903 }
7904
7905 if( n0 == dX ) {
7906 /* This might over-estimate q, but it's probably not worth
7907 * the extra code here to find out. */
7908 q = ~(mpi_limb_t)0;
7909 }
7910 else {
7911 mpi_limb_t r;
7912
7913 udiv_qrnnd(q, r, n0, np[dsize - 1], dX);
7914 umul_ppmm(n1, n0, d1, q);
7915
7916 while( n1 > r || (n1 == r && n0 > np[dsize - 2])) {
7917 q--;
7918 r += dX;
7919 if( r < dX ) /* I.e. "carry in previous addition?" */
7920 break;
7921 n1 -= n0 < d1;
7922 n0 -= d1;
7923 }
7924 }
7925
7926 /* Possible optimization: We already have (q * n0) and (1 * n1)
7927 * after the calculation of q. Taking advantage of that, we
7928 * could make this loop make two iterations less. */
7929 cy_limb = mpihelp_submul_1(np, dp, dsize, q);
7930
7931 if( n2 != cy_limb ) {
7932 mpihelp_add_n(np, np, dp, dsize);
7933 q--;
7934 }
7935
7936 qp[i] = q;
7937 n0 = np[dsize - 1];
7938 }
7939 }
7940 }
7941
7942 return most_significant_q_limb;
7943 }
7944
7945
7946 /****************
7947 * Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB.
7948 * Write DIVIDEND_SIZE limbs of quotient at QUOT_PTR.
7949 * Return the single-limb remainder.
7950 * There are no constraints on the value of the divisor.
7951 *
7952 * QUOT_PTR and DIVIDEND_PTR might point to the same limb.
7953 */
7954
7955 mpi_limb_t
7956 mpihelp_divmod_1( mpi_ptr_t quot_ptr,
7957 mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
7958 mpi_limb_t divisor_limb)
7959 {
7960 mpi_size_t i;
7961 mpi_limb_t n1, n0, r;
7962 int dummy;
7963
7964 if( !dividend_size )
7965 return 0;
7966
7967 /* If multiplication is much faster than division, and the
7968 * dividend is large, pre-invert the divisor, and use
7969 * only multiplications in the inner loop.
7970 *
7971 * This test should be read:
7972 * Does it ever help to use udiv_qrnnd_preinv?
7973 * && Does what we save compensate for the inversion overhead?
7974 */
7975 if( UDIV_TIME > (2 * UMUL_TIME + 6)
7976 && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME ) {
7977 int normalization_steps;
7978
7979 count_leading_zeros( normalization_steps, divisor_limb );
7980 if( normalization_steps ) {
7981 mpi_limb_t divisor_limb_inverted;
7982
7983 divisor_limb <<= normalization_steps;
7984
7985 /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
7986 * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
7987 * most significant bit (with weight 2**N) implicit.
7988 */
7989 /* Special case for DIVISOR_LIMB == 100...000. */
7990 if( !(divisor_limb << 1) )
7991 divisor_limb_inverted = ~(mpi_limb_t)0;
7992 else
7993 udiv_qrnnd(divisor_limb_inverted, dummy,
7994 -divisor_limb, 0, divisor_limb);
7995
7996 n1 = dividend_ptr[dividend_size - 1];
7997 r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
7998
7999 /* Possible optimization:
8000 * if (r == 0
8001 * && divisor_limb > ((n1 << normalization_steps)
8002 * | (dividend_ptr[dividend_size - 2] >> ...)))
8003 * ...one division less...
8004 */
8005 for( i = dividend_size - 2; i >= 0; i--) {
8006 n0 = dividend_ptr[i];
8007 UDIV_QRNND_PREINV( quot_ptr[i + 1], r, r,
8008 ((n1 << normalization_steps)
8009 | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
8010 divisor_limb, divisor_limb_inverted);
8011 n1 = n0;
8012 }
8013 UDIV_QRNND_PREINV( quot_ptr[0], r, r,
8014 n1 << normalization_steps,
8015 divisor_limb, divisor_limb_inverted);
8016 return r >> normalization_steps;
8017 }
8018 else {
8019 mpi_limb_t divisor_limb_inverted;
8020
8021 /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
8022 * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
8023 * most significant bit (with weight 2**N) implicit.
8024 */
8025 /* Special case for DIVISOR_LIMB == 100...000. */
8026 if( !(divisor_limb << 1) )
8027 divisor_limb_inverted = ~(mpi_limb_t) 0;
8028 else
8029 udiv_qrnnd(divisor_limb_inverted, dummy,
8030 -divisor_limb, 0, divisor_limb);
8031
8032 i = dividend_size - 1;
8033 r = dividend_ptr[i];
8034
8035 if( r >= divisor_limb )
8036 r = 0;
8037 else
8038 quot_ptr[i--] = 0;
8039
8040 for( ; i >= 0; i-- ) {
8041 n0 = dividend_ptr[i];
8042 UDIV_QRNND_PREINV( quot_ptr[i], r, r,
8043 n0, divisor_limb, divisor_limb_inverted);
8044 }
8045 return r;
8046 }
8047 }
8048 else {
8049 if(UDIV_NEEDS_NORMALIZATION) {
8050 int normalization_steps;
8051
8052 count_leading_zeros (normalization_steps, divisor_limb);
8053 if( normalization_steps ) {
8054 divisor_limb <<= normalization_steps;
8055
8056 n1 = dividend_ptr[dividend_size - 1];
8057 r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
8058
8059 /* Possible optimization:
8060 * if (r == 0
8061 * && divisor_limb > ((n1 << normalization_steps)
8062 * | (dividend_ptr[dividend_size - 2] >> ...)))
8063 * ...one division less...
8064 */
8065 for( i = dividend_size - 2; i >= 0; i--) {
8066 n0 = dividend_ptr[i];
8067 udiv_qrnnd (quot_ptr[i + 1], r, r,
8068 ((n1 << normalization_steps)
8069 | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
8070 divisor_limb);
8071 n1 = n0;
8072 }
8073 udiv_qrnnd (quot_ptr[0], r, r,
8074 n1 << normalization_steps,
8075 divisor_limb);
8076 return r >> normalization_steps;
8077 }
8078 }
8079 /* No normalization needed, either because udiv_qrnnd doesn't require
8080 * it, or because DIVISOR_LIMB is already normalized. */
8081 i = dividend_size - 1;
8082 r = dividend_ptr[i];
8083
8084 if(r >= divisor_limb)
8085 r = 0;
8086 else
8087 quot_ptr[i--] = 0;
8088
8089 for(; i >= 0; i--) {
8090 n0 = dividend_ptr[i];
8091 udiv_qrnnd( quot_ptr[i], r, r, n0, divisor_limb );
8092 }
8093 return r;
8094 }
8095 }
-
+ 3222BFC241FA6104936CC585FDA392F220D88031FA0FDF460BB201A3AA7295E6D1DC75007BF53D2E501734D9FAAA31934EED944CE7452A6AA3AFCD3A333D3C13
mpi/mpih-lshift.c
(0 . 0)(1 . 68)
8100 /* mpihelp-lshift.c - MPI helper functions
8101 * Copyright (C) 1994, 1996, 1998, 2001 Free Software Foundation, Inc.
8102 *
8103 * This file is part of GnuPG.
8104 *
8105 * GnuPG is free software; you can redistribute it and/or modify
8106 * it under the terms of the GNU General Public License as published by
8107 * the Free Software Foundation; either version 3 of the License, or
8108 * (at your option) any later version.
8109 *
8110 * GnuPG is distributed in the hope that it will be useful,
8111 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8112 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8113 * GNU General Public License for more details.
8114 *
8115 * You should have received a copy of the GNU General Public License
8116 * along with this program; if not, see <http://www.gnu.org/licenses/>.
8117 *
8118 * Note: This code is heavily based on the GNU MP Library.
8119 * Actually it's the same code with only minor changes in the
8120 * way the data is stored; this is to support the abstraction
8121 * of an optional secure memory allocation which may be used
8122 * to avoid revealing of sensitive data due to paging etc.
8123 * The GNU MP Library itself is published under the LGPL;
8124 * however I decided to publish this code under the plain GPL.
8125 */
8126
8127 #include <config.h>
8128 #include <stdio.h>
8129 #include <stdlib.h>
8130 #include "mpi-internal.h"
8131
8132 /* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left
8133 * and store the USIZE least significant digits of the result at WP.
8134 * Return the bits shifted out from the most significant digit.
8135 *
8136 * Argument constraints:
8137 * 1. 0 < CNT < BITS_PER_MP_LIMB
8138 * 2. If the result is to be written over the input, WP must be >= UP.
8139 */
8140
8141 mpi_limb_t
8142 mpihelp_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
8143 unsigned int cnt)
8144 {
8145 mpi_limb_t high_limb, low_limb;
8146 unsigned sh_1, sh_2;
8147 mpi_size_t i;
8148 mpi_limb_t retval;
8149
8150 sh_1 = cnt;
8151 wp += 1;
8152 sh_2 = BITS_PER_MPI_LIMB - sh_1;
8153 i = usize - 1;
8154 low_limb = up[i];
8155 retval = low_limb >> sh_2;
8156 high_limb = low_limb;
8157 while( --i >= 0 ) {
8158 low_limb = up[i];
8159 wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
8160 high_limb = low_limb;
8161 }
8162 wp[i] = high_limb << sh_1;
8163
8164 return retval;
8165 }
8166
8167
-
+ 86B925ACDAEDFAAF9C7F7FF783DA4A049C62C8F63929BF288FDC8E4760DC9B451440ED5ED5F8549E8B2CCBD4F00175F068DE9DC337EEDFD8FAD8348D21F3ED13
mpi/mpih-mul1.c
(0 . 0)(1 . 60)
8172 /* mpihelp-mul_1.c - MPI helper functions
8173 * Copyright (C) 1994, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
8174 *
8175 * This file is part of GnuPG.
8176 *
8177 * GnuPG is free software; you can redistribute it and/or modify
8178 * it under the terms of the GNU General Public License as published by
8179 * the Free Software Foundation; either version 3 of the License, or
8180 * (at your option) any later version.
8181 *
8182 * GnuPG is distributed in the hope that it will be useful,
8183 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8184 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8185 * GNU General Public License for more details.
8186 *
8187 * You should have received a copy of the GNU General Public License
8188 * along with this program; if not, see <http://www.gnu.org/licenses/>.
8189 *
8190 * Note: This code is heavily based on the GNU MP Library.
8191 * Actually it's the same code with only minor changes in the
8192 * way the data is stored; this is to support the abstraction
8193 * of an optional secure memory allocation which may be used
8194 * to avoid revealing of sensitive data due to paging etc.
8195 * The GNU MP Library itself is published under the LGPL;
8196 * however I decided to publish this code under the plain GPL.
8197 */
8198
8199 #include <config.h>
8200 #include <stdio.h>
8201 #include <stdlib.h>
8202 #include "mpi-internal.h"
8203 #include "longlong.h"
8204
8205 mpi_limb_t
8206 mpihelp_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
8207 mpi_limb_t s2_limb)
8208 {
8209 mpi_limb_t cy_limb;
8210 mpi_size_t j;
8211 mpi_limb_t prod_high, prod_low;
8212
8213 /* The loop counter and index J goes from -S1_SIZE to -1. This way
8214 * the loop becomes faster. */
8215 j = -s1_size;
8216
8217 /* Offset the base pointers to compensate for the negative indices. */
8218 s1_ptr -= j;
8219 res_ptr -= j;
8220
8221 cy_limb = 0;
8222 do {
8223 umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb );
8224 prod_low += cy_limb;
8225 cy_limb = (prod_low < cy_limb?1:0) + prod_high;
8226 res_ptr[j] = prod_low;
8227 } while( ++j );
8228
8229 return cy_limb;
8230 }
8231
-
+ 340744F79D1466A916FCA829C66F86915B808800BF3EBE2CCADABA1D5FD89EF5C5DB486C94B0F01ACE52F13D7A74784B68214499F5AC120AC8449FC9EB5C61C3
mpi/mpih-mul2.c
(0 . 0)(1 . 65)
8236 /* mpihelp-mul_2.c - MPI helper functions
8237 * Copyright (C) 1994, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
8238 *
8239 * This file is part of GnuPG.
8240 *
8241 * GnuPG is free software; you can redistribute it and/or modify
8242 * it under the terms of the GNU General Public License as published by
8243 * the Free Software Foundation; either version 3 of the License, or
8244 * (at your option) any later version.
8245 *
8246 * GnuPG is distributed in the hope that it will be useful,
8247 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8248 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8249 * GNU General Public License for more details.
8250 *
8251 * You should have received a copy of the GNU General Public License
8252 * along with this program; if not, see <http://www.gnu.org/licenses/>.
8253 *
8254 * Note: This code is heavily based on the GNU MP Library.
8255 * Actually it's the same code with only minor changes in the
8256 * way the data is stored; this is to support the abstraction
8257 * of an optional secure memory allocation which may be used
8258 * to avoid revealing of sensitive data due to paging etc.
8259 * The GNU MP Library itself is published under the LGPL;
8260 * however I decided to publish this code under the plain GPL.
8261 */
8262
8263 #include <config.h>
8264 #include <stdio.h>
8265 #include <stdlib.h>
8266 #include "mpi-internal.h"
8267 #include "longlong.h"
8268
8269
8270 mpi_limb_t
8271 mpihelp_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
8272 mpi_size_t s1_size, mpi_limb_t s2_limb)
8273 {
8274 mpi_limb_t cy_limb;
8275 mpi_size_t j;
8276 mpi_limb_t prod_high, prod_low;
8277 mpi_limb_t x;
8278
8279 /* The loop counter and index J goes from -SIZE to -1. This way
8280 * the loop becomes faster. */
8281 j = -s1_size;
8282 res_ptr -= j;
8283 s1_ptr -= j;
8284
8285 cy_limb = 0;
8286 do {
8287 umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb );
8288
8289 prod_low += cy_limb;
8290 cy_limb = (prod_low < cy_limb?1:0) + prod_high;
8291
8292 x = res_ptr[j];
8293 prod_low = x + prod_low;
8294 cy_limb += prod_low < x?1:0;
8295 res_ptr[j] = prod_low;
8296 } while ( ++j );
8297 return cy_limb;
8298 }
8299
8300
-
+ 683F47357B0F57E3DC50AEFC32BDCD8C20E7A9A4C3DC48D3BA9E5715E12836B6CE53B8DFF653BDB86CDD197DAAB9AF7532DEF5BB06D861BDF48F4DC705AC6AA4
mpi/mpih-mul3.c
(0 . 0)(1 . 66)
8305 /* mpihelp-mul_3.c - MPI helper functions
8306 * Copyright (C) 1994, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
8307 *
8308 * This file is part of GnuPG.
8309 *
8310 * GnuPG is free software; you can redistribute it and/or modify
8311 * it under the terms of the GNU General Public License as published by
8312 * the Free Software Foundation; either version 3 of the License, or
8313 * (at your option) any later version.
8314 *
8315 * GnuPG is distributed in the hope that it will be useful,
8316 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8317 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8318 * GNU General Public License for more details.
8319 *
8320 * You should have received a copy of the GNU General Public License
8321 * along with this program; if not, see <http://www.gnu.org/licenses/>.
8322 *
8323 * Note: This code is heavily based on the GNU MP Library.
8324 * Actually it's the same code with only minor changes in the
8325 * way the data is stored; this is to support the abstraction
8326 * of an optional secure memory allocation which may be used
8327 * to avoid revealing of sensitive data due to paging etc.
8328 * The GNU MP Library itself is published under the LGPL;
8329 * however I decided to publish this code under the plain GPL.
8330 */
8331
8332 #include <config.h>
8333 #include <stdio.h>
8334 #include <stdlib.h>
8335 #include "mpi-internal.h"
8336 #include "longlong.h"
8337
8338
8339 mpi_limb_t
8340 mpihelp_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
8341 mpi_size_t s1_size, mpi_limb_t s2_limb)
8342 {
8343 mpi_limb_t cy_limb;
8344 mpi_size_t j;
8345 mpi_limb_t prod_high, prod_low;
8346 mpi_limb_t x;
8347
8348 /* The loop counter and index J goes from -SIZE to -1. This way
8349 * the loop becomes faster. */
8350 j = -s1_size;
8351 res_ptr -= j;
8352 s1_ptr -= j;
8353
8354 cy_limb = 0;
8355 do {
8356 umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb);
8357
8358 prod_low += cy_limb;
8359 cy_limb = (prod_low < cy_limb?1:0) + prod_high;
8360
8361 x = res_ptr[j];
8362 prod_low = x - prod_low;
8363 cy_limb += prod_low > x?1:0;
8364 res_ptr[j] = prod_low;
8365 } while( ++j );
8366
8367 return cy_limb;
8368 }
8369
8370
-
+ 2D6F3C1ECB3331CDFB54C9EFA53246CAC6A6DFA16465D2E354C6801974964229CB173E7AFF19C4C92E896B8C65CFBC6DA79EF03C20022772F5C299F1C3CBC063
mpi/mpih-mul.c
(0 . 0)(1 . 527)
8375 /* mpihelp-mul.c - MPI helper functions
8376 * Copyright (C) 1994, 1996, 1998, 1999,
8377 * 2000 Free Software Foundation, Inc.
8378 *
8379 * This file is part of GnuPG.
8380 *
8381 * GnuPG is free software; you can redistribute it and/or modify
8382 * it under the terms of the GNU General Public License as published by
8383 * the Free Software Foundation; either version 3 of the License, or
8384 * (at your option) any later version.
8385 *
8386 * GnuPG is distributed in the hope that it will be useful,
8387 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8388 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8389 * GNU General Public License for more details.
8390 *
8391 * You should have received a copy of the GNU General Public License
8392 * along with this program; if not, see <http://www.gnu.org/licenses/>.
8393 *
8394 * Note: This code is heavily based on the GNU MP Library.
8395 * Actually it's the same code with only minor changes in the
8396 * way the data is stored; this is to support the abstraction
8397 * of an optional secure memory allocation which may be used
8398 * to avoid revealing of sensitive data due to paging etc.
8399 * The GNU MP Library itself is published under the LGPL;
8400 * however I decided to publish this code under the plain GPL.
8401 */
8402
8403 #include <config.h>
8404 #include <stdio.h>
8405 #include <stdlib.h>
8406 #include <string.h>
8407 #include "mpi-internal.h"
8408 #include "longlong.h"
8409
8410
8411
8412 #define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
8413 do { \
8414 if( (size) < KARATSUBA_THRESHOLD ) \
8415 mul_n_basecase (prodp, up, vp, size); \
8416 else \
8417 mul_n (prodp, up, vp, size, tspace); \
8418 } while (0);
8419
8420 #define MPN_SQR_N_RECURSE(prodp, up, size, tspace) \
8421 do { \
8422 if ((size) < KARATSUBA_THRESHOLD) \
8423 mpih_sqr_n_basecase (prodp, up, size); \
8424 else \
8425 mpih_sqr_n (prodp, up, size, tspace); \
8426 } while (0);
8427
8428
8429
8430
8431 /* Multiply the natural numbers u (pointed to by UP) and v (pointed to by VP),
8432 * both with SIZE limbs, and store the result at PRODP. 2 * SIZE limbs are
8433 * always stored. Return the most significant limb.
8434 *
8435 * Argument constraints:
8436 * 1. PRODP != UP and PRODP != VP, i.e. the destination
8437 * must be distinct from the multiplier and the multiplicand.
8438 *
8439 *
8440 * Handle simple cases with traditional multiplication.
8441 *
8442 * This is the most critical code of multiplication. All multiplies rely
8443 * on this, both small and huge. Small ones arrive here immediately. Huge
8444 * ones arrive here as this is the base case for Karatsuba's recursive
8445 * algorithm below.
8446 */
8447
8448 static mpi_limb_t
8449 mul_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up,
8450 mpi_ptr_t vp, mpi_size_t size)
8451 {
8452 mpi_size_t i;
8453 mpi_limb_t cy;
8454 mpi_limb_t v_limb;
8455
8456 /* Multiply by the first limb in V separately, as the result can be
8457 * stored (not added) to PROD. We also avoid a loop for zeroing. */
8458 v_limb = vp[0];
8459 if( v_limb <= 1 ) {
8460 if( v_limb == 1 )
8461 MPN_COPY( prodp, up, size );
8462 else
8463 MPN_ZERO( prodp, size );
8464 cy = 0;
8465 }
8466 else
8467 cy = mpihelp_mul_1( prodp, up, size, v_limb );
8468
8469 prodp[size] = cy;
8470 prodp++;
8471
8472 /* For each iteration in the outer loop, multiply one limb from
8473 * U with one limb from V, and add it to PROD. */
8474 for( i = 1; i < size; i++ ) {
8475 v_limb = vp[i];
8476 if( v_limb <= 1 ) {
8477 cy = 0;
8478 if( v_limb == 1 )
8479 cy = mpihelp_add_n(prodp, prodp, up, size);
8480 }
8481 else
8482 cy = mpihelp_addmul_1(prodp, up, size, v_limb);
8483
8484 prodp[size] = cy;
8485 prodp++;
8486 }
8487
8488 return cy;
8489 }
8490
8491
8492 static void
8493 mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp,
8494 mpi_size_t size, mpi_ptr_t tspace )
8495 {
8496 if( size & 1 ) {
8497 /* The size is odd, and the code below doesn't handle that.
8498 * Multiply the least significant (size - 1) limbs with a recursive
8499 * call, and handle the most significant limb of S1 and S2
8500 * separately.
8501 * A slightly faster way to do this would be to make the Karatsuba
8502 * code below behave as if the size were even, and let it check for
8503 * odd size in the end. I.e., in essence move this code to the end.
8504 * Doing so would save us a recursive call, and potentially make the
8505 * stack grow a lot less.
8506 */
8507 mpi_size_t esize = size - 1; /* even size */
8508 mpi_limb_t cy_limb;
8509
8510 MPN_MUL_N_RECURSE( prodp, up, vp, esize, tspace );
8511 cy_limb = mpihelp_addmul_1( prodp + esize, up, esize, vp[esize] );
8512 prodp[esize + esize] = cy_limb;
8513 cy_limb = mpihelp_addmul_1( prodp + esize, vp, size, up[esize] );
8514 prodp[esize + size] = cy_limb;
8515 }
8516 else {
8517 /* Anatolij Alekseevich Karatsuba's divide-and-conquer algorithm.
8518 *
8519 * Split U in two pieces, U1 and U0, such that
8520 * U = U0 + U1*(B**n),
8521 * and V in V1 and V0, such that
8522 * V = V0 + V1*(B**n).
8523 *
8524 * UV is then computed recursively using the identity
8525 *
8526 * 2n n n n
8527 * UV = (B + B )U V + B (U -U )(V -V ) + (B + 1)U V
8528 * 1 1 1 0 0 1 0 0
8529 *
8530 * Where B = 2**BITS_PER_MP_LIMB.
8531 */
8532 mpi_size_t hsize = size >> 1;
8533 mpi_limb_t cy;
8534 int negflg;
8535
8536 /* Product H. ________________ ________________
8537 * |_____U1 x V1____||____U0 x V0_____|
8538 * Put result in upper part of PROD and pass low part of TSPACE
8539 * as new TSPACE.
8540 */
8541 MPN_MUL_N_RECURSE(prodp + size, up + hsize, vp + hsize, hsize, tspace);
8542
8543 /* Product M. ________________
8544 * |_(U1-U0)(V0-V1)_|
8545 */
8546 if( mpihelp_cmp(up + hsize, up, hsize) >= 0 ) {
8547 mpihelp_sub_n(prodp, up + hsize, up, hsize);
8548 negflg = 0;
8549 }
8550 else {
8551 mpihelp_sub_n(prodp, up, up + hsize, hsize);
8552 negflg = 1;
8553 }
8554 if( mpihelp_cmp(vp + hsize, vp, hsize) >= 0 ) {
8555 mpihelp_sub_n(prodp + hsize, vp + hsize, vp, hsize);
8556 negflg ^= 1;
8557 }
8558 else {
8559 mpihelp_sub_n(prodp + hsize, vp, vp + hsize, hsize);
8560 /* No change of NEGFLG. */
8561 }
8562 /* Read temporary operands from low part of PROD.
8563 * Put result in low part of TSPACE using upper part of TSPACE
8564 * as new TSPACE.
8565 */
8566 MPN_MUL_N_RECURSE(tspace, prodp, prodp + hsize, hsize, tspace + size);
8567
8568 /* Add/copy product H. */
8569 MPN_COPY (prodp + hsize, prodp + size, hsize);
8570 cy = mpihelp_add_n( prodp + size, prodp + size,
8571 prodp + size + hsize, hsize);
8572
8573 /* Add product M (if NEGFLG M is a negative number) */
8574 if(negflg)
8575 cy -= mpihelp_sub_n(prodp + hsize, prodp + hsize, tspace, size);
8576 else
8577 cy += mpihelp_add_n(prodp + hsize, prodp + hsize, tspace, size);
8578
8579 /* Product L. ________________ ________________
8580 * |________________||____U0 x V0_____|
8581 * Read temporary operands from low part of PROD.
8582 * Put result in low part of TSPACE using upper part of TSPACE
8583 * as new TSPACE.
8584 */
8585 MPN_MUL_N_RECURSE(tspace, up, vp, hsize, tspace + size);
8586
8587 /* Add/copy Product L (twice) */
8588
8589 cy += mpihelp_add_n(prodp + hsize, prodp + hsize, tspace, size);
8590 if( cy )
8591 mpihelp_add_1(prodp + hsize + size, prodp + hsize + size, hsize, cy);
8592
8593 MPN_COPY(prodp, tspace, hsize);
8594 cy = mpihelp_add_n(prodp + hsize, prodp + hsize, tspace + hsize, hsize);
8595 if( cy )
8596 mpihelp_add_1(prodp + size, prodp + size, size, 1);
8597 }
8598 }
8599
8600
8601 void
8602 mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size )
8603 {
8604 mpi_size_t i;
8605 mpi_limb_t cy_limb;
8606 mpi_limb_t v_limb;
8607
8608 /* Multiply by the first limb in V separately, as the result can be
8609 * stored (not added) to PROD. We also avoid a loop for zeroing. */
8610 v_limb = up[0];
8611 if( v_limb <= 1 ) {
8612 if( v_limb == 1 )
8613 MPN_COPY( prodp, up, size );
8614 else
8615 MPN_ZERO(prodp, size);
8616 cy_limb = 0;
8617 }
8618 else
8619 cy_limb = mpihelp_mul_1( prodp, up, size, v_limb );
8620
8621 prodp[size] = cy_limb;
8622 prodp++;
8623
8624 /* For each iteration in the outer loop, multiply one limb from
8625 * U with one limb from V, and add it to PROD. */
8626 for( i=1; i < size; i++) {
8627 v_limb = up[i];
8628 if( v_limb <= 1 ) {
8629 cy_limb = 0;
8630 if( v_limb == 1 )
8631 cy_limb = mpihelp_add_n(prodp, prodp, up, size);
8632 }
8633 else
8634 cy_limb = mpihelp_addmul_1(prodp, up, size, v_limb);
8635
8636 prodp[size] = cy_limb;
8637 prodp++;
8638 }
8639 }
8640
8641
8642 void
8643 mpih_sqr_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size, mpi_ptr_t tspace)
8644 {
8645 if( size & 1 ) {
8646 /* The size is odd, and the code below doesn't handle that.
8647 * Multiply the least significant (size - 1) limbs with a recursive
8648 * call, and handle the most significant limb of S1 and S2
8649 * separately.
8650 * A slightly faster way to do this would be to make the Karatsuba
8651 * code below behave as if the size were even, and let it check for
8652 * odd size in the end. I.e., in essence move this code to the end.
8653 * Doing so would save us a recursive call, and potentially make the
8654 * stack grow a lot less.
8655 */
8656 mpi_size_t esize = size - 1; /* even size */
8657 mpi_limb_t cy_limb;
8658
8659 MPN_SQR_N_RECURSE( prodp, up, esize, tspace );
8660 cy_limb = mpihelp_addmul_1( prodp + esize, up, esize, up[esize] );
8661 prodp[esize + esize] = cy_limb;
8662 cy_limb = mpihelp_addmul_1( prodp + esize, up, size, up[esize] );
8663
8664 prodp[esize + size] = cy_limb;
8665 }
8666 else {
8667 mpi_size_t hsize = size >> 1;
8668 mpi_limb_t cy;
8669
8670 /* Product H. ________________ ________________
8671 * |_____U1 x U1____||____U0 x U0_____|
8672 * Put result in upper part of PROD and pass low part of TSPACE
8673 * as new TSPACE.
8674 */
8675 MPN_SQR_N_RECURSE(prodp + size, up + hsize, hsize, tspace);
8676
8677 /* Product M. ________________
8678 * |_(U1-U0)(U0-U1)_|
8679 */
8680 if( mpihelp_cmp( up + hsize, up, hsize) >= 0 )
8681 mpihelp_sub_n( prodp, up + hsize, up, hsize);
8682 else
8683 mpihelp_sub_n (prodp, up, up + hsize, hsize);
8684
8685 /* Read temporary operands from low part of PROD.
8686 * Put result in low part of TSPACE using upper part of TSPACE
8687 * as new TSPACE. */
8688 MPN_SQR_N_RECURSE(tspace, prodp, hsize, tspace + size);
8689
8690 /* Add/copy product H */
8691 MPN_COPY(prodp + hsize, prodp + size, hsize);
8692 cy = mpihelp_add_n(prodp + size, prodp + size,
8693 prodp + size + hsize, hsize);
8694
8695 /* Add product M (if NEGFLG M is a negative number). */
8696 cy -= mpihelp_sub_n (prodp + hsize, prodp + hsize, tspace, size);
8697
8698 /* Product L. ________________ ________________
8699 * |________________||____U0 x U0_____|
8700 * Read temporary operands from low part of PROD.
8701 * Put result in low part of TSPACE using upper part of TSPACE
8702 * as new TSPACE. */
8703 MPN_SQR_N_RECURSE (tspace, up, hsize, tspace + size);
8704
8705 /* Add/copy Product L (twice). */
8706 cy += mpihelp_add_n (prodp + hsize, prodp + hsize, tspace, size);
8707 if( cy )
8708 mpihelp_add_1(prodp + hsize + size, prodp + hsize + size,
8709 hsize, cy);
8710
8711 MPN_COPY(prodp, tspace, hsize);
8712 cy = mpihelp_add_n (prodp + hsize, prodp + hsize, tspace + hsize, hsize);
8713 if( cy )
8714 mpihelp_add_1 (prodp + size, prodp + size, size, 1);
8715 }
8716 }
8717
8718
8719 /* This should be made into an inline function in gmp.h. */
8720 void
8721 mpihelp_mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size)
8722 {
8723 int secure;
8724
8725 if( up == vp ) {
8726 if( size < KARATSUBA_THRESHOLD )
8727 mpih_sqr_n_basecase( prodp, up, size );
8728 else {
8729 mpi_ptr_t tspace;
8730 secure = m_is_secure( up );
8731 tspace = mpi_alloc_limb_space( 2 * size, secure );
8732 mpih_sqr_n( prodp, up, size, tspace );
8733 mpi_free_limb_space( tspace );
8734 }
8735 }
8736 else {
8737 if( size < KARATSUBA_THRESHOLD )
8738 mul_n_basecase( prodp, up, vp, size );
8739 else {
8740 mpi_ptr_t tspace;
8741 secure = m_is_secure( up ) || m_is_secure( vp );
8742 tspace = mpi_alloc_limb_space( 2 * size, secure );
8743 mul_n (prodp, up, vp, size, tspace);
8744 mpi_free_limb_space( tspace );
8745 }
8746 }
8747 }
8748
8749
8750
8751 void
8752 mpihelp_mul_karatsuba_case( mpi_ptr_t prodp,
8753 mpi_ptr_t up, mpi_size_t usize,
8754 mpi_ptr_t vp, mpi_size_t vsize,
8755 struct karatsuba_ctx *ctx )
8756 {
8757 mpi_limb_t cy;
8758
8759 if( !ctx->tspace || ctx->tspace_size < vsize ) {
8760 if( ctx->tspace )
8761 mpi_free_limb_space( ctx->tspace );
8762 ctx->tspace = mpi_alloc_limb_space( 2 * vsize,
8763 m_is_secure( up ) || m_is_secure( vp ) );
8764 ctx->tspace_size = vsize;
8765 }
8766
8767 MPN_MUL_N_RECURSE( prodp, up, vp, vsize, ctx->tspace );
8768
8769 prodp += vsize;
8770 up += vsize;
8771 usize -= vsize;
8772 if( usize >= vsize ) {
8773 if( !ctx->tp || ctx->tp_size < vsize ) {
8774 if( ctx->tp )
8775 mpi_free_limb_space( ctx->tp );
8776 ctx->tp = mpi_alloc_limb_space( 2 * vsize, m_is_secure( up )
8777 || m_is_secure( vp ) );
8778 ctx->tp_size = vsize;
8779 }
8780
8781 do {
8782 MPN_MUL_N_RECURSE( ctx->tp, up, vp, vsize, ctx->tspace );
8783 cy = mpihelp_add_n( prodp, prodp, ctx->tp, vsize );
8784 mpihelp_add_1( prodp + vsize, ctx->tp + vsize, vsize, cy );
8785 prodp += vsize;
8786 up += vsize;
8787 usize -= vsize;
8788 } while( usize >= vsize );
8789 }
8790
8791 if( usize ) {
8792 if( usize < KARATSUBA_THRESHOLD ) {
8793 mpihelp_mul( ctx->tspace, vp, vsize, up, usize );
8794 }
8795 else {
8796 if( !ctx->next ) {
8797 ctx->next = xmalloc_clear( sizeof *ctx );
8798 }
8799 mpihelp_mul_karatsuba_case( ctx->tspace,
8800 vp, vsize,
8801 up, usize,
8802 ctx->next );
8803 }
8804
8805 cy = mpihelp_add_n( prodp, prodp, ctx->tspace, vsize);
8806 mpihelp_add_1( prodp + vsize, ctx->tspace + vsize, usize, cy );
8807 }
8808 }
8809
8810
8811 void
8812 mpihelp_release_karatsuba_ctx( struct karatsuba_ctx *ctx )
8813 {
8814 struct karatsuba_ctx *ctx2;
8815
8816 if( ctx->tp )
8817 mpi_free_limb_space( ctx->tp );
8818 if( ctx->tspace )
8819 mpi_free_limb_space( ctx->tspace );
8820 for( ctx=ctx->next; ctx; ctx = ctx2 ) {
8821 ctx2 = ctx->next;
8822 if( ctx->tp )
8823 mpi_free_limb_space( ctx->tp );
8824 if( ctx->tspace )
8825 mpi_free_limb_space( ctx->tspace );
8826 xfree( ctx );
8827 }
8828 }
8829
8830 /* Multiply the natural numbers u (pointed to by UP, with USIZE limbs)
8831 * and v (pointed to by VP, with VSIZE limbs), and store the result at
8832 * PRODP. USIZE + VSIZE limbs are always stored, but if the input
8833 * operands are normalized. Return the most significant limb of the
8834 * result.
8835 *
8836 * NOTE: The space pointed to by PRODP is overwritten before finished
8837 * with U and V, so overlap is an error.
8838 *
8839 * Argument constraints:
8840 * 1. USIZE >= VSIZE.
8841 * 2. PRODP != UP and PRODP != VP, i.e. the destination
8842 * must be distinct from the multiplier and the multiplicand.
8843 */
8844
8845 mpi_limb_t
8846 mpihelp_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
8847 mpi_ptr_t vp, mpi_size_t vsize)
8848 {
8849 mpi_ptr_t prod_endp = prodp + usize + vsize - 1;
8850 mpi_limb_t cy;
8851 struct karatsuba_ctx ctx;
8852
8853 if( vsize < KARATSUBA_THRESHOLD ) {
8854 mpi_size_t i;
8855 mpi_limb_t v_limb;
8856
8857 if( !vsize )
8858 return 0;
8859
8860 /* Multiply by the first limb in V separately, as the result can be
8861 * stored (not added) to PROD. We also avoid a loop for zeroing. */
8862 v_limb = vp[0];
8863 if( v_limb <= 1 ) {
8864 if( v_limb == 1 )
8865 MPN_COPY( prodp, up, usize );
8866 else
8867 MPN_ZERO( prodp, usize );
8868 cy = 0;
8869 }
8870 else
8871 cy = mpihelp_mul_1( prodp, up, usize, v_limb );
8872
8873 prodp[usize] = cy;
8874 prodp++;
8875
8876 /* For each iteration in the outer loop, multiply one limb from
8877 * U with one limb from V, and add it to PROD. */
8878 for( i = 1; i < vsize; i++ ) {
8879 v_limb = vp[i];
8880 if( v_limb <= 1 ) {
8881 cy = 0;
8882 if( v_limb == 1 )
8883 cy = mpihelp_add_n(prodp, prodp, up, usize);
8884 }
8885 else
8886 cy = mpihelp_addmul_1(prodp, up, usize, v_limb);
8887
8888 prodp[usize] = cy;
8889 prodp++;
8890 }
8891
8892 return cy;
8893 }
8894
8895 memset( &ctx, 0, sizeof ctx );
8896 mpihelp_mul_karatsuba_case( prodp, up, usize, vp, vsize, &ctx );
8897 mpihelp_release_karatsuba_ctx( &ctx );
8898 return *prod_endp;
8899 }
8900
8901
-
+ B98CF2FB49B284C7FFDA191D6E1A336E87BC9D5C302753C04E704DE455793BD9736D6318E1C314FC8CF97BAEBC830EAE998C35382AFB2810126C1CC9BD18BDCE
mpi/mpih-rshift.c
(0 . 0)(1 . 67)
8906 /* mpih-rshift.c - MPI helper functions
8907 * Copyright (C) 1994, 1996, 1998, 1999,
8908 * 2000, 2001 Free Software Foundation, Inc.
8909 *
8910 * This file is part of GNUPG
8911 *
8912 * GNUPG is free software; you can redistribute it and/or modify
8913 * it under the terms of the GNU General Public License as published by
8914 * the Free Software Foundation; either version 3 of the License, or
8915 * (at your option) any later version.
8916 *
8917 * GNUPG is distributed in the hope that it will be useful,
8918 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8919 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8920 * GNU General Public License for more details.
8921 *
8922 * You should have received a copy of the GNU General Public License
8923 * along with this program; if not, see <http://www.gnu.org/licenses/>.
8924 *
8925 * Note: This code is heavily based on the GNU MP Library.
8926 * Actually it's the same code with only minor changes in the
8927 * way the data is stored; this is to support the abstraction
8928 * of an optional secure memory allocation which may be used
8929 * to avoid revealing of sensitive data due to paging etc.
8930 * The GNU MP Library itself is published under the LGPL;
8931 * however I decided to publish this code under the plain GPL.
8932 */
8933
8934 #include <config.h>
8935 #include <stdio.h>
8936 #include <stdlib.h>
8937 #include "mpi-internal.h"
8938
8939
8940 /* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right
8941 * and store the USIZE least significant limbs of the result at WP.
8942 * The bits shifted out to the right are returned.
8943 *
8944 * Argument constraints:
8945 * 1. 0 < CNT < BITS_PER_MP_LIMB
8946 * 2. If the result is to be written over the input, WP must be <= UP.
8947 */
8948
8949 mpi_limb_t
8950 mpihelp_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, unsigned cnt)
8951 {
8952 mpi_limb_t high_limb, low_limb;
8953 unsigned sh_1, sh_2;
8954 mpi_size_t i;
8955 mpi_limb_t retval;
8956
8957 sh_1 = cnt;
8958 wp -= 1;
8959 sh_2 = BITS_PER_MPI_LIMB - sh_1;
8960 high_limb = up[0];
8961 retval = high_limb << sh_2;
8962 low_limb = high_limb;
8963 for( i=1; i < usize; i++) {
8964 high_limb = up[i];
8965 wp[i] = (low_limb >> sh_1) | (high_limb << sh_2);
8966 low_limb = high_limb;
8967 }
8968 wp[i] = low_limb >> sh_1;
8969
8970 return retval;
8971 }
8972
-
+ 1F021E754F091EAC1AB7B46306B00849F7160CFA7CD0CC8A6481020B6D42CB12058CD12AC9E2B1D7F730688FBE2D876374EC9D5BB7A5F9D66A42CC9259CF2539
mpi/mpih-sub1.c
(0 . 0)(1 . 64)
8977 /* mpihelp-add_2.c - MPI helper functions
8978 * Copyright (C) 1994, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
8979 *
8980 * This file is part of GnuPG.
8981 *
8982 * GnuPG is free software; you can redistribute it and/or modify
8983 * it under the terms of the GNU General Public License as published by
8984 * the Free Software Foundation; either version 3 of the License, or
8985 * (at your option) any later version.
8986 *
8987 * GnuPG is distributed in the hope that it will be useful,
8988 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8989 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8990 * GNU General Public License for more details.
8991 *
8992 * You should have received a copy of the GNU General Public License
8993 * along with this program; if not, see <http://www.gnu.org/licenses/>.
8994 *
8995 * Note: This code is heavily based on the GNU MP Library.
8996 * Actually it's the same code with only minor changes in the
8997 * way the data is stored; this is to support the abstraction
8998 * of an optional secure memory allocation which may be used
8999 * to avoid revealing of sensitive data due to paging etc.
9000 * The GNU MP Library itself is published under the LGPL;
9001 * however I decided to publish this code under the plain GPL.
9002 */
9003
9004 #include <config.h>
9005 #include <stdio.h>
9006 #include <stdlib.h>
9007 #include "mpi-internal.h"
9008 #include "longlong.h"
9009
9010 mpi_limb_t
9011 mpihelp_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
9012 mpi_ptr_t s2_ptr, mpi_size_t size)
9013 {
9014 mpi_limb_t x, y, cy;
9015 mpi_size_t j;
9016
9017 /* The loop counter and index J goes from -SIZE to -1. This way
9018 the loop becomes faster. */
9019 j = -size;
9020
9021 /* Offset the base pointers to compensate for the negative indices. */
9022 s1_ptr -= j;
9023 s2_ptr -= j;
9024 res_ptr -= j;
9025
9026 cy = 0;
9027 do {
9028 y = s2_ptr[j];
9029 x = s1_ptr[j];
9030 y += cy; /* add previous carry to subtrahend */
9031 cy = y < cy; /* get out carry from that addition */
9032 y = x - y; /* main subtract */
9033 cy += y > x; /* get out carry from the subtract, combine */
9034 res_ptr[j] = y;
9035 } while( ++j );
9036
9037 return cy;
9038 }
9039
9040
-
+ 22B8E75D35ABC0449E048A2B18461B17D7EF5A6A00A56FE1A16BD89B526B8F6F19DEA196A258D6E3760F84B1124D7D40FA28D1B6C5BC4932BE11B9D91C7077EC
mpi/mpi-inline.c
(0 . 0)(1 . 35)
9045 /* mpi-inline.c
9046 * Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
9047 *
9048 * This file is part of GnuPG.
9049 *
9050 * GnuPG is free software; you can redistribute it and/or modify
9051 * it under the terms of the GNU General Public License as published by
9052 * the Free Software Foundation; either version 3 of the License, or
9053 * (at your option) any later version.
9054 *
9055 * GnuPG is distributed in the hope that it will be useful,
9056 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9057 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9058 * GNU General Public License for more details.
9059 *
9060 * You should have received a copy of the GNU General Public License
9061 * along with this program; if not, see <http://www.gnu.org/licenses/>.
9062 */
9063
9064 #include <config.h>
9065 #include <stdio.h>
9066 #include <stdlib.h>
9067
9068 /* put the inline functions as real functions into the lib */
9069 #define G10_MPI_INLINE_DECL
9070
9071 #include "mpi-internal.h"
9072
9073 /* always include the header becuase it is only
9074 * included by mpi-internal if __GCC__ is defined but we
9075 * need it here in all cases and the above definition of
9076 * of the macro allows us to do so
9077 */
9078 #include "mpi-inline.h"
9079
-
+ 66EDF48A07BB672B7D9329150436A40AB2F1628F1F289B4C52B2E4BDB987B9105F36C441FB21A141346406A675D34B6265A4A0BC00D3C4DE471F461D0ACC5765
mpi/mpi-inv.c
(0 . 0)(1 . 266)
9084 /* mpi-inv.c - MPI functions
9085 * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
9086 *
9087 * This file is part of GnuPG.
9088 *
9089 * GnuPG is free software; you can redistribute it and/or modify
9090 * it under the terms of the GNU General Public License as published by
9091 * the Free Software Foundation; either version 3 of the License, or
9092 * (at your option) any later version.
9093 *
9094 * GnuPG is distributed in the hope that it will be useful,
9095 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9096 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9097 * GNU General Public License for more details.
9098 *
9099 * You should have received a copy of the GNU General Public License
9100 * along with this program; if not, see <http://www.gnu.org/licenses/>.
9101 */
9102
9103 #include <config.h>
9104 #include <stdio.h>
9105 #include <stdlib.h>
9106 #include "mpi-internal.h"
9107
9108
9109 /****************
9110 * Calculate the multiplicative inverse X of A mod N
9111 * That is: Find the solution x for
9112 * 1 = (a*x) mod n
9113 */
9114 void
9115 mpi_invm( MPI x, MPI a, MPI n )
9116 {
9117 #if 0
9118 MPI u, v, u1, u2, u3, v1, v2, v3, q, t1, t2, t3;
9119 MPI ta, tb, tc;
9120
9121 u = mpi_copy(a);
9122 v = mpi_copy(n);
9123 u1 = mpi_alloc_set_ui(1);
9124 u2 = mpi_alloc_set_ui(0);
9125 u3 = mpi_copy(u);
9126 v1 = mpi_alloc_set_ui(0);
9127 v2 = mpi_alloc_set_ui(1);
9128 v3 = mpi_copy(v);
9129 q = mpi_alloc( mpi_get_nlimbs(u)+1 );
9130 t1 = mpi_alloc( mpi_get_nlimbs(u)+1 );
9131 t2 = mpi_alloc( mpi_get_nlimbs(u)+1 );
9132 t3 = mpi_alloc( mpi_get_nlimbs(u)+1 );
9133 while( mpi_cmp_ui( v3, 0 ) ) {
9134 mpi_fdiv_q( q, u3, v3 );
9135 mpi_mul(t1, v1, q); mpi_mul(t2, v2, q); mpi_mul(t3, v3, q);
9136 mpi_sub(t1, u1, t1); mpi_sub(t2, u2, t2); mpi_sub(t3, u3, t3);
9137 mpi_set(u1, v1); mpi_set(u2, v2); mpi_set(u3, v3);
9138 mpi_set(v1, t1); mpi_set(v2, t2); mpi_set(v3, t3);
9139 }
9140 /* log_debug("result:\n");
9141 log_mpidump("q =", q );
9142 log_mpidump("u1=", u1);
9143 log_mpidump("u2=", u2);
9144 log_mpidump("u3=", u3);
9145 log_mpidump("v1=", v1);
9146 log_mpidump("v2=", v2); */
9147 mpi_set(x, u1);
9148
9149 mpi_free(u1);
9150 mpi_free(u2);
9151 mpi_free(u3);
9152 mpi_free(v1);
9153 mpi_free(v2);
9154 mpi_free(v3);
9155 mpi_free(q);
9156 mpi_free(t1);
9157 mpi_free(t2);
9158 mpi_free(t3);
9159 mpi_free(u);
9160 mpi_free(v);
9161 #elif 0
9162 /* Extended Euclid's algorithm (See TAOPC Vol II, 4.5.2, Alg X)
9163 * modified according to Michael Penk's solution for Exercice 35 */
9164
9165 /* FIXME: we can simplify this in most cases (see Knuth) */
9166 MPI u, v, u1, u2, u3, v1, v2, v3, t1, t2, t3;
9167 unsigned k;
9168 int sign;
9169
9170 u = mpi_copy(a);
9171 v = mpi_copy(n);
9172 for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) {
9173 mpi_rshift(u, u, 1);
9174 mpi_rshift(v, v, 1);
9175 }
9176
9177
9178 u1 = mpi_alloc_set_ui(1);
9179 u2 = mpi_alloc_set_ui(0);
9180 u3 = mpi_copy(u);
9181 v1 = mpi_copy(v); /* !-- used as const 1 */
9182 v2 = mpi_alloc( mpi_get_nlimbs(u) ); mpi_sub( v2, u1, u );
9183 v3 = mpi_copy(v);
9184 if( mpi_test_bit(u, 0) ) { /* u is odd */
9185 t1 = mpi_alloc_set_ui(0);
9186 t2 = mpi_alloc_set_ui(1); t2->sign = 1;
9187 t3 = mpi_copy(v); t3->sign = !t3->sign;
9188 goto Y4;
9189 }
9190 else {
9191 t1 = mpi_alloc_set_ui(1);
9192 t2 = mpi_alloc_set_ui(0);
9193 t3 = mpi_copy(u);
9194 }
9195 do {
9196 do {
9197 if( mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0) ) { /* one is odd */
9198 mpi_add(t1, t1, v);
9199 mpi_sub(t2, t2, u);
9200 }
9201 mpi_rshift(t1, t1, 1);
9202 mpi_rshift(t2, t2, 1);
9203 mpi_rshift(t3, t3, 1);
9204 Y4:
9205 ;
9206 } while( !mpi_test_bit( t3, 0 ) ); /* while t3 is even */
9207
9208 if( !t3->sign ) {
9209 mpi_set(u1, t1);
9210 mpi_set(u2, t2);
9211 mpi_set(u3, t3);
9212 }
9213 else {
9214 mpi_sub(v1, v, t1);
9215 sign = u->sign; u->sign = !u->sign;
9216 mpi_sub(v2, u, t2);
9217 u->sign = sign;
9218 sign = t3->sign; t3->sign = !t3->sign;
9219 mpi_set(v3, t3);
9220 t3->sign = sign;
9221 }
9222 mpi_sub(t1, u1, v1);
9223 mpi_sub(t2, u2, v2);
9224 mpi_sub(t3, u3, v3);
9225 if( t1->sign ) {
9226 mpi_add(t1, t1, v);
9227 mpi_sub(t2, t2, u);
9228 }
9229 } while( mpi_cmp_ui( t3, 0 ) ); /* while t3 != 0 */
9230 /* mpi_lshift( u3, k ); */
9231 mpi_set(x, u1);
9232
9233 mpi_free(u1);
9234 mpi_free(u2);
9235 mpi_free(u3);
9236 mpi_free(v1);
9237 mpi_free(v2);
9238 mpi_free(v3);
9239 mpi_free(t1);
9240 mpi_free(t2);
9241 mpi_free(t3);
9242 #else
9243 /* Extended Euclid's algorithm (See TAOPC Vol II, 4.5.2, Alg X)
9244 * modified according to Michael Penk's solution for Exercice 35
9245 * with further enhancement */
9246 MPI u, v, u1, u2=NULL, u3, v1, v2=NULL, v3, t1, t2=NULL, t3;
9247 unsigned k;
9248 int sign;
9249 int odd ;
9250
9251 u = mpi_copy(a);
9252 v = mpi_copy(n);
9253
9254 for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) {
9255 mpi_rshift(u, u, 1);
9256 mpi_rshift(v, v, 1);
9257 }
9258 odd = mpi_test_bit(v,0);
9259
9260 u1 = mpi_alloc_set_ui(1);
9261 if( !odd )
9262 u2 = mpi_alloc_set_ui(0);
9263 u3 = mpi_copy(u);
9264 v1 = mpi_copy(v);
9265 if( !odd ) {
9266 v2 = mpi_alloc( mpi_get_nlimbs(u) );
9267 mpi_sub( v2, u1, u ); /* U is used as const 1 */
9268 }
9269 v3 = mpi_copy(v);
9270 if( mpi_test_bit(u, 0) ) { /* u is odd */
9271 t1 = mpi_alloc_set_ui(0);
9272 if( !odd ) {
9273 t2 = mpi_alloc_set_ui(1); t2->sign = 1;
9274 }
9275 t3 = mpi_copy(v); t3->sign = !t3->sign;
9276 goto Y4;
9277 }
9278 else {
9279 t1 = mpi_alloc_set_ui(1);
9280 if( !odd )
9281 t2 = mpi_alloc_set_ui(0);
9282 t3 = mpi_copy(u);
9283 }
9284 do {
9285 do {
9286 if( !odd ) {
9287 if( mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0) ) { /* one is odd */
9288 mpi_add(t1, t1, v);
9289 mpi_sub(t2, t2, u);
9290 }
9291 mpi_rshift(t1, t1, 1);
9292 mpi_rshift(t2, t2, 1);
9293 mpi_rshift(t3, t3, 1);
9294 }
9295 else {
9296 if( mpi_test_bit(t1, 0) )
9297 mpi_add(t1, t1, v);
9298 mpi_rshift(t1, t1, 1);
9299 mpi_rshift(t3, t3, 1);
9300 }
9301 Y4:
9302 ;
9303 } while( !mpi_test_bit( t3, 0 ) ); /* while t3 is even */
9304
9305 if( !t3->sign ) {
9306 mpi_set(u1, t1);
9307 if( !odd )
9308 mpi_set(u2, t2);
9309 mpi_set(u3, t3);
9310 }
9311 else {
9312 mpi_sub(v1, v, t1);
9313 sign = u->sign; u->sign = !u->sign;
9314 if( !odd )
9315 mpi_sub(v2, u, t2);
9316 u->sign = sign;
9317 sign = t3->sign; t3->sign = !t3->sign;
9318 mpi_set(v3, t3);
9319 t3->sign = sign;
9320 }
9321 mpi_sub(t1, u1, v1);
9322 if( !odd )
9323 mpi_sub(t2, u2, v2);
9324 mpi_sub(t3, u3, v3);
9325 if( t1->sign ) {
9326 mpi_add(t1, t1, v);
9327 if( !odd )
9328 mpi_sub(t2, t2, u);
9329 }
9330 } while( mpi_cmp_ui( t3, 0 ) ); /* while t3 != 0 */
9331 /* mpi_lshift( u3, k ); */
9332 mpi_set(x, u1);
9333
9334 mpi_free(u1);
9335 mpi_free(v1);
9336 mpi_free(t1);
9337 if( !odd ) {
9338 mpi_free(u2);
9339 mpi_free(v2);
9340 mpi_free(t2);
9341 }
9342 mpi_free(u3);
9343 mpi_free(v3);
9344 mpi_free(t3);
9345
9346 mpi_free(u);
9347 mpi_free(v);
9348 #endif
9349 }
-
+ A87EBB2E2397F5903EAA0066A9ADF8F977BF7A67866CD181D0699B6D6A029880D86F349BE9CB9E6901D35B052BD871380E18AB19EFCF319C8A3662A93691856E
mpi/mpi-mpow.c
(0 . 0)(1 . 98)
9354 /* mpi-mpow.c - MPI functions
9355 * Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
9356 *
9357 * This file is part of GnuPG.
9358 *
9359 * GnuPG is free software; you can redistribute it and/or modify
9360 * it under the terms of the GNU General Public License as published by
9361 * the Free Software Foundation; either version 3 of the License, or
9362 * (at your option) any later version.
9363 *
9364 * GnuPG is distributed in the hope that it will be useful,
9365 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9366 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9367 * GNU General Public License for more details.
9368 *
9369 * You should have received a copy of the GNU General Public License
9370 * along with this program; if not, see <http://www.gnu.org/licenses/>.
9371 */
9372
9373 #include <config.h>
9374 #include <stdio.h>
9375 #include <stdlib.h>
9376 #include "mpi-internal.h"
9377 #include "longlong.h"
9378 #include <assert.h>
9379
9380 static int
9381 build_index( MPI *exparray, int k, int i, int t )
9382 {
9383 int j, bitno;
9384 int idx = 0;
9385
9386 bitno = t-i;
9387 for(j=k-1; j >= 0; j-- ) {
9388 idx <<= 1;
9389 if( mpi_test_bit( exparray[j], bitno ) )
9390 idx |= 1;
9391 }
9392 return idx;
9393 }
9394
9395 /****************
9396 * RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M
9397 */
9398 void
9399 mpi_mulpowm( MPI res, MPI *basearray, MPI *exparray, MPI m)
9400 {
9401 int k; /* number of elements */
9402 int t; /* bit size of largest exponent */
9403 int i, j, idx;
9404 MPI *G; /* table with precomputed values of size 2^k */
9405 MPI tmp;
9406
9407 for(k=0; basearray[k]; k++ )
9408 ;
9409 assert(k);
9410 for(t=0, i=0; (tmp=exparray[i]); i++ ) {
9411 j = mpi_get_nbits(tmp);
9412 if( j > t )
9413 t = j;
9414 }
9415 assert(i==k);
9416 assert(t);
9417 assert( k < 10 );
9418
9419 G = xmalloc_clear( (1<<k) * sizeof *G );
9420 /* and calculate */
9421 tmp = mpi_alloc( mpi_get_nlimbs(m)+1 );
9422 mpi_set_ui( res, 1 );
9423 for(i = 1; i <= t; i++ ) {
9424 mpi_mulm(tmp, res, res, m );
9425 idx = build_index( exparray, k, i, t );
9426 assert( idx >= 0 && idx < (1<<k) );
9427 if( !G[idx] ) {
9428 if( !idx )
9429 G[0] = mpi_alloc_set_ui( 1 );
9430 else {
9431 for(j=0; j < k; j++ ) {
9432 if( (idx & (1<<j) ) ) {
9433 if( !G[idx] )
9434 G[idx] = mpi_copy( basearray[j] );
9435 else
9436 mpi_mulm( G[idx], G[idx], basearray[j], m );
9437 }
9438 }
9439 if( !G[idx] )
9440 G[idx] = mpi_alloc(0);
9441 }
9442 }
9443 mpi_mulm(res, tmp, G[idx], m );
9444 }
9445
9446 /* cleanup */
9447 mpi_free(tmp);
9448 for(i=0; i < (1<<k); i++ )
9449 mpi_free(G[i]);
9450 xfree(G);
9451 }
-
+ 8A56ADB14BCAC8D72E4454562A0455C241756EDE576D2CD4E8A42CFDFF5ABE7C803A5F1523945EE81D5A149B88D969739443D00165FDAAB7041BAC9BE10DC8CF
mpi/mpi-mul.c
(0 . 0)(1 . 214)
9456 /* mpi-mul.c - MPI functions
9457 * Copyright (C) 1994, 1996 Free Software Foundation, Inc.
9458 * Copyright (C) 1998, 2001 Free Software Foundation, Inc.
9459 *
9460 * This file is part of GnuPG.
9461 *
9462 * GnuPG is free software; you can redistribute it and/or modify
9463 * it under the terms of the GNU General Public License as published by
9464 * the Free Software Foundation; either version 3 of the License, or
9465 * (at your option) any later version.
9466 *
9467 * GnuPG is distributed in the hope that it will be useful,
9468 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9469 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9470 * GNU General Public License for more details.
9471 *
9472 * You should have received a copy of the GNU General Public License
9473 * along with this program; if not, see <http://www.gnu.org/licenses/>.
9474 *
9475 * Note: This code is heavily based on the GNU MP Library.
9476 * Actually it's the same code with only minor changes in the
9477 * way the data is stored; this is to support the abstraction
9478 * of an optional secure memory allocation which may be used
9479 * to avoid revealing of sensitive data due to paging etc.
9480 * The GNU MP Library itself is published under the LGPL;
9481 * however I decided to publish this code under the plain GPL.
9482 */
9483
9484 #include <config.h>
9485 #include <stdio.h>
9486 #include <stdlib.h>
9487 #include "mpi-internal.h"
9488
9489
9490 void
9491 mpi_mul_ui( MPI prod, MPI mult, unsigned long small_mult )
9492 {
9493 mpi_size_t size, prod_size;
9494 mpi_ptr_t prod_ptr;
9495 mpi_limb_t cy;
9496 int sign;
9497
9498 size = mult->nlimbs;
9499 sign = mult->sign;
9500
9501 if( !size || !small_mult ) {
9502 prod->nlimbs = 0;
9503 prod->sign = 0;
9504 return;
9505 }
9506
9507 prod_size = size + 1;
9508 if( prod->alloced < prod_size )
9509 mpi_resize( prod, prod_size );
9510 prod_ptr = prod->d;
9511
9512 cy = mpihelp_mul_1( prod_ptr, mult->d, size, (mpi_limb_t)small_mult );
9513 if( cy )
9514 prod_ptr[size++] = cy;
9515 prod->nlimbs = size;
9516 prod->sign = sign;
9517 }
9518
9519
9520 void
9521 mpi_mul_2exp( MPI w, MPI u, unsigned long cnt)
9522 {
9523 mpi_size_t usize, wsize, limb_cnt;
9524 mpi_ptr_t wp;
9525 mpi_limb_t wlimb;
9526 int usign, wsign;
9527
9528 usize = u->nlimbs;
9529 usign = u->sign;
9530
9531 if( !usize ) {
9532 w->nlimbs = 0;
9533 w->sign = 0;
9534 return;
9535 }
9536
9537 limb_cnt = cnt / BITS_PER_MPI_LIMB;
9538 wsize = usize + limb_cnt + 1;
9539 if( w->alloced < wsize )
9540 mpi_resize(w, wsize );
9541 wp = w->d;
9542 wsize = usize + limb_cnt;
9543 wsign = usign;
9544
9545 cnt %= BITS_PER_MPI_LIMB;
9546 if( cnt ) {
9547 wlimb = mpihelp_lshift( wp + limb_cnt, u->d, usize, cnt );
9548 if( wlimb ) {
9549 wp[wsize] = wlimb;
9550 wsize++;
9551 }
9552 }
9553 else {
9554 MPN_COPY_DECR( wp + limb_cnt, u->d, usize );
9555 }
9556
9557 /* Zero all whole limbs at low end. Do it here and not before calling
9558 * mpn_lshift, not to lose for U == W. */
9559 MPN_ZERO( wp, limb_cnt );
9560
9561 w->nlimbs = wsize;
9562 w->sign = wsign;
9563 }
9564
9565
9566
9567 void
9568 mpi_mul( MPI w, MPI u, MPI v)
9569 {
9570 mpi_size_t usize, vsize, wsize;
9571 mpi_ptr_t up, vp, wp;
9572 mpi_limb_t cy;
9573 int usign, vsign, usecure, vsecure, sign_product;
9574 int assign_wp=0;
9575 mpi_ptr_t tmp_limb=NULL;
9576
9577
9578 if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
9579 usize = v->nlimbs;
9580 usign = v->sign;
9581 usecure = mpi_is_secure(v);
9582 up = v->d;
9583 vsize = u->nlimbs;
9584 vsign = u->sign;
9585 vsecure = mpi_is_secure(u);
9586 vp = u->d;
9587 }
9588 else {
9589 usize = u->nlimbs;
9590 usign = u->sign;
9591 usecure = mpi_is_secure(u);
9592 up = u->d;
9593 vsize = v->nlimbs;
9594 vsign = v->sign;
9595 vsecure = mpi_is_secure(v);
9596 vp = v->d;
9597 }
9598 sign_product = usign ^ vsign;
9599 wp = w->d;
9600
9601 /* Ensure W has space enough to store the result. */
9602 wsize = usize + vsize;
9603 if ( !mpi_is_secure (w) && (mpi_is_secure (u) || mpi_is_secure (v)) ) {
9604 /* w is not allocated in secure space but u or v is. To make sure
9605 * that no temporray results are stored in w, we temporary use
9606 * a newly allocated limb space for w */
9607 wp = mpi_alloc_limb_space( wsize, 1 );
9608 assign_wp = 2; /* mark it as 2 so that we can later copy it back to
9609 * mormal memory */
9610 }
9611 else if( w->alloced < wsize ) {
9612 if( wp == up || wp == vp ) {
9613 wp = mpi_alloc_limb_space( wsize, mpi_is_secure(w) );
9614 assign_wp = 1;
9615 }
9616 else {
9617 mpi_resize(w, wsize );
9618 wp = w->d;
9619 }
9620 }
9621 else { /* Make U and V not overlap with W. */
9622 if( wp == up ) {
9623 /* W and U are identical. Allocate temporary space for U. */
9624 up = tmp_limb = mpi_alloc_limb_space( usize, usecure );
9625 /* Is V identical too? Keep it identical with U. */
9626 if( wp == vp )
9627 vp = up;
9628 /* Copy to the temporary space. */
9629 MPN_COPY( up, wp, usize );
9630 }
9631 else if( wp == vp ) {
9632 /* W and V are identical. Allocate temporary space for V. */
9633 vp = tmp_limb = mpi_alloc_limb_space( vsize, vsecure );
9634 /* Copy to the temporary space. */
9635 MPN_COPY( vp, wp, vsize );
9636 }
9637 }
9638
9639 if( !vsize )
9640 wsize = 0;
9641 else {
9642 cy = mpihelp_mul( wp, up, usize, vp, vsize );
9643 wsize -= cy? 0:1;
9644 }
9645
9646 if( assign_wp ) {
9647 if (assign_wp == 2) {
9648 /* copy the temp wp from secure memory back to normal memory */
9649 mpi_ptr_t tmp_wp = mpi_alloc_limb_space (wsize, 0);
9650 MPN_COPY (tmp_wp, wp, wsize);
9651 mpi_free_limb_space (wp);
9652 wp = tmp_wp;
9653 }
9654 mpi_assign_limb_space( w, wp, wsize );
9655 }
9656 w->nlimbs = wsize;
9657 w->sign = sign_product;
9658 if( tmp_limb )
9659 mpi_free_limb_space( tmp_limb );
9660 }
9661
9662
9663 void
9664 mpi_mulm( MPI w, MPI u, MPI v, MPI m)
9665 {
9666 mpi_mul(w, u, v);
9667 mpi_fdiv_r( w, w, m );
9668 }
9669
-
+ 8341923461226EC55DE5B29209CC03051587DE11885CB49433FF4C0EBA2160798B7DC27573B9BC363EE0954A8FC08CBD21AF3F655A9C0BC8AA294A74F80EB2C9
mpi/mpi-pow.c
(0 . 0)(1 . 294)
9674 /* mpi-pow.c - MPI functions
9675 * Copyright (C) 1994, 1996, 1998, 2000 Free Software Foundation, Inc.
9676 *
9677 * This file is part of GnuPG.
9678 *
9679 * GnuPG is free software; you can redistribute it and/or modify
9680 * it under the terms of the GNU General Public License as published by
9681 * the Free Software Foundation; either version 3 of the License, or
9682 * (at your option) any later version.
9683 *
9684 * GnuPG is distributed in the hope that it will be useful,
9685 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9686 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9687 * GNU General Public License for more details.
9688 *
9689 * You should have received a copy of the GNU General Public License
9690 * along with this program; if not, see <http://www.gnu.org/licenses/>.
9691 *
9692 * Note: This code is heavily based on the GNU MP Library.
9693 * Actually it's the same code with only minor changes in the
9694 * way the data is stored; this is to support the abstraction
9695 * of an optional secure memory allocation which may be used
9696 * to avoid revealing of sensitive data due to paging etc.
9697 * The GNU MP Library itself is published under the LGPL;
9698 * however I decided to publish this code under the plain GPL.
9699 */
9700
9701 #include <config.h>
9702 #include <stdio.h>
9703 #include <stdlib.h>
9704 #include <string.h>
9705 #include "mpi-internal.h"
9706 #include "longlong.h"
9707 #include <assert.h>
9708
9709
9710 /****************
9711 * RES = BASE ^ EXP mod MOD
9712 */
9713 void
9714 mpi_powm( MPI res, MPI base, MPI exponent, MPI mod)
9715 {
9716 mpi_ptr_t rp, ep, mp, bp;
9717 mpi_size_t esize, msize, bsize, rsize;
9718 int esign, msign, bsign, rsign;
9719 int esec, msec, bsec, rsec;
9720 mpi_size_t size;
9721 int mod_shift_cnt;
9722 int negative_result;
9723 mpi_ptr_t mp_marker=NULL, bp_marker=NULL, ep_marker=NULL;
9724 mpi_ptr_t xp_marker=NULL;
9725 int assign_rp=0;
9726 mpi_ptr_t tspace = NULL;
9727 mpi_size_t tsize=0; /* to avoid compiler warning */
9728 /* fixme: we should check that the warning is void*/
9729
9730 esize = exponent->nlimbs;
9731 msize = mod->nlimbs;
9732 size = 2 * msize;
9733 esign = exponent->sign;
9734 msign = mod->sign;
9735
9736 esec = mpi_is_secure(exponent);
9737 msec = mpi_is_secure(mod);
9738 bsec = mpi_is_secure(base);
9739 rsec = mpi_is_secure(res);
9740
9741 rp = res->d;
9742 ep = exponent->d;
9743
9744 if( !msize )
9745 msize = 1 / msize; /* provoke a signal */
9746
9747 if( !esize ) {
9748 /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0
9749 * depending on if MOD equals 1. */
9750 rp[0] = 1;
9751 res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
9752 res->sign = 0;
9753 goto leave;
9754 }
9755
9756 /* Normalize MOD (i.e. make its most significant bit set) as required by
9757 * mpn_divrem. This will make the intermediate values in the calculation
9758 * slightly larger, but the correct result is obtained after a final
9759 * reduction using the original MOD value. */
9760 mp = mp_marker = mpi_alloc_limb_space(msize, msec);
9761 count_leading_zeros( mod_shift_cnt, mod->d[msize-1] );
9762 if( mod_shift_cnt )
9763 mpihelp_lshift( mp, mod->d, msize, mod_shift_cnt );
9764 else
9765 MPN_COPY( mp, mod->d, msize );
9766
9767 bsize = base->nlimbs;
9768 bsign = base->sign;
9769 if( bsize > msize ) { /* The base is larger than the module. Reduce it. */
9770 /* Allocate (BSIZE + 1) with space for remainder and quotient.
9771 * (The quotient is (bsize - msize + 1) limbs.) */
9772 bp = bp_marker = mpi_alloc_limb_space( bsize + 1, bsec );
9773 MPN_COPY( bp, base->d, bsize );
9774 /* We don't care about the quotient, store it above the remainder,
9775 * at BP + MSIZE. */
9776 mpihelp_divrem( bp + msize, 0, bp, bsize, mp, msize );
9777 bsize = msize;
9778 /* Canonicalize the base, since we are going to multiply with it
9779 * quite a few times. */
9780 MPN_NORMALIZE( bp, bsize );
9781 }
9782 else
9783 bp = base->d;
9784
9785 if( !bsize ) {
9786 res->nlimbs = 0;
9787 res->sign = 0;
9788 goto leave;
9789 }
9790
9791 if( res->alloced < size ) {
9792 /* We have to allocate more space for RES. If any of the input
9793 * parameters are identical to RES, defer deallocation of the old
9794 * space. */
9795 if( rp == ep || rp == mp || rp == bp ) {
9796 rp = mpi_alloc_limb_space( size, rsec );
9797 assign_rp = 1;
9798 }
9799 else {
9800 mpi_resize( res, size );
9801 rp = res->d;
9802 }
9803 }
9804 else { /* Make BASE, EXPONENT and MOD not overlap with RES. */
9805 if( rp == bp ) {
9806 /* RES and BASE are identical. Allocate temp. space for BASE. */
9807 assert( !bp_marker );
9808 bp = bp_marker = mpi_alloc_limb_space( bsize, bsec );
9809 MPN_COPY(bp, rp, bsize);
9810 }
9811 if( rp == ep ) {
9812 /* RES and EXPONENT are identical.
9813 Allocate temp. space for EXPONENT. */
9814 ep = ep_marker = mpi_alloc_limb_space( esize, esec );
9815 MPN_COPY(ep, rp, esize);
9816 }
9817 if( rp == mp ) {
9818 /* RES and MOD are identical. Allocate temporary space for MOD.*/
9819 assert( !mp_marker );
9820 mp = mp_marker = mpi_alloc_limb_space( msize, msec );
9821 MPN_COPY(mp, rp, msize);
9822 }
9823 }
9824
9825 MPN_COPY( rp, bp, bsize );
9826 rsize = bsize;
9827 rsign = bsign;
9828
9829 {
9830 mpi_size_t i;
9831 mpi_ptr_t xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
9832 int c;
9833 mpi_limb_t e;
9834 mpi_limb_t carry_limb;
9835 struct karatsuba_ctx karactx;
9836
9837 memset( &karactx, 0, sizeof karactx );
9838 negative_result = (ep[0] & 1) && base->sign;
9839
9840 i = esize - 1;
9841 e = ep[i];
9842 count_leading_zeros (c, e);
9843 e = (e << c) << 1; /* shift the exp bits to the left, lose msb */
9844 c = BITS_PER_MPI_LIMB - 1 - c;
9845
9846 /* Main loop.
9847 *
9848 * Make the result be pointed to alternately by XP and RP. This
9849 * helps us avoid block copying, which would otherwise be necessary
9850 * with the overlap restrictions of mpihelp_divmod. With 50% probability
9851 * the result after this loop will be in the area originally pointed
9852 * by RP (==RES->d), and with 50% probability in the area originally
9853 * pointed to by XP.
9854 */
9855
9856 for(;;) {
9857 while( c ) {
9858 mpi_ptr_t tp;
9859 mpi_size_t xsize;
9860
9861 /*mpihelp_mul_n(xp, rp, rp, rsize);*/
9862 if( rsize < KARATSUBA_THRESHOLD )
9863 mpih_sqr_n_basecase( xp, rp, rsize );
9864 else {
9865 if( !tspace ) {
9866 tsize = 2 * rsize;
9867 tspace = mpi_alloc_limb_space( tsize, 0 );
9868 }
9869 else if( tsize < (2*rsize) ) {
9870 mpi_free_limb_space( tspace );
9871 tsize = 2 * rsize;
9872 tspace = mpi_alloc_limb_space( tsize, 0 );
9873 }
9874 mpih_sqr_n( xp, rp, rsize, tspace );
9875 }
9876
9877 xsize = 2 * rsize;
9878 if( xsize > msize ) {
9879 mpihelp_divrem(xp + msize, 0, xp, xsize, mp, msize);
9880 xsize = msize;
9881 }
9882
9883 tp = rp; rp = xp; xp = tp;
9884 rsize = xsize;
9885
9886 if( (mpi_limb_signed_t)e < 0 ) {
9887 /*mpihelp_mul( xp, rp, rsize, bp, bsize );*/
9888 if( bsize < KARATSUBA_THRESHOLD ) {
9889 mpihelp_mul( xp, rp, rsize, bp, bsize );
9890 }
9891 else {
9892 mpihelp_mul_karatsuba_case(
9893 xp, rp, rsize, bp, bsize, &karactx );
9894 }
9895
9896 xsize = rsize + bsize;
9897 if( xsize > msize ) {
9898 mpihelp_divrem(xp + msize, 0, xp, xsize, mp, msize);
9899 xsize = msize;
9900 }
9901
9902 tp = rp; rp = xp; xp = tp;
9903 rsize = xsize;
9904 }
9905 e <<= 1;
9906 c--;
9907 }
9908
9909 i--;
9910 if( i < 0 )
9911 break;
9912 e = ep[i];
9913 c = BITS_PER_MPI_LIMB;
9914 }
9915
9916 /* We shifted MOD, the modulo reduction argument, left MOD_SHIFT_CNT
9917 * steps. Adjust the result by reducing it with the original MOD.
9918 *
9919 * Also make sure the result is put in RES->d (where it already
9920 * might be, see above).
9921 */
9922 if( mod_shift_cnt ) {
9923 carry_limb = mpihelp_lshift( res->d, rp, rsize, mod_shift_cnt);
9924 rp = res->d;
9925 if( carry_limb ) {
9926 rp[rsize] = carry_limb;
9927 rsize++;
9928 }
9929 }
9930 else {
9931 MPN_COPY( res->d, rp, rsize);
9932 rp = res->d;
9933 }
9934
9935 if( rsize >= msize ) {
9936 mpihelp_divrem(rp + msize, 0, rp, rsize, mp, msize);
9937 rsize = msize;
9938 }
9939
9940 /* Remove any leading zero words from the result. */
9941 if( mod_shift_cnt )
9942 mpihelp_rshift( rp, rp, rsize, mod_shift_cnt);
9943 MPN_NORMALIZE (rp, rsize);
9944
9945 mpihelp_release_karatsuba_ctx( &karactx );
9946 }
9947
9948 if( negative_result && rsize ) {
9949 if( mod_shift_cnt )
9950 mpihelp_rshift( mp, mp, msize, mod_shift_cnt);
9951 mpihelp_sub( rp, mp, msize, rp, rsize);
9952 rsize = msize;
9953 rsign = msign;
9954 MPN_NORMALIZE(rp, rsize);
9955 }
9956 res->nlimbs = rsize;
9957 res->sign = rsign;
9958
9959 leave:
9960 if( assign_rp ) mpi_assign_limb_space( res, rp, size );
9961 if( mp_marker ) mpi_free_limb_space( mp_marker );
9962 if( bp_marker ) mpi_free_limb_space( bp_marker );
9963 if( ep_marker ) mpi_free_limb_space( ep_marker );
9964 if( xp_marker ) mpi_free_limb_space( xp_marker );
9965 if( tspace ) mpi_free_limb_space( tspace );
9966 }
9967
-
+ AFFA0E93E6625CAD75CD10C454B493CBEBF061AECA3185E45B6571A26AE10F03947A1EF363C0898609F95CC737053E45A73926B22F14F4EC6A800410915D3FF9
mpi/mpi-scan.c
(0 . 0)(1 . 138)
9972 /* mpi-scan.c - MPI functions
9973 * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
9974 *
9975 * This file is part of GnuPG.
9976 *
9977 * GnuPG is free software; you can redistribute it and/or modify
9978 * it under the terms of the GNU General Public License as published by
9979 * the Free Software Foundation; either version 3 of the License, or
9980 * (at your option) any later version.
9981 *
9982 * GnuPG is distributed in the hope that it will be useful,
9983 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9984 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9985 * GNU General Public License for more details.
9986 *
9987 * You should have received a copy of the GNU General Public License
9988 * along with this program; if not, see <http://www.gnu.org/licenses/>.
9989 */
9990
9991 #include <config.h>
9992 #include <stdio.h>
9993 #include <stdlib.h>
9994 #include "mpi-internal.h"
9995 #include "longlong.h"
9996
9997 /****************
9998 * Scan through an mpi and return byte for byte. a -1 is returned to indicate
9999 * the end of the mpi. Scanning is done from the lsb to the msb, returned
10000 * values are in the range of 0 .. 255.
10001 *
10002 * FIXME: This code is VERY ugly!
10003 */
10004 #if 0 /* Code is not used */
10005 int
10006 mpi_getbyte( MPI a, unsigned idx )
10007 {
10008 int i, j;
10009 unsigned n;
10010 mpi_ptr_t ap;
10011 mpi_limb_t limb;
10012
10013 ap = a->d;
10014 for(n=0,i=0; i < a->nlimbs; i++ ) {
10015 limb = ap[i];
10016 for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
10017 if( n == idx )
10018 return (limb >> j*8) & 0xff;
10019 }
10020 return -1;
10021 }
10022 #endif /* Code is not used */
10023
10024
10025 /****************
10026 * Put a value at position IDX into A. idx counts from lsb to msb
10027 */
10028 /* FIXME: There is a problem with the long constants which should have
10029 a LL prefix or better the macros we use at other places. */
10030 #if 0 /* Code is not used */
10031 void
10032 mpi_putbyte( MPI a, unsigned idx, int xc )
10033 {
10034
10035 int i, j;
10036 unsigned n;
10037 mpi_ptr_t ap;
10038 mpi_limb_t limb, c;
10039
10040 c = xc & 0xff;
10041 ap = a->d;
10042 for(n=0,i=0; i < a->alloced; i++ ) {
10043 limb = ap[i];
10044 for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
10045 if( n == idx ) {
10046 #if BYTES_PER_MPI_LIMB == 4
10047 if( j == 0 )
10048 limb = (limb & 0xffffff00) | c;
10049 else if( j == 1 )
10050 limb = (limb & 0xffff00ff) | (c<<8);
10051 else if( j == 2 )
10052 limb = (limb & 0xff00ffff) | (c<<16);
10053 else
10054 limb = (limb & 0x00ffffff) | (c<<24);
10055 #elif BYTES_PER_MPI_LIMB == 8
10056 if( j == 0 )
10057 limb = (limb & 0xffffffffffffff00) | c;
10058 else if( j == 1 )
10059 limb = (limb & 0xffffffffffff00ff) | (c<<8);
10060 else if( j == 2 )
10061 limb = (limb & 0xffffffffff00ffff) | (c<<16);
10062 else if( j == 3 )
10063 limb = (limb & 0xffffffff00ffffff) | (c<<24);
10064 else if( j == 4 )
10065 limb = (limb & 0xffffff00ffffffff) | (c<<32);
10066 else if( j == 5 )
10067 limb = (limb & 0xffff00ffffffffff) | (c<<40);
10068 else if( j == 6 )
10069 limb = (limb & 0xff00ffffffffffff) | (c<<48);
10070 else
10071 limb = (limb & 0x00ffffffffffffff) | (c<<56);
10072 #else
10073 #error please enhance this function, its ugly - i know.
10074 #endif
10075 if( a->nlimbs <= i )
10076 a->nlimbs = i+1;
10077 ap[i] = limb;
10078 return;
10079 }
10080 }
10081 abort(); /* index out of range */
10082 }
10083 #endif /* Code is not used */
10084
10085
10086 /****************
10087 * Count the number of zerobits at the low end of A
10088 */
10089 unsigned int
10090 mpi_trailing_zeros( MPI a )
10091 {
10092 unsigned n, count = 0;
10093
10094 for(n=0; n < a->nlimbs; n++ ) {
10095 if( a->d[n] ) {
10096 unsigned nn;
10097 mpi_limb_t alimb = a->d[n];
10098
10099 count_trailing_zeros( nn, alimb );
10100 count += nn;
10101 break;
10102 }
10103 count += BITS_PER_MPI_LIMB;
10104 }
10105 return count;
10106
10107 }
10108
10109
-
+ 757F8A9FFA7640843ABC7A20EE7F0460FAE4CB11A2928963C85399B7EA7ABA3332F5C1574E86DAB4BBA8384E5BF3F95161C1D1E15DB7B85BB96F369F1E67F6FA
mpi/mpiutil.c
(0 . 0)(1 . 505)
10114 /* mpiutil.ac - Utility functions for MPI
10115 * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
10116 *
10117 * This file is part of GnuPG.
10118 *
10119 * GnuPG is free software; you can redistribute it and/or modify
10120 * it under the terms of the GNU General Public License as published by
10121 * the Free Software Foundation; either version 3 of the License, or
10122 * (at your option) any later version.
10123 *
10124 * GnuPG is distributed in the hope that it will be useful,
10125 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10126 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10127 * GNU General Public License for more details.
10128 *
10129 * You should have received a copy of the GNU General Public License
10130 * along with this program; if not, see <http://www.gnu.org/licenses/>.
10131 */
10132
10133 #include <config.h>
10134 #include <stdio.h>
10135 #include <stdlib.h>
10136 #include <string.h>
10137 #include <assert.h>
10138
10139 #include "mpi.h"
10140 #include "mpi-internal.h"
10141 #include "memory.h"
10142 #include "util.h"
10143
10144
10145 #ifdef M_DEBUG
10146 #undef mpi_alloc
10147 #undef mpi_alloc_secure
10148 #undef mpi_free
10149 #endif
10150
10151 /****************
10152 * Note: It was a bad idea to use the number of limbs to allocate
10153 * because on a alpha the limbs are large but we normally need
10154 * integers of n bits - So we should chnage this to bits (or bytes).
10155 *
10156 * But mpi_alloc is used in a lot of places :-)
10157 */
10158 MPI
10159 #ifdef M_DEBUG
10160 mpi_debug_alloc( unsigned nlimbs, const char *info )
10161 #else
10162 mpi_alloc( unsigned nlimbs )
10163 #endif
10164 {
10165 MPI a;
10166
10167 if( DBG_MEMORY )
10168 log_debug("mpi_alloc(%u)\n", nlimbs*BITS_PER_MPI_LIMB );
10169 #ifdef M_DEBUG
10170 a = m_debug_alloc( sizeof *a, info );
10171 a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 0, info ) : NULL;
10172 #else
10173 a = xmalloc( sizeof *a );
10174 a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
10175 #endif
10176 a->alloced = nlimbs;
10177 a->nlimbs = 0;
10178 a->sign = 0;
10179 a->flags = 0;
10180 a->nbits = 0;
10181 return a;
10182 }
10183
10184 void
10185 mpi_m_check( MPI a )
10186 {
10187 m_check(a);
10188 m_check(a->d);
10189 }
10190
10191 MPI
10192 #ifdef M_DEBUG
10193 mpi_debug_alloc_secure( unsigned nlimbs, const char *info )
10194 #else
10195 mpi_alloc_secure( unsigned nlimbs )
10196 #endif
10197 {
10198 MPI a;
10199
10200 if( DBG_MEMORY )
10201 log_debug("mpi_alloc_secure(%u)\n", nlimbs*BITS_PER_MPI_LIMB );
10202 #ifdef M_DEBUG
10203 a = m_debug_alloc( sizeof *a, info );
10204 a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 1, info ) : NULL;
10205 #else
10206 a = xmalloc( sizeof *a );
10207 a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
10208 #endif
10209 a->alloced = nlimbs;
10210 a->flags = 1;
10211 a->nlimbs = 0;
10212 a->sign = 0;
10213 a->nbits = 0;
10214 return a;
10215 }
10216
10217
10218 #if 0
10219 static void *unused_limbs_5;
10220 static void *unused_limbs_32;
10221 static void *unused_limbs_64;
10222 #endif
10223
10224 mpi_ptr_t
10225 #ifdef M_DEBUG
10226 mpi_debug_alloc_limb_space( unsigned nlimbs, int secure, const char *info )
10227 #else
10228 mpi_alloc_limb_space( unsigned nlimbs, int secure )
10229 #endif
10230 {
10231 size_t len = nlimbs * sizeof(mpi_limb_t);
10232 mpi_ptr_t p;
10233
10234 if( DBG_MEMORY )
10235 log_debug("mpi_alloc_limb_space(%u)\n", (unsigned)len*8 );
10236 #if 0
10237 if( !secure ) {
10238 if( nlimbs == 5 && unused_limbs_5 ) { /* DSA 160 bits */
10239 p = unused_limbs_5;
10240 unused_limbs_5 = *p;
10241 return p;
10242 }
10243 else if( nlimbs == 32 && unused_limbs_32 ) { /* DSA 1024 bits */
10244 p = unused_limbs_32;
10245 unused_limbs_32 = *p;
10246 return p;
10247 }
10248 else if( nlimbs == 64 && unused_limbs_64 ) { /* DSA 2*1024 bits */
10249 p = unused_limbs_64;
10250 unused_limbs_64 = *p;
10251 return p;
10252 }
10253 }
10254 #endif
10255
10256 #ifdef M_DEBUG
10257 p = secure? m_debug_alloc_secure(len, info):m_debug_alloc( len, info );
10258 #else
10259 p = secure? xmalloc_secure( len ):xmalloc( len );
10260 #endif
10261
10262 return p;
10263 }
10264
10265 void
10266 #ifdef M_DEBUG
10267 mpi_debug_free_limb_space( mpi_ptr_t a, const char *info )
10268 #else
10269 mpi_free_limb_space( mpi_ptr_t a )
10270 #endif
10271 {
10272 if( !a )
10273 return;
10274 if( DBG_MEMORY )
10275 log_debug("mpi_free_limb_space of size %lu\n", (ulong)m_size(a)*8 );
10276
10277 #if 0
10278 if( !m_is_secure(a) ) {
10279 size_t nlimbs = m_size(a) / 4 ;
10280 void *p = a;
10281
10282 if( nlimbs == 5 ) { /* DSA 160 bits */
10283 *a = unused_limbs_5;
10284 unused_limbs_5 = a;
10285 return;
10286 }
10287 else if( nlimbs == 32 ) { /* DSA 1024 bits */
10288 *a = unused_limbs_32;
10289 unused_limbs_32 = a;
10290 return;
10291 }
10292 else if( nlimbs == 64 ) { /* DSA 2*1024 bits */
10293 *a = unused_limbs_64;
10294 unused_limbs_64 = a;
10295 return;
10296 }
10297 }
10298 #endif
10299
10300 xfree(a);
10301 }
10302
10303
10304 void
10305 mpi_assign_limb_space( MPI a, mpi_ptr_t ap, unsigned nlimbs )
10306 {
10307 mpi_free_limb_space(a->d);
10308 a->d = ap;
10309 a->alloced = nlimbs;
10310 }
10311
10312
10313
10314 /****************
10315 * Resize the array of A to NLIMBS. the additional space is cleared
10316 * (set to 0) [done by xrealloc()]
10317 */
10318 void
10319 #ifdef M_DEBUG
10320 mpi_debug_resize( MPI a, unsigned nlimbs, const char *info )
10321 #else
10322 mpi_resize( MPI a, unsigned nlimbs )
10323 #endif
10324 {
10325 if( nlimbs <= a->alloced )
10326 return; /* no need to do it */
10327 /* Note: a->secure is not used - instead the realloc functions
10328 * take care of it. Maybe we should drop a->secure completely
10329 * and rely on a mpi_is_secure function, which would be
10330 * a wrapper around m_is_secure
10331 */
10332 #ifdef M_DEBUG
10333 if( a->d )
10334 a->d = m_debug_realloc(a->d, nlimbs * sizeof(mpi_limb_t), info );
10335 else
10336 a->d = m_debug_alloc_clear( nlimbs * sizeof(mpi_limb_t), info );
10337 #else
10338 if( a->d )
10339 a->d = xrealloc(a->d, nlimbs * sizeof(mpi_limb_t) );
10340 else
10341 a->d = xmalloc_clear( nlimbs * sizeof(mpi_limb_t) );
10342 #endif
10343 a->alloced = nlimbs;
10344 }
10345
10346 void
10347 mpi_clear( MPI a )
10348 {
10349 a->nlimbs = 0;
10350 a->nbits = 0;
10351 a->flags = 0;
10352 }
10353
10354
10355 void
10356 #ifdef M_DEBUG
10357 mpi_debug_free( MPI a, const char *info )
10358 #else
10359 mpi_free( MPI a )
10360 #endif
10361 {
10362 if( !a )
10363 return;
10364 if( DBG_MEMORY )
10365 log_debug("mpi_free\n" );
10366 if( a->flags & 4 )
10367 xfree( a->d );
10368 else {
10369 #ifdef M_DEBUG
10370 mpi_debug_free_limb_space(a->d, info);
10371 #else
10372 mpi_free_limb_space(a->d);
10373 #endif
10374 }
10375 if( a->flags & ~7 )
10376 log_bug("invalid flag value in mpi\n");
10377 xfree(a);
10378 }
10379
10380
10381 void
10382 mpi_set_secure( MPI a )
10383 {
10384 mpi_ptr_t ap, bp;
10385
10386 if( (a->flags & 1) )
10387 return;
10388 a->flags |= 1;
10389 ap = a->d;
10390 if( !a->nlimbs ) {
10391 assert(!ap);
10392 return;
10393 }
10394 #ifdef M_DEBUG
10395 bp = mpi_debug_alloc_limb_space( a->nlimbs, 1, "set_secure" );
10396 #else
10397 bp = mpi_alloc_limb_space( a->nlimbs, 1 );
10398 #endif
10399 MPN_COPY( bp, ap, a->nlimbs );
10400 a->d = bp;
10401 #ifdef M_DEBUG
10402 mpi_debug_free_limb_space(ap, "set_secure");
10403 #else
10404 mpi_free_limb_space(ap);
10405 #endif
10406 }
10407
10408
10409 MPI
10410 mpi_set_opaque( MPI a, void *p, unsigned int len )
10411 {
10412 if( !a ) {
10413 #ifdef M_DEBUG
10414 a = mpi_debug_alloc(0,"alloc_opaque");
10415 #else
10416 a = mpi_alloc(0);
10417 #endif
10418 }
10419
10420 if( a->flags & 4 )
10421 xfree( a->d );
10422 else {
10423 #ifdef M_DEBUG
10424 mpi_debug_free_limb_space(a->d, "alloc_opaque");
10425 #else
10426 mpi_free_limb_space(a->d);
10427 #endif
10428 }
10429
10430 a->d = p;
10431 a->alloced = 0;
10432 a->nlimbs = 0;
10433 a->nbits = len;
10434 a->flags = 4;
10435 return a;
10436 }
10437
10438
10439 void *
10440 mpi_get_opaque( MPI a, unsigned int *len )
10441 {
10442 if( !(a->flags & 4) )
10443 log_bug("mpi_get_opaque on normal mpi\n");
10444 if( len )
10445 *len = a->nbits;
10446 return a->d;
10447 }
10448
10449
10450 /****************
10451 * Note: This copy function should not interpret the MPI
10452 * but copy it transparently.
10453 */
10454 MPI
10455 #ifdef M_DEBUG
10456 mpi_debug_copy( MPI a, const char *info )
10457 #else
10458 mpi_copy( MPI a )
10459 #endif
10460 {
10461 int i;
10462 MPI b;
10463
10464 if( a && (a->flags & 4) ) {
10465 void *p = m_is_secure(a->d)? xmalloc_secure( a->nbits )
10466 : xmalloc( a->nbits );
10467 memcpy( p, a->d, a->nbits );
10468 b = mpi_set_opaque( NULL, p, a->nbits );
10469 }
10470 else if( a ) {
10471 #ifdef M_DEBUG
10472 b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
10473 : mpi_debug_alloc( a->nlimbs, info );
10474 #else
10475 b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
10476 : mpi_alloc( a->nlimbs );
10477 #endif
10478 b->nlimbs = a->nlimbs;
10479 b->sign = a->sign;
10480 b->flags = a->flags;
10481 b->nbits = a->nbits;
10482 for(i=0; i < b->nlimbs; i++ )
10483 b->d[i] = a->d[i];
10484 }
10485 else
10486 b = NULL;
10487 return b;
10488 }
10489
10490
10491 /****************
10492 * This function allocates an MPI which is optimized to hold
10493 * a value as large as the one given in the argument and allocates it
10494 * with the same flags as A.
10495 */
10496 MPI
10497 #ifdef M_DEBUG
10498 mpi_debug_alloc_like( MPI a, const char *info )
10499 #else
10500 mpi_alloc_like( MPI a )
10501 #endif
10502 {
10503 MPI b;
10504
10505 if( a && (a->flags & 4) ) {
10506 void *p = m_is_secure(a->d)? xmalloc_secure( a->nbits )
10507 : xmalloc( a->nbits );
10508 memcpy( p, a->d, a->nbits );
10509 b = mpi_set_opaque( NULL, p, a->nbits );
10510 }
10511 else if( a ) {
10512 #ifdef M_DEBUG
10513 b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
10514 : mpi_debug_alloc( a->nlimbs, info );
10515 #else
10516 b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
10517 : mpi_alloc( a->nlimbs );
10518 #endif
10519 b->nlimbs = 0;
10520 b->sign = 0;
10521 b->flags = a->flags;
10522 b->nbits = 0;
10523 }
10524 else
10525 b = NULL;
10526 return b;
10527 }
10528
10529
10530 void
10531 mpi_set( MPI w, MPI u)
10532 {
10533 mpi_ptr_t wp, up;
10534 mpi_size_t usize = u->nlimbs;
10535 int usign = u->sign;
10536
10537 RESIZE_IF_NEEDED(w, usize);
10538 wp = w->d;
10539 up = u->d;
10540 MPN_COPY( wp, up, usize );
10541 w->nlimbs = usize;
10542 w->nbits = u->nbits;
10543 w->flags = u->flags;
10544 w->sign = usign;
10545 }
10546
10547
10548 void
10549 mpi_set_ui( MPI w, unsigned long u)
10550 {
10551 RESIZE_IF_NEEDED(w, 1);
10552 w->d[0] = u;
10553 w->nlimbs = u? 1:0;
10554 w->sign = 0;
10555 w->nbits = 0;
10556 w->flags = 0;
10557 }
10558
10559
10560 MPI
10561 mpi_alloc_set_ui( unsigned long u)
10562 {
10563 #ifdef M_DEBUG
10564 MPI w = mpi_debug_alloc(1,"alloc_set_ui");
10565 #else
10566 MPI w = mpi_alloc(1);
10567 #endif
10568 w->d[0] = u;
10569 w->nlimbs = u? 1:0;
10570 w->sign = 0;
10571 return w;
10572 }
10573
10574
10575 void
10576 mpi_swap( MPI a, MPI b)
10577 {
10578 struct gcry_mpi tmp;
10579
10580 tmp = *a; *a = *b; *b = tmp;
10581 }
10582
10583
10584 int
10585 mpi_get_nlimbs (MPI a)
10586 {
10587 return a->nlimbs;
10588 }
10589
10590
10591 int
10592 mpi_is_neg (MPI a)
10593 {
10594 return a->sign;
10595 }
10596
10597
10598 /* Return the number of limbs to store an MPI which is specified by
10599 the number of bytes to represent it. */
10600 unsigned int
10601 mpi_nlimb_hint_from_nbytes (unsigned int nbytes)
10602 {
10603 return (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
10604 }
10605
10606 /* Return the number of limbs to store an MPI which is specified by
10607 the number of bytes to represent it. */
10608 unsigned int
10609 mpi_nlimb_hint_from_nbits (unsigned int nbits)
10610 {
10611 return (nbits+BITS_PER_MPI_LIMB-1) / BITS_PER_MPI_LIMB;
10612 }
10613
10614 unsigned int
10615 mpi_get_flags (MPI a)
10616 {
10617 return a->flags;
10618 }
-
+ 0FBA934FB804042EF44214806D9256EE9D9E9A51878CA97942941C1EF5A9E81F779C2AB99C0C6F3C9DD01A748DB7D4624E35635FD2A748DF00655F95CBD98F22
mpi/obj/README
(0 . 0)(1 . 1)
10623 obj
-
+ 6BE57F08EC92D8BB7FBA6E14DE060CA60D0655B3DAD55CCC31B8387B9A305361F208E05589F091F8A0F774D9830E43B015E81E5DDC16EC41C16B00A04A13F69F
mpi/README
(0 . 0)(1 . 57)
10629 What you see here is a very classic version of the GNU MPI (bignum) library.
10630 It has been surgically removed from GnuPG 1.4.10, specifically as found at:
10631
10632 http://trilema.com/wp-content/uploads/2015/10/gnupg-1.4.10.tar.gz.asc
10633
10634 SHA512(gnupg-1.4.10.tar.gz) :
10635 d037041d2e6882fd3b999500b5a7b42be2c224836afc358e1f8a2465c1b74473d518f185b7c324b2c8dec4ffb70e9e34a03c94d1a54cc55d297f40c9745f6e1b
10636
10637 CHANGES FROM ORIGINAL:
10638
10639 1) Everything pertaining to Automake was nuked, and the earth where it stood -
10640 salted.
10641
10642 Instead, we now have a conventional Makefile. It builds precisely
10643 ONE THING - a single 'mpi.a' library suitable for static linking into
10644 another project. This will turn up in 'bin'.
10645
10646 Among other things, this now means that all KNOBS now reside in a
10647 MANUALLY-controlled 'config.h' found in 'include'. If you are building
10648 on some very peculiar unix, please read it and adjust as appropriate.
10649 It contains ONLY those knobs which actually pertain to the code.
10650
10651 The Makefile contains a 'check-syntax' - users of Emacs and Flymake
10652 will see proper error-highlighting.
10653
10654 2) ALL chip-specific ASM optimizations (including those found in longlong.h)
10655 have been nuked.
10656
10657 3) GPG-specific cruft has been amputated to the extent practical.
10658
10659 The logging system has been retained, but it can be easily torn out,
10660 which I may choose to do in the near future.
10661
10662 The I/O buffering system has been retained. I may choose to remove it
10663 in the near future.
10664
10665 The 'secure memory' (unpageable alloc) system has been retained.
10666
10667 'Localization' and all related idiocies have been nuked.
10668 Write hieroglyphs at home, leave them there, civilized folk
10669 don't need'em in their source code.
10670
10671 4) Other code has been altered solely to the extent required by items
10672 (1) and (2).
10673
10674 Cruft which appears in dead #ifdefs may be removed in the future.
10675 Don't get comfortable with it being there.
10676
10677 5) Readers who wish to know EXACTLY what I changed, should get a copy of the
10678 original tarball and write a simple script involving 'find' and 'vdiff',
10679 which sadly did not fit in the margins of this page.
10680
10681 6) To use the library, include 'include/mpi.h' in your project,
10682 and statically link with 'bin/mpi.a'.
10683
10684 7) The original code was distributed under GPL 3, which may apply on
10685 your planet and is therefore included. (See COPYING.)
-
+ A0B28117315BD9560BE404C97E44252316FD19FF9CBC762BF5D46235034846155D5058E22A73D7010F78CF7442BA6624E2417A719FFCBE2F8A163090706E069C
mpi/secmem.c
(0 . 0)(1 . 519)
10690 /* secmem.c - memory allocation from a secure heap
10691 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
10692 * 2007 Free Software Foundation, Inc.
10693 *
10694 * This file is part of GnuPG.
10695 *
10696 * GnuPG is free software; you can redistribute it and/or modify
10697 * it under the terms of the GNU General Public License as published by
10698 * the Free Software Foundation; either version 3 of the License, or
10699 * (at your option) any later version.
10700 *
10701 * GnuPG is distributed in the hope that it will be useful,
10702 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10703 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10704 * GNU General Public License for more details.
10705 *
10706 * You should have received a copy of the GNU General Public License
10707 * along with this program; if not, see <http://www.gnu.org/licenses/>.
10708 */
10709
10710 #include <config.h>
10711 #include <stdio.h>
10712 #include <stdlib.h>
10713 #include <string.h>
10714 #include <errno.h>
10715 #include <stdarg.h>
10716 #include <unistd.h>
10717 #if defined(HAVE_MLOCK) || defined(HAVE_MMAP)
10718 #include <sys/mman.h>
10719 #include <sys/types.h>
10720 #include <fcntl.h>
10721 #ifdef USE_CAPABILITIES
10722 #include <sys/capability.h>
10723 #endif
10724 #ifdef HAVE_PLOCK
10725 #include <sys/lock.h>
10726 #endif
10727 #endif
10728
10729 #include "types.h"
10730 #include "memory.h"
10731 #include "util.h"
10732
10733 /* MinGW doesn't seem to prototype getpagesize, though it does have
10734 it. */
10735 #if !HAVE_DECL_GETPAGESIZE
10736 int getpagesize(void);
10737 #endif
10738
10739 #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
10740 #define MAP_ANONYMOUS MAP_ANON
10741 #endif
10742 /* It seems that Slackware 7.1 does not know about EPERM */
10743 #if !defined(EPERM) && defined(ENOMEM)
10744 #define EPERM ENOMEM
10745 #endif
10746
10747
10748 #define DEFAULT_POOLSIZE 16384
10749
10750 typedef struct memblock_struct MEMBLOCK;
10751 struct memblock_struct {
10752 unsigned size;
10753 union {
10754 MEMBLOCK *next;
10755 PROPERLY_ALIGNED_TYPE aligned;
10756 } u;
10757 };
10758
10759
10760
10761 static void *pool;
10762 static volatile int pool_okay; /* may be checked in an atexit function */
10763 #ifdef HAVE_MMAP
10764 static volatile int pool_is_mmapped;
10765 #endif
10766 static size_t poolsize; /* allocated length */
10767 static size_t poollen; /* used length */
10768 static MEMBLOCK *unused_blocks;
10769 static unsigned max_alloced;
10770 static unsigned cur_alloced;
10771 static unsigned max_blocks;
10772 static unsigned cur_blocks;
10773 static int disable_secmem;
10774 static int show_warning;
10775 static int no_warning;
10776 static int suspend_warning;
10777
10778
10779 static void
10780 print_warn(void)
10781 {
10782 if (!no_warning)
10783 {
10784 log_info(_("WARNING: using insecure memory!\n"));
10785 log_info(_("please see http://www.gnupg.org/faq.html"
10786 " for more information\n"));
10787 }
10788 }
10789
10790
10791 static void
10792 lock_pool( void *p, size_t n )
10793 {
10794 #if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK)
10795 int err;
10796
10797 cap_set_proc( cap_from_text("cap_ipc_lock+ep") );
10798 err = mlock( p, n );
10799 if( err && errno )
10800 err = errno;
10801 cap_set_proc( cap_from_text("cap_ipc_lock+p") );
10802
10803 if( err ) {
10804 if( errno != EPERM
10805 #ifdef EAGAIN /* OpenBSD returns this */
10806 && errno != EAGAIN
10807 #endif
10808 #ifdef ENOSYS /* Some SCOs return this (function not implemented) */
10809 && errno != ENOSYS
10810 #endif
10811 #ifdef ENOMEM /* Linux can return this */
10812 && errno != ENOMEM
10813 #endif
10814 )
10815 log_error("can't lock memory: %s\n", strerror(err));
10816 show_warning = 1;
10817 }
10818
10819 #elif defined(HAVE_MLOCK)
10820 uid_t uid;
10821 int err;
10822
10823 uid = getuid();
10824
10825 #ifdef HAVE_BROKEN_MLOCK
10826 /* ick. but at least we get secured memory. about to lock
10827 entire data segment. */
10828 #ifdef HAVE_PLOCK
10829 # ifdef _AIX
10830 /* The configure for AIX returns broken mlock but the plock has
10831 the strange requirement to somehow set the stack limit first.
10832 The problem might turn out in indeterministic program behaviour
10833 and hanging processes which can somehow be solved when enough
10834 processes are clogging up the memory. To get this problem out
10835 of the way we simply don't try to lock the memory at all.
10836 */
10837 errno = EPERM;
10838 err = errno;
10839 # else /* !_AIX */
10840 err = plock( DATLOCK );
10841 if( err && errno )
10842 err = errno;
10843 # endif /*_AIX*/
10844 #else /*!HAVE_PLOCK*/
10845 if( uid ) {
10846 errno = EPERM;
10847 err = errno;
10848 }
10849 else {
10850 err = mlock( p, n );
10851 if( err && errno )
10852 err = errno;
10853 }
10854 #endif /*!HAVE_PLOCK*/
10855 #else
10856 err = mlock( p, n );
10857 if( err && errno )
10858 err = errno;
10859 #endif
10860
10861 if( uid && !geteuid() ) {
10862 /* check that we really dropped the privs.
10863 * Note: setuid(0) should always fail */
10864 if( setuid( uid ) || getuid() != geteuid() || !setuid(0) )
10865 log_fatal("failed to reset uid: %s\n", strerror(errno));
10866 }
10867
10868 if( err ) {
10869 if( errno != EPERM
10870 #ifdef EAGAIN /* OpenBSD returns this */
10871 && errno != EAGAIN
10872 #endif
10873 #ifdef ENOSYS /* Some SCOs return this (function not implemented) */
10874 && errno != ENOSYS
10875 #endif
10876 #ifdef ENOMEM /* Linux can return this */
10877 && errno != ENOMEM
10878 #endif
10879 )
10880 log_error("can't lock memory: %s\n", strerror(err));
10881 show_warning = 1;
10882 }
10883
10884 #elif defined ( __QNX__ )
10885 /* QNX does not page at all, so the whole secure memory stuff does
10886 * not make much sense. However it is still of use because it
10887 * wipes out the memory on a free().
10888 * Therefore it is sufficient to suppress the warning
10889 */
10890 #elif defined (HAVE_DOSISH_SYSTEM) || defined (__CYGWIN__)
10891 /* It does not make sense to print such a warning, given the fact that
10892 * this whole Windows !@#$% and their user base are inherently insecure
10893 */
10894 #elif defined (__riscos__)
10895 /* no virtual memory on RISC OS, so no pages are swapped to disc,
10896 * besides we don't have mmap, so we don't use it! ;-)
10897 * But don't complain, as explained above.
10898 */
10899 #else
10900 log_info("Please note that you don't have secure memory on this system\n");
10901 #endif
10902 }
10903
10904
10905 static void
10906 init_pool( size_t n)
10907 {
10908 long int pgsize_val;
10909 size_t pgsize;
10910
10911 poolsize = n;
10912
10913 if( disable_secmem )
10914 log_bug("secure memory is disabled");
10915
10916 #if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
10917 pgsize_val = sysconf (_SC_PAGESIZE);
10918 #elif defined(HAVE_GETPAGESIZE)
10919 pgsize_val = getpagesize ();
10920 #else
10921 pgsize_val = -1;
10922 #endif
10923 pgsize = (pgsize_val != -1 && pgsize_val > 0)? pgsize_val : 4096;
10924
10925
10926 #ifdef HAVE_MMAP
10927 poolsize = (poolsize + pgsize -1 ) & ~(pgsize-1);
10928 #ifdef MAP_ANONYMOUS
10929 pool = mmap( 0, poolsize, PROT_READ|PROT_WRITE,
10930 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
10931 #else /* map /dev/zero instead */
10932 { int fd;
10933
10934 fd = open("/dev/zero", O_RDWR);
10935 if( fd == -1 ) {
10936 log_error("can't open /dev/zero: %s\n", strerror(errno) );
10937 pool = (void*)-1;
10938 }
10939 else {
10940 pool = mmap( 0, poolsize, PROT_READ|PROT_WRITE,
10941 MAP_PRIVATE, fd, 0);
10942 close (fd);
10943 }
10944 }
10945 #endif
10946 if( pool == (void*)-1 )
10947 log_info("can't mmap pool of %u bytes: %s - using malloc\n",
10948 (unsigned)poolsize, strerror(errno));
10949 else {
10950 pool_is_mmapped = 1;
10951 pool_okay = 1;
10952 }
10953
10954 #endif
10955 if( !pool_okay ) {
10956 pool = malloc( poolsize );
10957 if( !pool )
10958 log_fatal("can't allocate memory pool of %u bytes\n",
10959 (unsigned)poolsize);
10960 else
10961 pool_okay = 1;
10962 }
10963 lock_pool( pool, poolsize );
10964 poollen = 0;
10965 }
10966
10967
10968 /* concatenate unused blocks */
10969 static void
10970 compress_pool(void)
10971 {
10972 /* fixme: we really should do this */
10973 }
10974
10975 void
10976 secmem_set_flags( unsigned flags )
10977 {
10978 int was_susp = suspend_warning;
10979
10980 no_warning = flags & 1;
10981 suspend_warning = flags & 2;
10982
10983 /* and now issue the warning if it is not longer suspended */
10984 if( was_susp && !suspend_warning && show_warning ) {
10985 show_warning = 0;
10986 print_warn();
10987 }
10988 }
10989
10990 unsigned
10991 secmem_get_flags(void)
10992 {
10993 unsigned flags;
10994
10995 flags = no_warning ? 1:0;
10996 flags |= suspend_warning ? 2:0;
10997 return flags;
10998 }
10999
11000 /* Returns 1 if memory was locked, 0 if not. */
11001 int
11002 secmem_init( size_t n )
11003 {
11004 if( !n ) {
11005 #ifndef __riscos__
11006 #ifdef USE_CAPABILITIES
11007 /* drop all capabilities */
11008 cap_set_proc( cap_from_text("all-eip") );
11009
11010 #elif !defined(HAVE_DOSISH_SYSTEM)
11011 uid_t uid;
11012
11013 disable_secmem=1;
11014 uid = getuid();
11015 if( uid != geteuid() ) {
11016 if( setuid( uid ) || getuid() != geteuid() || !setuid(0) )
11017 log_fatal("failed to drop setuid\n" );
11018 }
11019 #endif
11020 #endif /* !__riscos__ */
11021 }
11022 else {
11023 if( n < DEFAULT_POOLSIZE )
11024 n = DEFAULT_POOLSIZE;
11025 if( !pool_okay )
11026 init_pool(n);
11027 else
11028 log_error("Oops, secure memory pool already initialized\n");
11029 }
11030
11031 return !show_warning;
11032 }
11033
11034
11035 void *
11036 secmem_malloc( size_t size )
11037 {
11038 MEMBLOCK *mb, *mb2;
11039 int compressed=0;
11040
11041 if( !pool_okay ) {
11042 log_info(
11043 _("operation is not possible without initialized secure memory\n"));
11044 log_info(_("(you may have used the wrong program for this task)\n"));
11045 exit(2);
11046 }
11047 if( show_warning && !suspend_warning ) {
11048 show_warning = 0;
11049 print_warn();
11050 }
11051
11052 /* Blocks are always a multiple of 32. Note that we allocate an
11053 extra of the size of an entire MEMBLOCK. This is required
11054 becuase we do not only need the SIZE info but also extra space
11055 to chain up unused memory blocks. */
11056 size += sizeof(MEMBLOCK);
11057 size = ((size + 31) / 32) * 32;
11058
11059 retry:
11060 /* try to get it from the used blocks */
11061 for(mb = unused_blocks,mb2=NULL; mb; mb2=mb, mb = mb->u.next )
11062 if( mb->size >= size ) {
11063 if( mb2 )
11064 mb2->u.next = mb->u.next;
11065 else
11066 unused_blocks = mb->u.next;
11067 goto leave;
11068 }
11069 /* allocate a new block */
11070 if( (poollen + size <= poolsize) ) {
11071 mb = (void*)((char*)pool + poollen);
11072 poollen += size;
11073 mb->size = size;
11074 }
11075 else if( !compressed ) {
11076 compressed=1;
11077 compress_pool();
11078 goto retry;
11079 }
11080 else
11081 return NULL;
11082
11083 leave:
11084 cur_alloced += mb->size;
11085 cur_blocks++;
11086 if( cur_alloced > max_alloced )
11087 max_alloced = cur_alloced;
11088 if( cur_blocks > max_blocks )
11089 max_blocks = cur_blocks;
11090
11091 return &mb->u.aligned.c;
11092 }
11093
11094
11095 void *
11096 secmexrealloc( void *p, size_t newsize )
11097 {
11098 MEMBLOCK *mb;
11099 size_t size;
11100 void *a;
11101
11102 mb = (MEMBLOCK*)((char*)p - ((size_t) &((MEMBLOCK*)0)->u.aligned.c));
11103 size = mb->size;
11104 if (size < sizeof(MEMBLOCK))
11105 log_bug ("secure memory corrupted at block %p\n", (void *)mb);
11106 size -= ((size_t) &((MEMBLOCK*)0)->u.aligned.c);
11107
11108 if( newsize <= size )
11109 return p; /* It is easier not to shrink the memory. */
11110 a = secmem_malloc( newsize );
11111 if ( a ) {
11112 memcpy(a, p, size);
11113 memset((char*)a+size, 0, newsize-size);
11114 secmem_free(p);
11115 }
11116 return a;
11117 }
11118
11119
11120 void
11121 secmem_free( void *a )
11122 {
11123 MEMBLOCK *mb;
11124 size_t size;
11125
11126 if( !a )
11127 return;
11128
11129 mb = (MEMBLOCK*)((char*)a - ((size_t) &((MEMBLOCK*)0)->u.aligned.c));
11130 size = mb->size;
11131 /* This does not make much sense: probably this memory is held in the
11132 * cache. We do it anyway: */
11133 wipememory2(mb, 0xff, size );
11134 wipememory2(mb, 0xaa, size );
11135 wipememory2(mb, 0x55, size );
11136 wipememory2(mb, 0x00, size );
11137 mb->size = size;
11138 mb->u.next = unused_blocks;
11139 unused_blocks = mb;
11140 cur_blocks--;
11141 cur_alloced -= size;
11142 }
11143
11144
11145 /* Check whether P points into the pool. */
11146 static int
11147 ptr_into_pool_p (const void *p)
11148 {
11149 /* We need to convert pointers to addresses. This is required by
11150 C-99 6.5.8 to avoid undefined behaviour. Using size_t is at
11151 least only implementation defined. See also
11152 http://lists.gnupg.org/pipermail/gcrypt-devel/2007-February/001102.html
11153 */
11154 size_t p_addr = (size_t)p;
11155 size_t pool_addr = (size_t)pool;
11156
11157 return p_addr >= pool_addr && p_addr < pool_addr+poolsize;
11158 }
11159
11160
11161 int
11162 m_is_secure( const void *p )
11163 {
11164 return pool_okay && ptr_into_pool_p (p);
11165 }
11166
11167
11168
11169 /****************
11170 * Warning: This code might be called by an interrupt handler
11171 * and frankly, there should really be such a handler,
11172 * to make sure that the memory is wiped out.
11173 * We hope that the OS wipes out mlocked memory after
11174 * receiving a SIGKILL - it really should do so, otherwise
11175 * there is no chance to get the secure memory cleaned.
11176 */
11177 void
11178 secmem_term()
11179 {
11180 if( !pool_okay )
11181 return;
11182
11183 wipememory2( pool, 0xff, poolsize);
11184 wipememory2( pool, 0xaa, poolsize);
11185 wipememory2( pool, 0x55, poolsize);
11186 wipememory2( pool, 0x00, poolsize);
11187 #ifdef HAVE_MMAP
11188 if( pool_is_mmapped )
11189 munmap( pool, poolsize );
11190 #endif
11191 pool = NULL;
11192 pool_okay = 0;
11193 poolsize=0;
11194 poollen=0;
11195 unused_blocks=NULL;
11196 }
11197
11198
11199 void
11200 secmem_dump_stats()
11201 {
11202 if( disable_secmem )
11203 return;
11204 fprintf(stderr,
11205 "secmem usage: %u/%u bytes in %u/%u blocks of pool %lu/%lu\n",
11206 cur_alloced, max_alloced, cur_blocks, max_blocks,
11207 (ulong)poollen, (ulong)poolsize );
11208 }
-
+ FB984A326A9BCDA1A4CBC05EE279E55CFEFCF157393D2F66405760B256395C3A73F1F41EBFC335722022EA04C79F6E02AB3179ECC9A66E037DD7A106572B4924
mpi/udiv-w-sdiv.c
(0 . 0)(1 . 132)
11213 /* mpihelp_udiv_w_sdiv -- implement udiv_qrnnd on machines with only signed
11214 * division.
11215 * Copyright (C) 1992, 1994, 1996, 1998 Free Software Foundation, Inc.
11216 * Contributed by Peter L. Montgomery.
11217 *
11218 * This file is part of GnuPG.
11219 *
11220 * GnuPG is free software; you can redistribute it and/or modify
11221 * it under the terms of the GNU General Public License as published by
11222 * the Free Software Foundation; either version 3 of the License, or
11223 * (at your option) any later version.
11224 *
11225 * GnuPG is distributed in the hope that it will be useful,
11226 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11227 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11228 * GNU General Public License for more details.
11229 *
11230 * You should have received a copy of the GNU General Public License
11231 * along with this program; if not, see <http://www.gnu.org/licenses/>.
11232 */
11233
11234 #include <config.h>
11235 #include <stdio.h>
11236 #include <stdlib.h>
11237 #include "mpi-internal.h"
11238 #include "longlong.h"
11239
11240
11241 #if 0 /* not yet ported to MPI */
11242
11243 mpi_limb_t
11244 mpihelp_udiv_w_sdiv( mpi_limp_t *rp,
11245 mpi_limp_t *a1,
11246 mpi_limp_t *a0,
11247 mpi_limp_t *d )
11248 {
11249 mp_limb_t q, r;
11250 mp_limb_t c0, c1, b1;
11251
11252 if ((mpi_limb_signed_t) d >= 0)
11253 {
11254 if (a1 < d - a1 - (a0 >> (BITS_PER_MP_LIMB - 1)))
11255 {
11256 /* dividend, divisor, and quotient are nonnegative */
11257 sdiv_qrnnd (q, r, a1, a0, d);
11258 }
11259 else
11260 {
11261 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
11262 sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (BITS_PER_MP_LIMB - 1));
11263 /* Divide (c1*2^32 + c0) by d */
11264 sdiv_qrnnd (q, r, c1, c0, d);
11265 /* Add 2^31 to quotient */
11266 q += (mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1);
11267 }
11268 }
11269 else
11270 {
11271 b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
11272 c1 = a1 >> 1; /* A/2 */
11273 c0 = (a1 << (BITS_PER_MP_LIMB - 1)) + (a0 >> 1);
11274
11275 if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
11276 {
11277 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
11278
11279 r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
11280 if ((d & 1) != 0)
11281 {
11282 if (r >= q)
11283 r = r - q;
11284 else if (q - r <= d)
11285 {
11286 r = r - q + d;
11287 q--;
11288 }
11289 else
11290 {
11291 r = r - q + 2*d;
11292 q -= 2;
11293 }
11294 }
11295 }
11296 else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
11297 {
11298 c1 = (b1 - 1) - c1;
11299 c0 = ~c0; /* logical NOT */
11300
11301 sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
11302
11303 q = ~q; /* (A/2)/b1 */
11304 r = (b1 - 1) - r;
11305
11306 r = 2*r + (a0 & 1); /* A/(2*b1) */
11307
11308 if ((d & 1) != 0)
11309 {
11310 if (r >= q)
11311 r = r - q;
11312 else if (q - r <= d)
11313 {
11314 r = r - q + d;
11315 q--;
11316 }
11317 else
11318 {
11319 r = r - q + 2*d;
11320 q -= 2;
11321 }
11322 }
11323 }
11324 else /* Implies c1 = b1 */
11325 { /* Hence a1 = d - 1 = 2*b1 - 1 */
11326 if (a0 >= -d)
11327 {
11328 q = -1;
11329 r = a0 + d;
11330 }
11331 else
11332 {
11333 q = -2;
11334 r = a0 + 2*d;
11335 }
11336 }
11337 }
11338
11339 *rp = r;
11340 return q;
11341 }
11342
11343 #endif
11344