Upload xnu-7195.141.2 Source

This commit is contained in:
Thomas A 2023-05-16 21:41:14 -07:00
commit cdbc10b677
4540 changed files with 1973310 additions and 0 deletions

367
APPLE_LICENSE Normal file
View File

@ -0,0 +1,367 @@
APPLE PUBLIC SOURCE LICENSE
Version 2.0 - August 6, 2003
Please read this License carefully before downloading this software.
By downloading or using this software, you are agreeing to be bound by
the terms of this License. If you do not or cannot agree to the terms
of this License, please do not download or use the software.
1. General; Definitions. This License applies to any program or other
work which Apple Computer, Inc. ("Apple") makes publicly available and
which contains a notice placed by Apple identifying such program or
work as "Original Code" and stating that it is subject to the terms of
this Apple Public Source License version 2.0 ("License"). As used in
this License:
1.1 "Applicable Patent Rights" mean: (a) in the case where Apple is
the grantor of rights, (i) claims of patents that are now or hereafter
acquired, owned by or assigned to Apple and (ii) that cover subject
matter contained in the Original Code, but only to the extent
necessary to use, reproduce and/or distribute the Original Code
without infringement; and (b) in the case where You are the grantor of
rights, (i) claims of patents that are now or hereafter acquired,
owned by or assigned to You and (ii) that cover subject matter in Your
Modifications, taken alone or in combination with Original Code.
1.2 "Contributor" means any person or entity that creates or
contributes to the creation of Modifications.
1.3 "Covered Code" means the Original Code, Modifications, the
combination of Original Code and any Modifications, and/or any
respective portions thereof.
1.4 "Externally Deploy" means: (a) to sublicense, distribute or
otherwise make Covered Code available, directly or indirectly, to
anyone other than You; and/or (b) to use Covered Code, alone or as
part of a Larger Work, in any way to provide a service, including but
not limited to delivery of content, through electronic communication
with a client other than You.
1.5 "Larger Work" means a work which combines Covered Code or portions
thereof with code not governed by the terms of this License.
1.6 "Modifications" mean any addition to, deletion from, and/or change
to, the substance and/or structure of the Original Code, any previous
Modifications, the combination of Original Code and any previous
Modifications, and/or any respective portions thereof. When code is
released as a series of files, a Modification is: (a) any addition to
or deletion from the contents of a file containing Covered Code;
and/or (b) any new file or other representation of computer program
statements that contains any part of Covered Code.
1.7 "Original Code" means (a) the Source Code of a program or other
work as originally made available by Apple under this License,
including the Source Code of any updates or upgrades to such programs
or works made available by Apple under this License, and that has been
expressly identified by Apple as such in the header file(s) of such
work; and (b) the object code compiled from such Source Code and
originally made available by Apple under this License.
1.8 "Source Code" means the human readable form of a program or other
work that is suitable for making modifications to it, including all
modules it contains, plus any associated interface definition files,
scripts used to control compilation and installation of an executable
(object code).
1.9 "You" or "Your" means an individual or a legal entity exercising
rights under this License. For legal entities, "You" or "Your"
includes any entity which controls, is controlled by, or is under
common control with, You, where "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of fifty percent
(50%) or more of the outstanding shares or beneficial ownership of
such entity.
2. Permitted Uses; Conditions & Restrictions. Subject to the terms
and conditions of this License, Apple hereby grants You, effective on
the date You accept this License and download the Original Code, a
world-wide, royalty-free, non-exclusive license, to the extent of
Apple's Applicable Patent Rights and copyrights covering the Original
Code, to do the following:
2.1 Unmodified Code. You may use, reproduce, display, perform,
internally distribute within Your organization, and Externally Deploy
verbatim, unmodified copies of the Original Code, for commercial or
non-commercial purposes, provided that in each instance:
(a) You must retain and reproduce in all copies of Original Code the
copyright and other proprietary notices and disclaimers of Apple as
they appear in the Original Code, and keep intact all notices in the
Original Code that refer to this License; and
(b) You must include a copy of this License with every copy of Source
Code of Covered Code and documentation You distribute or Externally
Deploy, and You may not offer or impose any terms on such Source Code
that alter or restrict this License or the recipients' rights
hereunder, except as permitted under Section 6.
2.2 Modified Code. You may modify Covered Code and use, reproduce,
display, perform, internally distribute within Your organization, and
Externally Deploy Your Modifications and Covered Code, for commercial
or non-commercial purposes, provided that in each instance You also
meet all of these conditions:
(a) You must satisfy all the conditions of Section 2.1 with respect to
the Source Code of the Covered Code;
(b) You must duplicate, to the extent it does not already exist, the
notice in Exhibit A in each file of the Source Code of all Your
Modifications, and cause the modified files to carry prominent notices
stating that You changed the files and the date of any change; and
(c) If You Externally Deploy Your Modifications, You must make
Source Code of all Your Externally Deployed Modifications either
available to those to whom You have Externally Deployed Your
Modifications, or publicly available. Source Code of Your Externally
Deployed Modifications must be released under the terms set forth in
this License, including the license grants set forth in Section 3
below, for as long as you Externally Deploy the Covered Code or twelve
(12) months from the date of initial External Deployment, whichever is
longer. You should preferably distribute the Source Code of Your
Externally Deployed Modifications electronically (e.g. download from a
web site).
2.3 Distribution of Executable Versions. In addition, if You
Externally Deploy Covered Code (Original Code and/or Modifications) in
object code, executable form only, You must include a prominent
notice, in the code itself as well as in related documentation,
stating that Source Code of the Covered Code is available under the
terms of this License with information on how and where to obtain such
Source Code.
2.4 Third Party Rights. You expressly acknowledge and agree that
although Apple and each Contributor grants the licenses to their
respective portions of the Covered Code set forth herein, no
assurances are provided by Apple or any Contributor that the Covered
Code does not infringe the patent or other intellectual property
rights of any other entity. Apple and each Contributor disclaim any
liability to You for claims brought by any other entity based on
infringement of intellectual property rights or otherwise. As a
condition to exercising the rights and licenses granted hereunder, You
hereby assume sole responsibility to secure any other intellectual
property rights needed, if any. For example, if a third party patent
license is required to allow You to distribute the Covered Code, it is
Your responsibility to acquire that license before distributing the
Covered Code.
3. Your Grants. In consideration of, and as a condition to, the
licenses granted to You under this License, You hereby grant to any
person or entity receiving or distributing Covered Code under this
License a non-exclusive, royalty-free, perpetual, irrevocable license,
under Your Applicable Patent Rights and other intellectual property
rights (other than patent) owned or controlled by You, to use,
reproduce, display, perform, modify, sublicense, distribute and
Externally Deploy Your Modifications of the same scope and extent as
Apple's licenses under Sections 2.1 and 2.2 above.
4. Larger Works. You may create a Larger Work by combining Covered
Code with other code not governed by the terms of this License and
distribute the Larger Work as a single product. In each such instance,
You must make sure the requirements of this License are fulfilled for
the Covered Code or any portion thereof.
5. Limitations on Patent License. Except as expressly stated in
Section 2, no other patent rights, express or implied, are granted by
Apple herein. Modifications and/or Larger Works may require additional
patent licenses from Apple which Apple may grant in its sole
discretion.
6. Additional Terms. You may choose to offer, and to charge a fee for,
warranty, support, indemnity or liability obligations and/or other
rights consistent with the scope of the license granted herein
("Additional Terms") to one or more recipients of Covered Code.
However, You may do so only on Your own behalf and as Your sole
responsibility, and not on behalf of Apple or any Contributor. You
must obtain the recipient's agreement that any such Additional Terms
are offered by You alone, and You hereby agree to indemnify, defend
and hold Apple and every Contributor harmless for any liability
incurred by or claims asserted against Apple or such Contributor by
reason of any such Additional Terms.
7. Versions of the License. Apple may publish revised and/or new
versions of this License from time to time. Each version will be given
a distinguishing version number. Once Original Code has been published
under a particular version of this License, You may continue to use it
under the terms of that version. You may also choose to use such
Original Code under the terms of any subsequent version of this
License published by Apple. No one other than Apple has the right to
modify the terms applicable to Covered Code created under this
License.
8. NO WARRANTY OR SUPPORT. The Covered Code may contain in whole or in
part pre-release, untested, or not fully tested works. The Covered
Code may contain errors that could cause failures or loss of data, and
may be incomplete or contain inaccuracies. You expressly acknowledge
and agree that use of the Covered Code, or any portion thereof, is at
Your sole and entire risk. THE COVERED CODE IS PROVIDED "AS IS" AND
WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND AND APPLE AND
APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE
PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM
ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF
MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR
PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD
PARTY RIGHTS. APPLE AND EACH CONTRIBUTOR DOES NOT WARRANT AGAINST
INTERFERENCE WITH YOUR ENJOYMENT OF THE COVERED CODE, THAT THE
FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR REQUIREMENTS,
THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR
ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO
ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE
AUTHORIZED REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY.
You acknowledge that the Covered Code is not intended for use in the
operation of nuclear facilities, aircraft navigation, communication
systems, or air traffic control machines in which case the failure of
the Covered Code could lead to death, personal injury, or severe
physical or environmental damage.
9. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO
EVENT SHALL APPLE OR ANY CONTRIBUTOR BE LIABLE FOR ANY INCIDENTAL,
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING
TO THIS LICENSE OR YOUR USE OR INABILITY TO USE THE COVERED CODE, OR
ANY PORTION THEREOF, WHETHER UNDER A THEORY OF CONTRACT, WARRANTY,
TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, EVEN IF
APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY
REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY OF
INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY
TO YOU. In no event shall Apple's total liability to You for all
damages (other than as may be required by applicable law) under this
License exceed the amount of fifty dollars ($50.00).
10. Trademarks. This License does not grant any rights to use the
trademarks or trade names "Apple", "Apple Computer", "Mac", "Mac OS",
"QuickTime", "QuickTime Streaming Server" or any other trademarks,
service marks, logos or trade names belonging to Apple (collectively
"Apple Marks") or to any trademark, service mark, logo or trade name
belonging to any Contributor. You agree not to use any Apple Marks in
or as part of the name of products derived from the Original Code or
to endorse or promote products derived from the Original Code other
than as expressly permitted by and in strict compliance at all times
with Apple's third party trademark usage guidelines which are posted
at http://www.apple.com/legal/guidelinesfor3rdparties.html.
11. Ownership. Subject to the licenses granted under this License,
each Contributor retains all rights, title and interest in and to any
Modifications made by such Contributor. Apple retains all rights,
title and interest in and to the Original Code and any Modifications
made by or on behalf of Apple ("Apple Modifications"), and such Apple
Modifications will not be automatically subject to this License. Apple
may, at its sole discretion, choose to license such Apple
Modifications under this License, or on different terms from those
contained in this License or may choose not to license them at all.
12. Termination.
12.1 Termination. This License and the rights granted hereunder will
terminate:
(a) automatically without notice from Apple if You fail to comply with
any term(s) of this License and fail to cure such breach within 30
days of becoming aware of such breach;
(b) immediately in the event of the circumstances described in Section
13.5(b); or
(c) automatically without notice from Apple if You, at any time during
the term of this License, commence an action for patent infringement
against Apple; provided that Apple did not first commence
an action for patent infringement against You in that instance.
12.2 Effect of Termination. Upon termination, You agree to immediately
stop any further use, reproduction, modification, sublicensing and
distribution of the Covered Code. All sublicenses to the Covered Code
which have been properly granted prior to termination shall survive
any termination of this License. Provisions which, by their nature,
should remain in effect beyond the termination of this License shall
survive, including but not limited to Sections 3, 5, 8, 9, 10, 11,
12.2 and 13. No party will be liable to any other for compensation,
indemnity or damages of any sort solely as a result of terminating
this License in accordance with its terms, and termination of this
License will be without prejudice to any other right or remedy of
any party.
13. Miscellaneous.
13.1 Government End Users. The Covered Code is a "commercial item" as
defined in FAR 2.101. Government software and technical data rights in
the Covered Code include only those rights customarily provided to the
public as defined in this License. This customary commercial license
in technical data and software is provided in accordance with FAR
12.211 (Technical Data) and 12.212 (Computer Software) and, for
Department of Defense purchases, DFAR 252.227-7015 (Technical Data --
Commercial Items) and 227.7202-3 (Rights in Commercial Computer
Software or Computer Software Documentation). Accordingly, all U.S.
Government End Users acquire Covered Code with only those rights set
forth herein.
13.2 Relationship of Parties. This License will not be construed as
creating an agency, partnership, joint venture or any other form of
legal association between or among You, Apple or any Contributor, and
You will not represent to the contrary, whether expressly, by
implication, appearance or otherwise.
13.3 Independent Development. Nothing in this License will impair
Apple's right to acquire, license, develop, have others develop for
it, market and/or distribute technology or products that perform the
same or similar functions as, or otherwise compete with,
Modifications, Larger Works, technology or products that You may
develop, produce, market or distribute.
13.4 Waiver; Construction. Failure by Apple or any Contributor to
enforce any provision of this License will not be deemed a waiver of
future enforcement of that or any other provision. Any law or
regulation which provides that the language of a contract shall be
construed against the drafter will not apply to this License.
13.5 Severability. (a) If for any reason a court of competent
jurisdiction finds any provision of this License, or portion thereof,
to be unenforceable, that provision of the License will be enforced to
the maximum extent permissible so as to effect the economic benefits
and intent of the parties, and the remainder of this License will
continue in full force and effect. (b) Notwithstanding the foregoing,
if applicable law prohibits or restricts You from fully and/or
specifically complying with Sections 2 and/or 3 or prevents the
enforceability of either of those Sections, this License will
immediately terminate and You must immediately discontinue any use of
the Covered Code and destroy all copies of it that are in your
possession or control.
13.6 Dispute Resolution. Any litigation or other dispute resolution
between You and Apple relating to this License shall take place in the
Northern District of California, and You and Apple hereby consent to
the personal jurisdiction of, and venue in, the state and federal
courts within that District with respect to this License. The
application of the United Nations Convention on Contracts for the
International Sale of Goods is expressly excluded.
13.7 Entire Agreement; Governing Law. This License constitutes the
entire agreement between the parties with respect to the subject
matter hereof. This License shall be governed by the laws of the
United States and the State of California, except that body of
California law concerning conflicts of law.
Where You are located in the province of Quebec, Canada, the following
clause applies: The parties hereby confirm that they have requested
that this License and all related documents be drafted in English. Les
parties ont exige que le present contrat et tous les documents
connexes soient rediges en anglais.
EXHIBIT A.
"Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
Reserved.
This file contains Original Code and/or Modifications of Original Code
as defined in and that are subject to the Apple Public Source License
Version 2.0 (the 'License'). You may not use this file except in
compliance with the License. Please obtain a copy of the License at
http://www.opensource.apple.com/apsl/ and read it before using this
file.
The Original Code and all software distributed under the License are
distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
Please see the License for the specific language governing rights and
limitations under the License."

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,420 @@
/*
* Copyright (c) 2007-2016 by Apple Inc.. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef __AVAILABILITY__
#define __AVAILABILITY__
/*
These macros are for use in OS header files. They enable function prototypes
and Objective-C methods to be tagged with the OS version in which they
were first available; and, if applicable, the OS version in which they
became deprecated.
The desktop Mac OS X and iOS each have different version numbers.
The __OSX_AVAILABLE_STARTING() macro allows you to specify both the desktop
and iOS version numbers. For instance:
__OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_2_0)
means the function/method was first available on Mac OS X 10.2 on the desktop
and first available in iOS 2.0 on the iPhone.
If a function is available on one platform, but not the other a _NA (not
applicable) parameter is used. For instance:
__OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_NA)
means that the function/method was first available on Mac OS X 10.3, and it
currently not implemented on the iPhone.
At some point, a function/method may be deprecated. That means Apple
recommends applications stop using the function, either because there is a
better replacement or the functionality is being phased out. Deprecated
functions/methods can be tagged with a __OSX_AVAILABLE_BUT_DEPRECATED()
macro which specifies the OS version where the function became available
as well as the OS version in which it became deprecated. For instance:
__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0,__MAC_10_5,__IPHONE_NA,__IPHONE_NA)
means that the function/method was introduced in Mac OS X 10.0, then
became deprecated beginning in Mac OS X 10.5. On iOS the function
has never been available.
For these macros to function properly, a program must specify the OS version range
it is targeting. The min OS version is specified as an option to the compiler:
-mmacosx-version-min=10.x when building for Mac OS X, and -miphoneos-version-min=y.z
when building for the iPhone. The upper bound for the OS version is rarely needed,
but it can be set on the command line via: -D__MAC_OS_X_VERSION_MAX_ALLOWED=10x0 for
Mac OS X and __IPHONE_OS_VERSION_MAX_ALLOWED = y0z00 for iOS.
Examples:
A function available in Mac OS X 10.5 and later, but not on the phone:
extern void mymacfunc() __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_NA);
An Objective-C method in Mac OS X 10.5 and later, but not on the phone:
@interface MyClass : NSObject
-(void) mymacmethod __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_NA);
@end
An enum available on the phone, but not available on Mac OS X:
#if __IPHONE_OS_VERSION_MIN_REQUIRED
enum { myEnum = 1 };
#endif
Note: this works when targeting the Mac OS X platform because
__IPHONE_OS_VERSION_MIN_REQUIRED is undefined which evaluates to zero.
An enum with values added in different iPhoneOS versions:
enum {
myX = 1, // Usable on iPhoneOS 2.1 and later
myY = 2, // Usable on iPhoneOS 3.0 and later
myZ = 3, // Usable on iPhoneOS 3.0 and later
...
Note: you do not want to use #if with enumeration values
when a client needs to see all values at compile time
and use runtime logic to only use the viable values.
It is also possible to use the *_VERSION_MIN_REQUIRED in source code to make one
source base that can be compiled to target a range of OS versions. It is best
to not use the _MAC_* and __IPHONE_* macros for comparisons, but rather their values.
That is because you might get compiled on an old OS that does not define a later
OS version macro, and in the C preprocessor undefined values evaluate to zero
in expresssions, which could cause the #if expression to evaluate in an unexpected
way.
#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED
// code only compiled when targeting Mac OS X and not iPhone
// note use of 1050 instead of __MAC_10_5
#if __MAC_OS_X_VERSION_MIN_REQUIRED < 1050
// code in here might run on pre-Leopard OS
#else
// code here can assume Leopard or later
#endif
#endif
*/
#define __MAC_10_0 1000
#define __MAC_10_1 1010
#define __MAC_10_2 1020
#define __MAC_10_3 1030
#define __MAC_10_4 1040
#define __MAC_10_5 1050
#define __MAC_10_6 1060
#define __MAC_10_7 1070
#define __MAC_10_8 1080
#define __MAC_10_9 1090
#define __MAC_10_10 101000
#define __MAC_10_10_2 101002
#define __MAC_10_10_3 101003
#define __MAC_10_11 101100
#define __MAC_10_11_2 101102
#define __MAC_10_11_3 101103
#define __MAC_10_11_4 101104
#define __MAC_10_12 101200
#define __MAC_10_12_1 101201
#define __MAC_10_12_2 101202
#define __MAC_10_12_4 101204
/* __MAC_NA is not defined to a value but is uses as a token by macros to indicate that the API is unavailable */
#define __IPHONE_2_0 20000
#define __IPHONE_2_1 20100
#define __IPHONE_2_2 20200
#define __IPHONE_3_0 30000
#define __IPHONE_3_1 30100
#define __IPHONE_3_2 30200
#define __IPHONE_4_0 40000
#define __IPHONE_4_1 40100
#define __IPHONE_4_2 40200
#define __IPHONE_4_3 40300
#define __IPHONE_5_0 50000
#define __IPHONE_5_1 50100
#define __IPHONE_6_0 60000
#define __IPHONE_6_1 60100
#define __IPHONE_7_0 70000
#define __IPHONE_7_1 70100
#define __IPHONE_8_0 80000
#define __IPHONE_8_1 80100
#define __IPHONE_8_2 80200
#define __IPHONE_8_3 80300
#define __IPHONE_8_4 80400
#define __IPHONE_9_0 90000
#define __IPHONE_9_1 90100
#define __IPHONE_9_2 90200
#define __IPHONE_9_3 90300
#define __IPHONE_10_0 100000
#define __IPHONE_10_1 100100
#define __IPHONE_10_2 100200
#define __IPHONE_10_3 100300
/* __IPHONE_NA is not defined to a value but is uses as a token by macros to indicate that the API is unavailable */
#define __TVOS_9_0 90000
#define __TVOS_9_1 90100
#define __TVOS_9_2 90200
#define __TVOS_10_0 100000
#define __TVOS_10_0_1 100001
#define __TVOS_10_1 100100
#define __TVOS_10_2 100200
#define __WATCHOS_1_0 10000
#define __WATCHOS_2_0 20000
#define __WATCHOS_3_0 30000
#define __WATCHOS_3_1 30100
#define __WATCHOS_3_1_1 30101
#define __WATCHOS_3_2 30200
#include <AvailabilityInternal.h>
#ifdef __IPHONE_OS_VERSION_MIN_REQUIRED
#define __OSX_AVAILABLE_STARTING(_osx, _ios) __AVAILABILITY_INTERNAL##_ios
#define __OSX_AVAILABLE_BUT_DEPRECATED(_osxIntro, _osxDep, _iosIntro, _iosDep) \
__AVAILABILITY_INTERNAL##_iosIntro##_DEP##_iosDep
#define __OSX_AVAILABLE_BUT_DEPRECATED_MSG(_osxIntro, _osxDep, _iosIntro, _iosDep, _msg) \
__AVAILABILITY_INTERNAL##_iosIntro##_DEP##_iosDep##_MSG(_msg)
#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED)
#define __OSX_AVAILABLE_STARTING(_osx, _ios) __AVAILABILITY_INTERNAL##_osx
#define __OSX_AVAILABLE_BUT_DEPRECATED(_osxIntro, _osxDep, _iosIntro, _iosDep) \
__AVAILABILITY_INTERNAL##_osxIntro##_DEP##_osxDep
#define __OSX_AVAILABLE_BUT_DEPRECATED_MSG(_osxIntro, _osxDep, _iosIntro, _iosDep, _msg) \
__AVAILABILITY_INTERNAL##_osxIntro##_DEP##_osxDep##_MSG(_msg)
#else
#define __OSX_AVAILABLE_STARTING(_osx, _ios)
#define __OSX_AVAILABLE_BUT_DEPRECATED(_osxIntro, _osxDep, _iosIntro, _iosDep)
#define __OSX_AVAILABLE_BUT_DEPRECATED_MSG(_osxIntro, _osxDep, _iosIntro, _iosDep, _msg)
#endif
#if defined(__has_feature)
#if __has_feature(attribute_availability_with_message)
#define __OS_AVAILABILITY(_target, _availability) __attribute__((availability(_target,_availability)))
#define __OS_AVAILABILITY_MSG(_target, _availability, _msg) __attribute__((availability(_target,_availability,message=_msg)))
#elif __has_feature(attribute_availability)
#define __OS_AVAILABILITY(_target, _availability) __attribute__((availability(_target,_availability)))
#define __OS_AVAILABILITY_MSG(_target, _availability, _msg) __attribute__((availability(_target,_availability)))
#else
#define __OS_AVAILABILITY(_target, _availability)
#define __OS_AVAILABILITY_MSG(_target, _availability, _msg)
#endif
#else
#define __OS_AVAILABILITY(_target, _availability)
#define __OS_AVAILABILITY_MSG(_target, _availability, _msg)
#endif
/* for use to document app extension usage */
#if defined(__has_feature)
#if __has_feature(attribute_availability_app_extension)
#define __OSX_EXTENSION_UNAVAILABLE(_msg) __OS_AVAILABILITY_MSG(macosx_app_extension,unavailable,_msg)
#define __IOS_EXTENSION_UNAVAILABLE(_msg) __OS_AVAILABILITY_MSG(ios_app_extension,unavailable,_msg)
#else
#define __OSX_EXTENSION_UNAVAILABLE(_msg)
#define __IOS_EXTENSION_UNAVAILABLE(_msg)
#endif
#else
#define __OSX_EXTENSION_UNAVAILABLE(_msg)
#define __IOS_EXTENSION_UNAVAILABLE(_msg)
#endif
#define __OS_EXTENSION_UNAVAILABLE(_msg) __OSX_EXTENSION_UNAVAILABLE(_msg) __IOS_EXTENSION_UNAVAILABLE(_msg)
/* for use marking APIs available info for Mac OSX */
#if defined(__has_attribute)
#if __has_attribute(availability)
#define __OSX_UNAVAILABLE __OS_AVAILABILITY(macosx,unavailable)
#define __OSX_AVAILABLE(_vers) __OS_AVAILABILITY(macosx,introduced=_vers)
#define __OSX_DEPRECATED(_start, _dep, _msg) __OSX_AVAILABLE(_start) __OS_AVAILABILITY_MSG(macosx,deprecated=_dep,_msg)
#endif
#endif
#ifndef __OSX_UNAVAILABLE
#define __OSX_UNAVAILABLE
#endif
#ifndef __OSX_AVAILABLE
#define __OSX_AVAILABLE(_vers)
#endif
#ifndef __OSX_DEPRECATED
#define __OSX_DEPRECATED(_start, _dep, _msg)
#endif
/* for use marking APIs available info for iOS */
#if defined(__has_attribute)
#if __has_attribute(availability)
#define __IOS_UNAVAILABLE __OS_AVAILABILITY(ios,unavailable)
#define __IOS_PROHIBITED __OS_AVAILABILITY(ios,unavailable)
#define __IOS_AVAILABLE(_vers) __OS_AVAILABILITY(ios,introduced=_vers)
#define __IOS_DEPRECATED(_start, _dep, _msg) __IOS_AVAILABLE(_start) __OS_AVAILABILITY_MSG(ios,deprecated=_dep,_msg)
#endif
#endif
#ifndef __IOS_UNAVAILABLE
#define __IOS_UNAVAILABLE
#endif
#ifndef __IOS_PROHIBITED
#define __IOS_PROHIBITED
#endif
#ifndef __IOS_AVAILABLE
#define __IOS_AVAILABLE(_vers)
#endif
#ifndef __IOS_DEPRECATED
#define __IOS_DEPRECATED(_start, _dep, _msg)
#endif
/* for use marking APIs available info for tvOS */
#if defined(__has_feature)
#if __has_feature(attribute_availability_tvos)
#define __TVOS_UNAVAILABLE __OS_AVAILABILITY(tvos,unavailable)
#define __TVOS_PROHIBITED __OS_AVAILABILITY(tvos,unavailable)
#define __TVOS_AVAILABLE(_vers) __OS_AVAILABILITY(tvos,introduced=_vers)
#define __TVOS_DEPRECATED(_start, _dep, _msg) __TVOS_AVAILABLE(_start) __OS_AVAILABILITY_MSG(tvos,deprecated=_dep,_msg)
#endif
#endif
#ifndef __TVOS_UNAVAILABLE
#define __TVOS_UNAVAILABLE
#endif
#ifndef __TVOS_PROHIBITED
#define __TVOS_PROHIBITED
#endif
#ifndef __TVOS_AVAILABLE
#define __TVOS_AVAILABLE(_vers)
#endif
#ifndef __TVOS_DEPRECATED
#define __TVOS_DEPRECATED(_start, _dep, _msg)
#endif
/* for use marking APIs available info for Watch OS */
#if defined(__has_feature)
#if __has_feature(attribute_availability_watchos)
#define __WATCHOS_UNAVAILABLE __OS_AVAILABILITY(watchos,unavailable)
#define __WATCHOS_PROHIBITED __OS_AVAILABILITY(watchos,unavailable)
#define __WATCHOS_AVAILABLE(_vers) __OS_AVAILABILITY(watchos,introduced=_vers)
#define __WATCHOS_DEPRECATED(_start, _dep, _msg) __WATCHOS_AVAILABLE(_start) __OS_AVAILABILITY_MSG(watchos,deprecated=_dep,_msg)
#endif
#endif
#ifndef __WATCHOS_UNAVAILABLE
#define __WATCHOS_UNAVAILABLE
#endif
#ifndef __WATCHOS_PROHIBITED
#define __WATCHOS_PROHIBITED
#endif
#ifndef __WATCHOS_AVAILABLE
#define __WATCHOS_AVAILABLE(_vers)
#endif
#ifndef __WATCHOS_DEPRECATED
#define __WATCHOS_DEPRECATED(_start, _dep, _msg)
#endif
/* for use marking APIs unavailable for swift */
#if defined(__has_feature)
#if __has_feature(attribute_availability_swift)
#define __SWIFT_UNAVAILABLE __OS_AVAILABILITY(swift,unavailable)
#define __SWIFT_UNAVAILABLE_MSG(_msg) __OS_AVAILABILITY_MSG(swift,unavailable,_msg)
#endif
#endif
#ifndef __SWIFT_UNAVAILABLE
#define __SWIFT_UNAVAILABLE
#endif
#ifndef __SWIFT_UNAVAILABLE_MSG
#define __SWIFT_UNAVAILABLE_MSG(_msg)
#endif
#if __has_include(<AvailabilityProhibitedInternal.h>)
#include <AvailabilityProhibitedInternal.h>
#endif
/*
Macros for defining which versions/platform a given symbol can be used.
@see http://clang.llvm.org/docs/AttributeReference.html#availability
*/
/*
* API Introductions
*
* Use to specify the release that a particular API became available.
*
* Platform names:
* macos, ios, tvos, watchos
*
* Examples:
* __API_AVAILABLE(macos(10.10))
* __API_AVAILABLE(macos(10.9), ios(10.0))
* __API_AVAILABLE(macos(10.4), ios(8.0), watchos(2.0), tvos(10.0))
*/
#define __API_AVAILABLE(...) __API_AVAILABLE_GET_MACRO(__VA_ARGS__,__API_AVAILABLE4, __API_AVAILABLE3, __API_AVAILABLE2, __API_AVAILABLE1)(__VA_ARGS__)
/*
* API Deprecations
*
* Use to specify the release that a particular API became unavailable.
*
* Platform names:
* macos, ios, tvos, watchos
*
* Examples:
*
* __API_DEPRECATED("No longer supported", macos(10.4, 10.8))
* __API_DEPRECATED("No longer supported", macos(10.4, 10.8), ios(2.0, 3.0), watchos(2.0, 3.0), tvos(9.0, 10.0))
*
* __API_DEPRECATED_WITH_REPLACEMENT("-setName:", tvos(10.0, 10.4), ios(9.0, 10.0))
* __API_DEPRECATED_WITH_REPLACEMENT("SomeClassName", macos(10.4, 10.6), watchos(2.0, 3.0))
*/
#define __API_DEPRECATED(...) __API_DEPRECATED_MSG_GET_MACRO(__VA_ARGS__,__API_DEPRECATED_MSG5,__API_DEPRECATED_MSG4,__API_DEPRECATED_MSG3,__API_DEPRECATED_MSG2,__API_DEPRECATED_MSG1)(__VA_ARGS__)
#define __API_DEPRECATED_WITH_REPLACEMENT(...) __API_DEPRECATED_REP_GET_MACRO(__VA_ARGS__,__API_DEPRECATED_REP5,__API_DEPRECATED_REP4,__API_DEPRECATED_REP3,__API_DEPRECATED_REP2,__API_DEPRECATED_REP1)(__VA_ARGS__)
/*
* API Unavailability
* Use to specify that an API is unavailable for a particular platform.
*
* Example:
* __API_UNAVAILABLE(macos)
* __API_UNAVAILABLE(watchos, tvos)
*/
#define __API_UNAVAILABLE(...) __API_UNAVAILABLE_GET_MACRO(__VA_ARGS__,__API_UNAVAILABLE3,__API_UNAVAILABLE2,__API_UNAVAILABLE1)(__VA_ARGS__)
#endif /* __AVAILABILITY__ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.framework.kernel</string>
<key>CFBundleName</key>
<string>Kernel</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>###KERNEL_VERSION_SHORT###</string>
<key>CFBundleVersion</key>
<string>###KERNEL_VERSION_LONG###</string>
<key>CFBundleSignature</key>
<string>????</string>
</dict>
</plist>

52
EXTERNAL_HEADERS/Makefile Normal file
View File

@ -0,0 +1,52 @@
export MakeInc_cmd=${SRCROOT}/makedefs/MakeInc.cmd
export MakeInc_def=${SRCROOT}/makedefs/MakeInc.def
export MakeInc_rule=${SRCROOT}/makedefs/MakeInc.rule
export MakeInc_dir=${SRCROOT}/makedefs/MakeInc.dir
include $(MakeInc_cmd)
include $(MakeInc_def)
INSTINC_SUBDIRS = \
architecture \
mach-o \
sys
INSTINC_SUBDIRS_X86_64 = \
architecture
INSTINC_SUBDIRS_X86_64H = \
architecture
INSTINC_SUBDIRS_ARM = \
architecture
INSTINC_SUBDIRS_ARM64 = \
architecture
EXPORT_FILES = \
Availability.h \
AvailabilityInternal.h \
AvailabilityMacros.h
KERNEL_FILES = \
stdarg.h \
stdatomic.h \
stdbool.h \
stddef.h \
stdint.h \
ptrauth.h
INSTALL_MI_LIST =
INSTALL_MI_DIR = .
INSTALL_KF_MI_LIST = ${KERNEL_FILES}
INSTALL_KF_MI_LCL_LIST = ${KERNEL_FILES}
EXPORT_MI_LIST = ${EXPORT_FILES} ${KERNEL_FILES}
EXPORT_MI_DIR = .
include $(MakeInc_rule)
include $(MakeInc_dir)

View File

@ -0,0 +1,462 @@
/******************************************************************************
*
* Name: actbl.h - Basic ACPI Table Definitions
* $Revision: 1.7 $
*
*****************************************************************************/
/******************************************************************************
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2006, Intel Corp.
* All rights reserved.
*
* 2. License
*
* 2.1. This is your license from Intel Corp. under its intellectual property
* rights. You may have additional license terms from the party that provided
* you this software, covering your right to use that party's intellectual
* property rights.
*
* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
* copy of the source code appearing in this file ("Covered Code") an
* irrevocable, perpetual, worldwide license under Intel's copyrights in the
* base code distributed originally by Intel ("Original Intel Code") to copy,
* make derivatives, distribute, use and display any portion of the Covered
* Code in any form, with the right to sublicense such rights; and
*
* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
* license (with the right to sublicense), under only those claims of Intel
* patents that are infringed by the Original Intel Code, to make, use, sell,
* offer to sell, and import the Covered Code and derivative works thereof
* solely to the minimum extent necessary to exercise the above copyright
* license, and in no event shall the patent license extend to any additions
* to or modifications of the Original Intel Code. No other license or right
* is granted directly or by implication, estoppel or otherwise;
*
* The above copyright and patent license is granted only if the following
* conditions are met:
*
* 3. Conditions
*
* 3.1. Redistribution of Source with Rights to Further Distribute Source.
* Redistribution of source code of any substantial portion of the Covered
* Code or modification with rights to further distribute source must include
* the above Copyright Notice, the above License, this list of Conditions,
* and the following Disclaimer and Export Compliance provision. In addition,
* Licensee must cause all Covered Code to which Licensee contributes to
* contain a file documenting the changes Licensee made to create that Covered
* Code and the date of any change. Licensee must include in that file the
* documentation of any changes made by any predecessor Licensee. Licensee
* must include a prominent statement that the modification is derived,
* directly or indirectly, from Original Intel Code.
*
* 3.2. Redistribution of Source with no Rights to Further Distribute Source.
* Redistribution of source code of any substantial portion of the Covered
* Code or modification without rights to further distribute source must
* include the following Disclaimer and Export Compliance provision in the
* documentation and/or other materials provided with distribution. In
* addition, Licensee may not authorize further sublicense of source of any
* portion of the Covered Code, and must include terms to the effect that the
* license from Licensee to its licensee is limited to the intellectual
* property embodied in the software Licensee provides to its licensee, and
* not to intellectual property embodied in modifications its licensee may
* make.
*
* 3.3. Redistribution of Executable. Redistribution in executable form of any
* substantial portion of the Covered Code or modification must reproduce the
* above Copyright Notice, and the following Disclaimer and Export Compliance
* provision in the documentation and/or other materials provided with the
* distribution.
*
* 3.4. Intel retains all right, title, and interest in and to the Original
* Intel Code.
*
* 3.5. Neither the name Intel nor any other trademark owned or controlled by
* Intel shall be used in advertising or otherwise to promote the sale, use or
* other dealings in products derived from or relating to the Covered Code
* without prior written authorization from Intel.
*
* 4. Disclaimer and Export Compliance
*
* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
* LIMITED REMEDY.
*
* 4.3. Licensee shall not export, either directly or indirectly, any of this
* software or system incorporating such software without first obtaining any
* required license or other approval from the U. S. Department of Commerce or
* any other agency or department of the United States Government. In the
* event Licensee exports any such software from the United States or
* re-exports any such software from a foreign destination, Licensee shall
* ensure that the distribution and export/re-export of the software is in
* compliance with all laws, regulations, orders, or other restrictions of the
* U.S. Export Administration Regulations. Licensee agrees that neither it nor
* any of its subsidiaries will export/re-export any technical data, process,
* software, or service, directly or indirectly, to any country for which the
* United States government or any agency thereof requires an export license,
* other governmental approval, or letter of assurance, without first obtaining
* such license, approval or letter.
*
*****************************************************************************/
#ifndef __ACTBL_H__
#define __ACTBL_H__
/*
* Values for description table header signatures. Useful because they make
* it more difficult to inadvertently type in the wrong signature.
*/
#define DSDT_SIG "DSDT" /* Differentiated System Description Table */
#define FADT_SIG "FACP" /* Fixed ACPI Description Table */
#define FACS_SIG "FACS" /* Firmware ACPI Control Structure */
#define PSDT_SIG "PSDT" /* Persistent System Description Table */
#define RSDP_SIG "RSD PTR " /* Root System Description Pointer */
#define RSDT_SIG "RSDT" /* Root System Description Table */
#define XSDT_SIG "XSDT" /* Extended System Description Table */
#define SSDT_SIG "SSDT" /* Secondary System Description Table */
#define RSDP_NAME "RSDP"
/*
* All tables and structures must be byte-packed to match the ACPI
* specification, since the tables are provided by the system BIOS
*/
#pragma pack(1)
/*
* These are the ACPI tables that are directly consumed by the subsystem.
*
* The RSDP and FACS do not use the common ACPI table header. All other ACPI
* tables use the header.
*
* Note about bitfields: The UINT8 type is used for bitfields in ACPI tables.
* This is the only type that is even remotely portable. Anything else is not
* portable, so do not use any other bitfield types.
*/
/*******************************************************************************
*
* ACPI Table Header. This common header is used by all tables except the
* RSDP and FACS. The define is used for direct inclusion of header into
* other ACPI tables
*
******************************************************************************/
#define ACPI_TABLE_HEADER_DEF \
char Signature[4]; /* ASCII table signature */ \
UINT32 Length; /* Length of table in bytes, including this header */ \
UINT8 Revision; /* ACPI Specification minor version # */ \
UINT8 Checksum; /* To make sum of entire table == 0 */ \
char OemId[6]; /* ASCII OEM identification */ \
char OemTableId[8]; /* ASCII OEM table identification */ \
UINT32 OemRevision; /* OEM revision number */ \
char AslCompilerId[4]; /* ASCII ASL compiler vendor ID */ \
UINT32 AslCompilerRevision; /* ASL compiler version */
typedef struct acpi_table_header {
ACPI_TABLE_HEADER_DEF
} ACPI_TABLE_HEADER;
/*
* GAS - Generic Address Structure (ACPI 2.0+)
*/
typedef struct acpi_generic_address {
UINT8 AddressSpaceId; /* Address space where struct or register exists */
UINT8 RegisterBitWidth; /* Size in bits of given register */
UINT8 RegisterBitOffset; /* Bit offset within the register */
UINT8 AccessWidth; /* Minimum Access size (ACPI 3.0) */
UINT64 Address; /* 64-bit address of struct or register */
} ACPI_GENERIC_ADDRESS;
/*******************************************************************************
*
* RSDP - Root System Description Pointer (Signature is "RSD PTR ")
*
******************************************************************************/
typedef struct rsdp_descriptor {
char Signature[8]; /* ACPI signature, contains "RSD PTR " */
UINT8 Checksum; /* ACPI 1.0 checksum */
char OemId[6]; /* OEM identification */
UINT8 Revision; /* Must be (0) for ACPI 1.0 or (2) for ACPI 2.0+ */
UINT32 RsdtPhysicalAddress;/* 32-bit physical address of the RSDT */
UINT32 Length; /* Table length in bytes, including header (ACPI 2.0+) */
UINT64 XsdtPhysicalAddress;/* 64-bit physical address of the XSDT (ACPI 2.0+) */
UINT8 ExtendedChecksum; /* Checksum of entire table (ACPI 2.0+) */
UINT8 Reserved[3]; /* Reserved, must be zero */
} RSDP_DESCRIPTOR;
#define ACPI_RSDP_REV0_SIZE 20 /* Size of original ACPI 1.0 RSDP */
/*******************************************************************************
*
* RSDT/XSDT - Root System Description Tables
*
******************************************************************************/
typedef struct rsdt_descriptor {
ACPI_TABLE_HEADER_DEF
UINT32 TableOffsetEntry[1];/* Array of pointers to ACPI tables */
} RSDT_DESCRIPTOR;
typedef struct xsdt_descriptor {
ACPI_TABLE_HEADER_DEF
UINT64 TableOffsetEntry[1];/* Array of pointers to ACPI tables */
} XSDT_DESCRIPTOR;
/*******************************************************************************
*
* FACS - Firmware ACPI Control Structure (FACS)
*
******************************************************************************/
typedef struct facs_descriptor {
char Signature[4]; /* ASCII table signature */
UINT32 Length; /* Length of structure, in bytes */
UINT32 HardwareSignature; /* Hardware configuration signature */
UINT32 FirmwareWakingVector;/* 32-bit physical address of the Firmware Waking Vector */
UINT32 GlobalLock; /* Global Lock for shared hardware resources */
/* Flags (32 bits) */
UINT8 S4Bios_f : 1;/* 00: S4BIOS support is present */
UINT8 : 7;/* 01-07: Reserved, must be zero */
UINT8 Reserved1[3]; /* 08-31: Reserved, must be zero */
UINT64 XFirmwareWakingVector;/* 64-bit version of the Firmware Waking Vector (ACPI 2.0+) */
UINT8 Version; /* Version of this table (ACPI 2.0+) */
UINT8 Reserved[31]; /* Reserved, must be zero */
} FACS_DESCRIPTOR;
#define ACPI_GLOCK_PENDING 0x01 /* 00: Pending global lock ownership */
#define ACPI_GLOCK_OWNED 0x02 /* 01: Global lock is owned */
/*
* Common FACS - This is a version-independent FACS structure used for internal use only
*/
typedef struct acpi_common_facs {
UINT32 *GlobalLock;
UINT64 *FirmwareWakingVector;
UINT8 VectorWidth;
} ACPI_COMMON_FACS;
/*******************************************************************************
*
* FADT - Fixed ACPI Description Table (Signature "FACP")
*
******************************************************************************/
/* Fields common to all versions of the FADT */
#define ACPI_FADT_COMMON \
ACPI_TABLE_HEADER_DEF \
UINT32 V1_FirmwareCtrl; /* 32-bit physical address of FACS */ \
UINT32 V1_Dsdt; /* 32-bit physical address of DSDT */ \
UINT8 Reserved1; /* System Interrupt Model isn't used in ACPI 2.0*/ \
UINT8 Prefer_PM_Profile; /* Conveys preferred power management profile to OSPM. */ \
UINT16 SciInt; /* System vector of SCI interrupt */ \
UINT32 SmiCmd; /* Port address of SMI command port */ \
UINT8 AcpiEnable; /* Value to write to smi_cmd to enable ACPI */ \
UINT8 AcpiDisable; /* Value to write to smi_cmd to disable ACPI */ \
UINT8 S4BiosReq; /* Value to write to SMI CMD to enter S4BIOS state */ \
UINT8 PstateCnt; /* Processor performance state control*/ \
UINT32 V1_Pm1aEvtBlk; /* Port address of Power Mgt 1a Event Reg Blk */ \
UINT32 V1_Pm1bEvtBlk; /* Port address of Power Mgt 1b Event Reg Blk */ \
UINT32 V1_Pm1aCntBlk; /* Port address of Power Mgt 1a Control Reg Blk */ \
UINT32 V1_Pm1bCntBlk; /* Port address of Power Mgt 1b Control Reg Blk */ \
UINT32 V1_Pm2CntBlk; /* Port address of Power Mgt 2 Control Reg Blk */ \
UINT32 V1_PmTmrBlk; /* Port address of Power Mgt Timer Ctrl Reg Blk */ \
UINT32 V1_Gpe0Blk; /* Port addr of General Purpose AcpiEvent 0 Reg Blk */ \
UINT32 V1_Gpe1Blk; /* Port addr of General Purpose AcpiEvent 1 Reg Blk */ \
UINT8 Pm1EvtLen; /* Byte Length of ports at pm1X_evt_blk */ \
UINT8 Pm1CntLen; /* Byte Length of ports at pm1X_cnt_blk */ \
UINT8 Pm2CntLen; /* Byte Length of ports at pm2_cnt_blk */ \
UINT8 PmTmLen; /* Byte Length of ports at pm_tm_blk */ \
UINT8 Gpe0BlkLen; /* Byte Length of ports at gpe0_blk */ \
UINT8 Gpe1BlkLen; /* Byte Length of ports at gpe1_blk */ \
UINT8 Gpe1Base; /* Offset in gpe model where gpe1 events start */ \
UINT8 CstCnt; /* Support for the _CST object and C States change notification.*/ \
UINT16 Plvl2Lat; /* Worst case HW latency to enter/exit C2 state */ \
UINT16 Plvl3Lat; /* Worst case HW latency to enter/exit C3 state */ \
UINT16 FlushSize; /* Processor's memory cache line width, in bytes */ \
UINT16 FlushStride; /* Number of flush strides that need to be read */ \
UINT8 DutyOffset; /* Processor's duty cycle index in processor's P_CNT reg*/ \
UINT8 DutyWidth; /* Processor's duty cycle value bit width in P_CNT register.*/ \
UINT8 DayAlrm; /* Index to day-of-month alarm in RTC CMOS RAM */ \
UINT8 MonAlrm; /* Index to month-of-year alarm in RTC CMOS RAM */ \
UINT8 Century; /* Index to century in RTC CMOS RAM */ \
UINT16 IapcBootArch; /* IA-PC Boot Architecture Flags. See Table 5-10 for description*/ \
UINT8 Reserved2; /* Reserved, must be zero */
/*
* ACPI 2.0+ FADT
*/
typedef struct fadt_descriptor {
ACPI_FADT_COMMON
/* Flags (32 bits) */
UINT8 WbInvd : 1;/* 00: The wbinvd instruction works properly */
UINT8 WbInvdFlush : 1;/* 01: The wbinvd flushes but does not invalidate */
UINT8 ProcC1 : 1;/* 02: All processors support C1 state */
UINT8 Plvl2Up : 1;/* 03: C2 state works on MP system */
UINT8 PwrButton : 1;/* 04: Power button is handled as a generic feature */
UINT8 SleepButton : 1;/* 05: Sleep button is handled as a generic feature, or not present */
UINT8 FixedRTC : 1;/* 06: RTC wakeup stat not in fixed register space */
UINT8 Rtcs4 : 1;/* 07: RTC wakeup stat not possible from S4 */
UINT8 TmrValExt : 1;/* 08: tmr_val is 32 bits 0=24-bits */
UINT8 DockCap : 1;/* 09: Docking supported */
UINT8 ResetRegSup : 1;/* 10: System reset via the FADT RESET_REG supported */
UINT8 SealedCase : 1;/* 11: No internal expansion capabilities and case is sealed */
UINT8 Headless : 1;/* 12: No local video capabilities or local input devices */
UINT8 CpuSwSleep : 1;/* 13: Must execute native instruction after writing SLP_TYPx register */
UINT8 PciExpWak : 1;/* 14: System supports PCIEXP_WAKE (STS/EN) bits (ACPI 3.0) */
UINT8 UsePlatformClock : 1;/* 15: OSPM should use platform-provided timer (ACPI 3.0) */
UINT8 S4RtcStsValid : 1;/* 16: Contents of RTC_STS valid after S4 wake (ACPI 3.0) */
UINT8 RemotePowerOnCapable : 1;/* 17: System is compatible with remote power on (ACPI 3.0) */
UINT8 ForceApicClusterModel : 1;/* 18: All local APICs must use cluster model (ACPI 3.0) */
UINT8 ForceApicPhysicalDestinationMode : 1;/* 19: All local xAPICs must use physical dest mode (ACPI 3.0) */
UINT8 : 4;/* 20-23: Reserved, must be zero */
UINT8 Reserved3; /* 24-31: Reserved, must be zero */
ACPI_GENERIC_ADDRESS ResetRegister; /* Reset register address in GAS format */
UINT8 ResetValue; /* Value to write to the ResetRegister port to reset the system */
UINT8 Reserved4[3]; /* These three bytes must be zero */
UINT64 XFirmwareCtrl; /* 64-bit physical address of FACS */
UINT64 XDsdt; /* 64-bit physical address of DSDT */
ACPI_GENERIC_ADDRESS XPm1aEvtBlk; /* Extended Power Mgt 1a AcpiEvent Reg Blk address */
ACPI_GENERIC_ADDRESS XPm1bEvtBlk; /* Extended Power Mgt 1b AcpiEvent Reg Blk address */
ACPI_GENERIC_ADDRESS XPm1aCntBlk; /* Extended Power Mgt 1a Control Reg Blk address */
ACPI_GENERIC_ADDRESS XPm1bCntBlk; /* Extended Power Mgt 1b Control Reg Blk address */
ACPI_GENERIC_ADDRESS XPm2CntBlk; /* Extended Power Mgt 2 Control Reg Blk address */
ACPI_GENERIC_ADDRESS XPmTmrBlk; /* Extended Power Mgt Timer Ctrl Reg Blk address */
ACPI_GENERIC_ADDRESS XGpe0Blk; /* Extended General Purpose AcpiEvent 0 Reg Blk address */
ACPI_GENERIC_ADDRESS XGpe1Blk; /* Extended General Purpose AcpiEvent 1 Reg Blk address */
} FADT_DESCRIPTOR;
/*
* "Down-revved" ACPI 2.0 FADT descriptor
* Defined here to allow compiler to generate the length of the struct
*/
typedef struct fadt_descriptor_rev2_minus {
ACPI_FADT_COMMON
UINT32 Flags;
ACPI_GENERIC_ADDRESS ResetRegister; /* Reset register address in GAS format */
UINT8 ResetValue; /* Value to write to the ResetRegister port to reset the system. */
UINT8 Reserved7[3]; /* Reserved, must be zero */
} FADT_DESCRIPTOR_REV2_MINUS;
/*
* ACPI 1.0 FADT
* Defined here to allow compiler to generate the length of the struct
*/
typedef struct fadt_descriptor_rev1 {
ACPI_FADT_COMMON
UINT32 Flags;
} FADT_DESCRIPTOR_REV1;
/* FADT: Prefered Power Management Profiles */
#define PM_UNSPECIFIED 0
#define PM_DESKTOP 1
#define PM_MOBILE 2
#define PM_WORKSTATION 3
#define PM_ENTERPRISE_SERVER 4
#define PM_SOHO_SERVER 5
#define PM_APPLIANCE_PC 6
/* FADT: Boot Arch Flags */
#define BAF_LEGACY_DEVICES 0x0001
#define BAF_8042_KEYBOARD_CONTROLLER 0x0002
#define FADT2_REVISION_ID 3
#define FADT2_MINUS_REVISION_ID 2
/* Reset to default packing */
#pragma pack()
/*
* This macro is temporary until the table bitfield flag definitions
* are removed and replaced by a Flags field.
*/
#define ACPI_FLAG_OFFSET(d, f, o) (UINT8) (ACPI_OFFSET (d,f) +\
sizeof(((d *)0)->f) + o)
/*
* Get the remaining ACPI tables
*/
#include "Acpi_v1.h"
/*
* ACPI Table information. We save the table address, length,
* and type of memory allocation (mapped or allocated) for each
* table for 1) when we exit, and 2) if a new table is installed
*/
#define ACPI_MEM_NOT_ALLOCATED 0
#define ACPI_MEM_ALLOCATED 1
#define ACPI_MEM_MAPPED 2
/* Definitions for the Flags bitfield member of ACPI_TABLE_SUPPORT */
#define ACPI_TABLE_SINGLE 0x00
#define ACPI_TABLE_MULTIPLE 0x01
#define ACPI_TABLE_EXECUTABLE 0x02
#define ACPI_TABLE_ROOT 0x00
#define ACPI_TABLE_PRIMARY 0x10
#define ACPI_TABLE_SECONDARY 0x20
#define ACPI_TABLE_ALL 0x30
#define ACPI_TABLE_TYPE_MASK 0x30
/* Data about each known table type */
typedef struct acpi_table_support {
char *Name;
char *Signature;
void **GlobalPtr;
UINT8 SigLength;
UINT8 Flags;
} ACPI_TABLE_SUPPORT;
/* Macros used to generate offsets to specific table fields */
#define ACPI_FACS_OFFSET(f) (UINT8) ACPI_OFFSET (FACS_DESCRIPTOR,f)
#define ACPI_FADT_OFFSET(f) (UINT8) ACPI_OFFSET (FADT_DESCRIPTOR, f)
#define ACPI_GAS_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_GENERIC_ADDRESS,f)
#define ACPI_HDR_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_HEADER,f)
#define ACPI_RSDP_OFFSET(f) (UINT8) ACPI_OFFSET (RSDP_DESCRIPTOR,f)
#define ACPI_FADT_FLAG_OFFSET(f, o) ACPI_FLAG_OFFSET (FADT_DESCRIPTOR,f,o)
#define ACPI_FACS_FLAG_OFFSET(f, o) ACPI_FLAG_OFFSET (FACS_DESCRIPTOR,f,o)
#endif /* __ACTBL_H__ */

View File

@ -0,0 +1,781 @@
/******************************************************************************
*
* Name: actbl1.h - Additional ACPI table definitions
* $Revision: 1.6 $
*
*****************************************************************************/
/******************************************************************************
*
* 1. Copyright Notice
*
* Some or all of this work - Copyright (c) 1999 - 2006, Intel Corp.
* All rights reserved.
*
* 2. License
*
* 2.1. This is your license from Intel Corp. under its intellectual property
* rights. You may have additional license terms from the party that provided
* you this software, covering your right to use that party's intellectual
* property rights.
*
* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
* copy of the source code appearing in this file ("Covered Code") an
* irrevocable, perpetual, worldwide license under Intel's copyrights in the
* base code distributed originally by Intel ("Original Intel Code") to copy,
* make derivatives, distribute, use and display any portion of the Covered
* Code in any form, with the right to sublicense such rights; and
*
* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
* license (with the right to sublicense), under only those claims of Intel
* patents that are infringed by the Original Intel Code, to make, use, sell,
* offer to sell, and import the Covered Code and derivative works thereof
* solely to the minimum extent necessary to exercise the above copyright
* license, and in no event shall the patent license extend to any additions
* to or modifications of the Original Intel Code. No other license or right
* is granted directly or by implication, estoppel or otherwise;
*
* The above copyright and patent license is granted only if the following
* conditions are met:
*
* 3. Conditions
*
* 3.1. Redistribution of Source with Rights to Further Distribute Source.
* Redistribution of source code of any substantial portion of the Covered
* Code or modification with rights to further distribute source must include
* the above Copyright Notice, the above License, this list of Conditions,
* and the following Disclaimer and Export Compliance provision. In addition,
* Licensee must cause all Covered Code to which Licensee contributes to
* contain a file documenting the changes Licensee made to create that Covered
* Code and the date of any change. Licensee must include in that file the
* documentation of any changes made by any predecessor Licensee. Licensee
* must include a prominent statement that the modification is derived,
* directly or indirectly, from Original Intel Code.
*
* 3.2. Redistribution of Source with no Rights to Further Distribute Source.
* Redistribution of source code of any substantial portion of the Covered
* Code or modification without rights to further distribute source must
* include the following Disclaimer and Export Compliance provision in the
* documentation and/or other materials provided with distribution. In
* addition, Licensee may not authorize further sublicense of source of any
* portion of the Covered Code, and must include terms to the effect that the
* license from Licensee to its licensee is limited to the intellectual
* property embodied in the software Licensee provides to its licensee, and
* not to intellectual property embodied in modifications its licensee may
* make.
*
* 3.3. Redistribution of Executable. Redistribution in executable form of any
* substantial portion of the Covered Code or modification must reproduce the
* above Copyright Notice, and the following Disclaimer and Export Compliance
* provision in the documentation and/or other materials provided with the
* distribution.
*
* 3.4. Intel retains all right, title, and interest in and to the Original
* Intel Code.
*
* 3.5. Neither the name Intel nor any other trademark owned or controlled by
* Intel shall be used in advertising or otherwise to promote the sale, use or
* other dealings in products derived from or relating to the Covered Code
* without prior written authorization from Intel.
*
* 4. Disclaimer and Export Compliance
*
* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
* LIMITED REMEDY.
*
* 4.3. Licensee shall not export, either directly or indirectly, any of this
* software or system incorporating such software without first obtaining any
* required license or other approval from the U. S. Department of Commerce or
* any other agency or department of the United States Government. In the
* event Licensee exports any such software from the United States or
* re-exports any such software from a foreign destination, Licensee shall
* ensure that the distribution and export/re-export of the software is in
* compliance with all laws, regulations, orders, or other restrictions of the
* U.S. Export Administration Regulations. Licensee agrees that neither it nor
* any of its subsidiaries will export/re-export any technical data, process,
* software, or service, directly or indirectly, to any country for which the
* United States government or any agency thereof requires an export license,
* other governmental approval, or letter of assurance, without first obtaining
* such license, approval or letter.
*
*****************************************************************************/
#ifndef __ACTBL1_H__
#define __ACTBL1_H__
/*******************************************************************************
*
* Additional ACPI Tables
*
* These tables are not consumed directly by the ACPICA subsystem, but are
* included here to support device drivers and the AML disassembler.
*
******************************************************************************/
/*
* Values for description table header signatures. Useful because they make
* it more difficult to inadvertently type in the wrong signature.
*/
#define ACPI_SIG_ASF "ASF!" /* Alert Standard Format table */
#define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */
#define ACPI_SIG_CPEP "CPEP" /* Corrected Platform Error Polling table */
#define ACPI_SIG_DBGP "DBGP" /* Debug Port table */
#define ACPI_SIG_ECDT "ECDT" /* Embedded Controller Boot Resources Table */
#define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */
#define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */
#define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */
#define ACPI_SIG_SBST "SBST" /* Smart Battery Specification Table */
#define ACPI_SIG_SLIT "SLIT" /* System Locality Distance Information Table */
#define ACPI_SIG_SPCR "SPCR" /* Serial Port Console Redirection table */
#define ACPI_SIG_SPMI "SPMI" /* Server Platform Management Interface table */
#define ACPI_SIG_SRAT "SRAT" /* System Resource Affinity Table */
#define ACPI_SIG_TCPA "TCPA" /* Trusted Computing Platform Alliance table */
#define ACPI_SIG_WDRT "WDRT" /* Watchdog Resource Table */
/* Legacy names */
#define APIC_SIG "APIC" /* Multiple APIC Description Table */
#define BOOT_SIG "BOOT" /* Simple Boot Flag Table */
#define SBST_SIG "SBST" /* Smart Battery Specification Table */
/*
* All tables must be byte-packed to match the ACPI specification, since
* the tables are provided by the system BIOS.
*/
#pragma pack(1)
/*
* Note about bitfields: The UINT8 type is used for bitfields in ACPI tables.
* This is the only type that is even remotely portable. Anything else is not
* portable, so do not use any other bitfield types.
*/
/*******************************************************************************
*
* ASF - Alert Standard Format table (Signature "ASF!")
*
******************************************************************************/
typedef struct acpi_table_asf {
ACPI_TABLE_HEADER_DEF
} ACPI_TABLE_ASF;
#define ACPI_ASF_HEADER_DEF \
UINT8 Type; \
UINT8 Reserved; \
UINT16 Length;
typedef struct acpi_asf_header {
ACPI_ASF_HEADER_DEF
} ACPI_ASF_HEADER;
/* Values for Type field */
#define ASF_INFO 0
#define ASF_ALERT 1
#define ASF_CONTROL 2
#define ASF_BOOT 3
#define ASF_ADDRESS 4
#define ASF_RESERVED 5
/*
* ASF subtables
*/
/* 0: ASF Information */
typedef struct acpi_asf_info {
ACPI_ASF_HEADER_DEF
UINT8 MinResetValue;
UINT8 MinPollInterval;
UINT16 SystemId;
UINT32 MfgId;
UINT8 Flags;
UINT8 Reserved2[3];
} ACPI_ASF_INFO;
/* 1: ASF Alerts */
typedef struct acpi_asf_alert {
ACPI_ASF_HEADER_DEF
UINT8 AssertMask;
UINT8 DeassertMask;
UINT8 Alerts;
UINT8 DataLength;
UINT8 Array[1];
} ACPI_ASF_ALERT;
/* 2: ASF Remote Control */
typedef struct acpi_asf_remote {
ACPI_ASF_HEADER_DEF
UINT8 Controls;
UINT8 DataLength;
UINT16 Reserved2;
UINT8 Array[1];
} ACPI_ASF_REMOTE;
/* 3: ASF RMCP Boot Options */
typedef struct acpi_asf_rmcp {
ACPI_ASF_HEADER_DEF
UINT8 Capabilities[7];
UINT8 CompletionCode;
UINT32 EnterpriseId;
UINT8 Command;
UINT16 Parameter;
UINT16 BootOptions;
UINT16 OemParameters;
} ACPI_ASF_RMCP;
/* 4: ASF Address */
typedef struct acpi_asf_address {
ACPI_ASF_HEADER_DEF
UINT8 EpromAddress;
UINT8 Devices;
UINT8 SmbusAddresses[1];
} ACPI_ASF_ADDRESS;
/*******************************************************************************
*
* BOOT - Simple Boot Flag Table
*
******************************************************************************/
typedef struct acpi_table_boot {
ACPI_TABLE_HEADER_DEF
UINT8 CmosIndex; /* Index in CMOS RAM for the boot register */
UINT8 Reserved[3];
} ACPI_TABLE_BOOT;
/*******************************************************************************
*
* CPEP - Corrected Platform Error Polling table
*
******************************************************************************/
typedef struct acpi_table_cpep {
ACPI_TABLE_HEADER_DEF
UINT64 Reserved;
} ACPI_TABLE_CPEP;
/* Subtable */
typedef struct acpi_cpep_polling {
UINT8 Type;
UINT8 Length;
UINT8 ProcessorId; /* Processor ID */
UINT8 ProcessorEid; /* Processor EID */
UINT32 PollingInterval;/* Polling interval (msec) */
} ACPI_CPEP_POLLING;
/*******************************************************************************
*
* DBGP - Debug Port table
*
******************************************************************************/
typedef struct acpi_table_dbgp {
ACPI_TABLE_HEADER_DEF
UINT8 InterfaceType; /* 0=full 16550, 1=subset of 16550 */
UINT8 Reserved[3];
ACPI_GENERIC_ADDRESS DebugPort;
} ACPI_TABLE_DBGP;
/*******************************************************************************
*
* ECDT - Embedded Controller Boot Resources Table
*
******************************************************************************/
typedef struct ec_boot_resources {
ACPI_TABLE_HEADER_DEF
ACPI_GENERIC_ADDRESS EcControl; /* Address of EC command/status register */
ACPI_GENERIC_ADDRESS EcData; /* Address of EC data register */
UINT32 Uid; /* Unique ID - must be same as the EC _UID method */
UINT8 GpeBit; /* The GPE for the EC */
UINT8 EcId[1]; /* Full namepath of the EC in the ACPI namespace */
} EC_BOOT_RESOURCES;
/*******************************************************************************
*
* HPET - High Precision Event Timer table
*
******************************************************************************/
typedef struct acpi_hpet_table {
ACPI_TABLE_HEADER_DEF
UINT32 HardwareId; /* Hardware ID of event timer block */
ACPI_GENERIC_ADDRESS BaseAddress; /* Address of event timer block */
UINT8 HpetNumber; /* HPET sequence number */
UINT16 ClockTick; /* Main counter min tick, periodic mode */
UINT8 Attributes;
} HPET_TABLE;
#if 0 /* HPET flags to be converted to macros */
struct /* Flags (8 bits) */
{
UINT8 PageProtect :1;/* 00: No page protection */
UINT8 PageProtect4 :1;/* 01: 4KB page protected */
UINT8 PageProtect64 :1;/* 02: 64KB page protected */
UINT8 :5;/* 03-07: Reserved, must be zero */
} Flags;
#endif
/*******************************************************************************
*
* MADT - Multiple APIC Description Table
*
******************************************************************************/
typedef struct multiple_apic_table {
ACPI_TABLE_HEADER_DEF
UINT32 LocalApicAddress;/* Physical address of local APIC */
/* Flags (32 bits) */
UINT8 PCATCompat : 1;/* 00: System also has dual 8259s */
UINT8 : 7;/* 01-07: Reserved, must be zero */
UINT8 Reserved1[3]; /* 08-31: Reserved, must be zero */
} MULTIPLE_APIC_TABLE;
/* Values for MADT PCATCompat */
#define DUAL_PIC 0
#define MULTIPLE_APIC 1
/* Common MADT Sub-table header */
#define APIC_HEADER_DEF \
UINT8 Type; \
UINT8 Length;
typedef struct apic_header {
APIC_HEADER_DEF
} APIC_HEADER;
/* Values for Type in APIC_HEADER */
#define APIC_PROCESSOR 0
#define APIC_IO 1
#define APIC_XRUPT_OVERRIDE 2
#define APIC_NMI 3
#define APIC_LOCAL_NMI 4
#define APIC_ADDRESS_OVERRIDE 5
#define APIC_IO_SAPIC 6
#define APIC_LOCAL_SAPIC 7
#define APIC_XRUPT_SOURCE 8
#define APIC_RESERVED 9 /* 9 and greater are reserved */
/* Flag definitions for MADT sub-tables */
#define ACPI_MADT_IFLAGS /* INTI flags (16 bits) */ \
UINT8 Polarity : 2; /* 00-01: Polarity of APIC I/O input signals */ \
UINT8 TriggerMode : 2; /* 02-03: Trigger mode of APIC input signals */ \
UINT8 : 4; /* 04-07: Reserved, must be zero */ \
UINT8 Reserved1; /* 08-15: Reserved, must be zero */
#define ACPI_MADT_LFLAGS /* Local Sapic flags (32 bits) */ \
UINT8 ProcessorEnabled: 1; /* 00: Processor is usable if set */ \
UINT8 : 7; /* 01-07: Reserved, must be zero */ \
UINT8 Reserved2[3]; /* 08-31: Reserved, must be zero */
/* Values for MPS INTI flags */
#define POLARITY_CONFORMS 0
#define POLARITY_ACTIVE_HIGH 1
#define POLARITY_RESERVED 2
#define POLARITY_ACTIVE_LOW 3
#define TRIGGER_CONFORMS 0
#define TRIGGER_EDGE 1
#define TRIGGER_RESERVED 2
#define TRIGGER_LEVEL 3
/*
* MADT Sub-tables, correspond to Type in APIC_HEADER
*/
/* 0: processor APIC */
typedef struct madt_processor_apic {
APIC_HEADER_DEF
UINT8 ProcessorId; /* ACPI processor id */
UINT8 LocalApicId; /* Processor's local APIC id */
ACPI_MADT_LFLAGS
} MADT_PROCESSOR_APIC;
/* 1: IO APIC */
typedef struct madt_io_apic {
APIC_HEADER_DEF
UINT8 IoApicId; /* I/O APIC ID */
UINT8 Reserved; /* Reserved - must be zero */
UINT32 Address; /* APIC physical address */
UINT32 Interrupt; /* Global system interrupt where INTI lines start */
} MADT_IO_APIC;
/* 2: Interrupt Override */
typedef struct madt_interrupt_override {
APIC_HEADER_DEF
UINT8 Bus; /* 0 - ISA */
UINT8 Source; /* Interrupt source (IRQ) */
UINT32 Interrupt; /* Global system interrupt */
ACPI_MADT_IFLAGS
} MADT_INTERRUPT_OVERRIDE;
/* 3: NMI Sources */
typedef struct madt_nmi_source {
APIC_HEADER_DEF
ACPI_MADT_IFLAGS
UINT32 Interrupt; /* Global system interrupt */
} MADT_NMI_SOURCE;
/* 4: Local APIC NMI */
typedef struct madt_local_apic_nmi {
APIC_HEADER_DEF
UINT8 ProcessorId; /* ACPI processor id */
ACPI_MADT_IFLAGS
UINT8 Lint; /* LINTn to which NMI is connected */
} MADT_LOCAL_APIC_NMI;
/* 5: Address Override */
typedef struct madt_address_override {
APIC_HEADER_DEF
UINT16 Reserved; /* Reserved, must be zero */
UINT64 Address; /* APIC physical address */
} MADT_ADDRESS_OVERRIDE;
/* 6: I/O Sapic */
typedef struct madt_io_sapic {
APIC_HEADER_DEF
UINT8 IoSapicId; /* I/O SAPIC ID */
UINT8 Reserved; /* Reserved, must be zero */
UINT32 InterruptBase; /* Glocal interrupt for SAPIC start */
UINT64 Address; /* SAPIC physical address */
} MADT_IO_SAPIC;
/* 7: Local Sapic */
typedef struct madt_local_sapic {
APIC_HEADER_DEF
UINT8 ProcessorId; /* ACPI processor id */
UINT8 LocalSapicId; /* SAPIC ID */
UINT8 LocalSapicEid; /* SAPIC EID */
UINT8 Reserved[3]; /* Reserved, must be zero */
ACPI_MADT_LFLAGS
UINT32 ProcessorUID; /* Numeric UID - ACPI 3.0 */
char ProcessorUIDString[1];/* String UID - ACPI 3.0 */
} MADT_LOCAL_SAPIC;
/* 8: Platform Interrupt Source */
typedef struct madt_interrupt_source {
APIC_HEADER_DEF
ACPI_MADT_IFLAGS
UINT8 InterruptType; /* 1=PMI, 2=INIT, 3=corrected */
UINT8 ProcessorId; /* Processor ID */
UINT8 ProcessorEid; /* Processor EID */
UINT8 IoSapicVector; /* Vector value for PMI interrupts */
UINT32 Interrupt; /* Global system interrupt */
UINT32 Flags; /* Interrupt Source Flags */
} MADT_INTERRUPT_SOURCE;
/*******************************************************************************
*
* MCFG - PCI Memory Mapped Configuration table and sub-table
*
******************************************************************************/
typedef struct acpi_table_mcfg {
ACPI_TABLE_HEADER_DEF
UINT8 Reserved[8];
} ACPI_TABLE_MCFG;
typedef struct acpi_mcfg_allocation {
UINT64 BaseAddress; /* Base address, processor-relative */
UINT16 PciSegment; /* PCI segment group number */
UINT8 StartBusNumber; /* Starting PCI Bus number */
UINT8 EndBusNumber; /* Final PCI Bus number */
UINT32 Reserved;
} ACPI_MCFG_ALLOCATION;
/*******************************************************************************
*
* SBST - Smart Battery Specification Table
*
******************************************************************************/
typedef struct smart_battery_table {
ACPI_TABLE_HEADER_DEF
UINT32 WarningLevel;
UINT32 LowLevel;
UINT32 CriticalLevel;
} SMART_BATTERY_TABLE;
/*******************************************************************************
*
* SLIT - System Locality Distance Information Table
*
******************************************************************************/
typedef struct system_locality_info {
ACPI_TABLE_HEADER_DEF
UINT64 LocalityCount;
UINT8 Entry[1][1];
} SYSTEM_LOCALITY_INFO;
/*******************************************************************************
*
* SPCR - Serial Port Console Redirection table
*
******************************************************************************/
typedef struct acpi_table_spcr {
ACPI_TABLE_HEADER_DEF
UINT8 InterfaceType; /* 0=full 16550, 1=subset of 16550 */
UINT8 Reserved[3];
ACPI_GENERIC_ADDRESS SerialPort;
UINT8 InterruptType;
UINT8 PcInterrupt;
UINT32 Interrupt;
UINT8 BaudRate;
UINT8 Parity;
UINT8 StopBits;
UINT8 FlowControl;
UINT8 TerminalType;
UINT8 Reserved2;
UINT16 PciDeviceId;
UINT16 PciVendorId;
UINT8 PciBus;
UINT8 PciDevice;
UINT8 PciFunction;
UINT32 PciFlags;
UINT8 PciSegment;
UINT32 Reserved3;
} ACPI_TABLE_SPCR;
/*******************************************************************************
*
* SPMI - Server Platform Management Interface table
*
******************************************************************************/
typedef struct acpi_table_spmi {
ACPI_TABLE_HEADER_DEF
UINT8 Reserved;
UINT8 InterfaceType;
UINT16 SpecRevision; /* Version of IPMI */
UINT8 InterruptType;
UINT8 GpeNumber; /* GPE assigned */
UINT8 Reserved2;
UINT8 PciDeviceFlag;
UINT32 Interrupt;
ACPI_GENERIC_ADDRESS IpmiRegister;
UINT8 PciSegment;
UINT8 PciBus;
UINT8 PciDevice;
UINT8 PciFunction;
} ACPI_TABLE_SPMI;
/*******************************************************************************
*
* SRAT - System Resource Affinity Table
*
******************************************************************************/
typedef struct system_resource_affinity {
ACPI_TABLE_HEADER_DEF
UINT32 Reserved1; /* Must be value '1' */
UINT64 Reserved2; /* Reserved, must be zero */
} SYSTEM_RESOURCE_AFFINITY;
/* SRAT common sub-table header */
#define SRAT_SUBTABLE_HEADER \
UINT8 Type; \
UINT8 Length;
/* Values for Type above */
#define SRAT_CPU_AFFINITY 0
#define SRAT_MEMORY_AFFINITY 1
#define SRAT_RESERVED 2
/* SRAT sub-tables */
typedef struct static_resource_alloc {
SRAT_SUBTABLE_HEADER
UINT8 ProximityDomainLo;
UINT8 ApicId;
/* Flags (32 bits) */
UINT8 Enabled :1;/* 00: Use affinity structure */
UINT8 :7;/* 01-07: Reserved, must be zero */
UINT8 Reserved3[3]; /* 08-31: Reserved, must be zero */
UINT8 LocalSapicEid;
UINT8 ProximityDomainHi[3];
UINT32 Reserved4; /* Reserved, must be zero */
} STATIC_RESOURCE_ALLOC;
typedef struct memory_affinity {
SRAT_SUBTABLE_HEADER
UINT32 ProximityDomain;
UINT16 Reserved3;
UINT64 BaseAddress;
UINT64 AddressLength;
UINT32 Reserved4;
/* Flags (32 bits) */
UINT8 Enabled :1;/* 00: Use affinity structure */
UINT8 HotPluggable :1;/* 01: Memory region is hot pluggable */
UINT8 NonVolatile :1;/* 02: Memory is non-volatile */
UINT8 :5;/* 03-07: Reserved, must be zero */
UINT8 Reserved5[3]; /* 08-31: Reserved, must be zero */
UINT64 Reserved6; /* Reserved, must be zero */
} MEMORY_AFFINITY;
/*******************************************************************************
*
* TCPA - Trusted Computing Platform Alliance table
*
******************************************************************************/
typedef struct acpi_table_tcpa {
ACPI_TABLE_HEADER_DEF
UINT16 Reserved;
UINT32 MaxLogLength; /* Maximum length for the event log area */
UINT64 LogAddress; /* Address of the event log area */
} ACPI_TABLE_TCPA;
/*******************************************************************************
*
* WDRT - Watchdog Resource Table
*
******************************************************************************/
typedef struct acpi_table_wdrt {
ACPI_TABLE_HEADER_DEF
UINT32 HeaderLength; /* Watchdog Header Length */
UINT8 PciSegment; /* PCI Segment number */
UINT8 PciBus; /* PCI Bus number */
UINT8 PciDevice; /* PCI Device number */
UINT8 PciFunction; /* PCI Function number */
UINT32 TimerPeriod; /* Period of one timer count (msec) */
UINT32 MaxCount; /* Maximum counter value supported */
UINT32 MinCount; /* Minimum counter value */
UINT8 Flags;
UINT8 Reserved[3];
UINT32 Entries; /* Number of watchdog entries that follow */
} ACPI_TABLE_WDRT;
#if 0 /* Flags, will be converted to macros */
UINT8 Enabled :1; /* 00: Timer enabled */
UINT8 :6; /* 01-06: Reserved */
UINT8 SleepStop :1; /* 07: Timer stopped in sleep state */
#endif
/* Macros used to generate offsets to specific table fields */
#define ACPI_ASF0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_ASF_INFO,f)
#define ACPI_ASF1_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_ASF_ALERT,f)
#define ACPI_ASF2_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_ASF_REMOTE,f)
#define ACPI_ASF3_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_ASF_RMCP,f)
#define ACPI_ASF4_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_ASF_ADDRESS,f)
#define ACPI_BOOT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_BOOT,f)
#define ACPI_CPEP_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_CPEP,f)
#define ACPI_CPEP0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_CPEP_POLLING,f)
#define ACPI_DBGP_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_DBGP,f)
#define ACPI_ECDT_OFFSET(f) (UINT8) ACPI_OFFSET (EC_BOOT_RESOURCES,f)
#define ACPI_HPET_OFFSET(f) (UINT8) ACPI_OFFSET (HPET_TABLE,f)
#define ACPI_MADT_OFFSET(f) (UINT8) ACPI_OFFSET (MULTIPLE_APIC_TABLE,f)
#define ACPI_MADT0_OFFSET(f) (UINT8) ACPI_OFFSET (MADT_PROCESSOR_APIC,f)
#define ACPI_MADT1_OFFSET(f) (UINT8) ACPI_OFFSET (MADT_IO_APIC,f)
#define ACPI_MADT2_OFFSET(f) (UINT8) ACPI_OFFSET (MADT_INTERRUPT_OVERRIDE,f)
#define ACPI_MADT3_OFFSET(f) (UINT8) ACPI_OFFSET (MADT_NMI_SOURCE,f)
#define ACPI_MADT4_OFFSET(f) (UINT8) ACPI_OFFSET (MADT_LOCAL_APIC_NMI,f)
#define ACPI_MADT5_OFFSET(f) (UINT8) ACPI_OFFSET (MADT_ADDRESS_OVERRIDE,f)
#define ACPI_MADT6_OFFSET(f) (UINT8) ACPI_OFFSET (MADT_IO_SAPIC,f)
#define ACPI_MADT7_OFFSET(f) (UINT8) ACPI_OFFSET (MADT_LOCAL_SAPIC,f)
#define ACPI_MADT8_OFFSET(f) (UINT8) ACPI_OFFSET (MADT_INTERRUPT_SOURCE,f)
#define ACPI_MADTH_OFFSET(f) (UINT8) ACPI_OFFSET (APIC_HEADER,f)
#define ACPI_MCFG_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_MCFG,f)
#define ACPI_MCFG0_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_MCFG_ALLOCATION,f)
#define ACPI_SBST_OFFSET(f) (UINT8) ACPI_OFFSET (SMART_BATTERY_TABLE,f)
#define ACPI_SLIT_OFFSET(f) (UINT8) ACPI_OFFSET (SYSTEM_LOCALITY_INFO,f)
#define ACPI_SPCR_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_SPCR,f)
#define ACPI_SPMI_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_SPMI,f)
#define ACPI_SRAT_OFFSET(f) (UINT8) ACPI_OFFSET (SYSTEM_RESOURCE_AFFINITY,f)
#define ACPI_SRAT0_OFFSET(f) (UINT8) ACPI_OFFSET (STATIC_RESOURCE_ALLOC,f)
#define ACPI_SRAT1_OFFSET(f) (UINT8) ACPI_OFFSET (MEMORY_AFFINITY,f)
#define ACPI_TCPA_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_TCPA,f)
#define ACPI_WDRT_OFFSET(f) (UINT8) ACPI_OFFSET (ACPI_TABLE_WDRT,f)
#define ACPI_HPET_FLAG_OFFSET(f, o) ACPI_FLAG_OFFSET (HPET_TABLE,f,o)
#define ACPI_SRAT0_FLAG_OFFSET(f, o) ACPI_FLAG_OFFSET (STATIC_RESOURCE_ALLOC,f,o)
#define ACPI_SRAT1_FLAG_OFFSET(f, o) ACPI_FLAG_OFFSET (MEMORY_AFFINITY,f,o)
#define ACPI_MADT_FLAG_OFFSET(f, o) ACPI_FLAG_OFFSET (MULTIPLE_APIC_TABLE,f,o)
#define ACPI_MADT0_FLAG_OFFSET(f, o) ACPI_FLAG_OFFSET (MADT_PROCESSOR_APIC,f,o)
#define ACPI_MADT2_FLAG_OFFSET(f, o) ACPI_FLAG_OFFSET (MADT_INTERRUPT_OVERRIDE,f,o)
#define ACPI_MADT3_FLAG_OFFSET(f, o) ACPI_FLAG_OFFSET (MADT_NMI_SOURCE,f,o)
#define ACPI_MADT4_FLAG_OFFSET(f, o) ACPI_FLAG_OFFSET (MADT_LOCAL_APIC_NMI,f,o)
#define ACPI_MADT7_FLAG_OFFSET(f, o) ACPI_FLAG_OFFSET (MADT_LOCAL_SAPIC,f,o)
#define ACPI_MADT8_FLAG_OFFSET(f, o) ACPI_FLAG_OFFSET (MADT_INTERRUPT_SOURCE,f,o)
/* Reset to default packing */
#pragma pack()
#endif /* __ACTBL1_H__ */

View File

@ -0,0 +1,36 @@
export MakeInc_cmd=${SRCROOT}/makedefs/MakeInc.cmd
export MakeInc_def=${SRCROOT}/makedefs/MakeInc.def
export MakeInc_rule=${SRCROOT}/makedefs/MakeInc.rule
export MakeInc_dir=${SRCROOT}/makedefs/MakeInc.dir
include $(MakeInc_cmd)
include $(MakeInc_def)
INSTINC_SUBDIRS =
INSTINC_SUBDIRS_X86_64 = \
i386
INSTINC_SUBDIRS_X86_64H = \
i386
INSTINC_SUBDIRS_ARM = \
arm
INSTINC_SUBDIRS_ARM64 = \
arm
EXPORT_FILES =
INSTALL_MI_LIST =
INSTALL_MI_DIR = architecture
INSTALL_KF_MI_LIST = byte_order.h
EXPORT_MI_LIST = ${EXPORT_FILES}
EXPORT_MI_DIR = architecture
include $(MakeInc_rule)
include $(MakeInc_dir)

View File

@ -0,0 +1,20 @@
export MakeInc_cmd=${SRCROOT}/makedefs/MakeInc.cmd
export MakeInc_def=${SRCROOT}/makedefs/MakeInc.def
export MakeInc_rule=${SRCROOT}/makedefs/MakeInc.rule
export MakeInc_dir=${SRCROOT}/makedefs/MakeInc.dir
include $(MakeInc_cmd)
include $(MakeInc_def)
EXPORT_FILES =
INSTALL_MD_LIST =
INSTALL_MD_DIR =
EXPORT_MD_LIST = ${EXPORT_FILES}
EXPORT_MD_DIR = architecture/arm
include $(MakeInc_rule)
include $(MakeInc_dir)

View File

@ -0,0 +1,371 @@
/*
* Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License."
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 1992 NeXT Computer, Inc.
*
* Byte ordering conversion.
*
*/
#ifndef _ARCHITECTURE_BYTE_ORDER_H_
#define _ARCHITECTURE_BYTE_ORDER_H_
#include <libkern/OSByteOrder.h>
typedef unsigned long NXSwappedFloat;
typedef unsigned long long NXSwappedDouble;
static __inline__
unsigned short
NXSwapShort(
unsigned short inv
)
{
return (unsigned short)OSSwapInt16((uint16_t)inv);
}
static __inline__
unsigned int
NXSwapInt(
unsigned int inv
)
{
return (unsigned int)OSSwapInt32((uint32_t)inv);
}
static __inline__
unsigned long
NXSwapLong(
unsigned long inv
)
{
return (unsigned long)OSSwapInt32((uint32_t)inv);
}
static __inline__
unsigned long long
NXSwapLongLong(
unsigned long long inv
)
{
return (unsigned long long)OSSwapInt64((uint64_t)inv);
}
static __inline__ NXSwappedFloat
NXConvertHostFloatToSwapped(float x)
{
union fconv {
float number;
NXSwappedFloat sf;
} u;
u.number = x;
return u.sf;
}
static __inline__ float
NXConvertSwappedFloatToHost(NXSwappedFloat x)
{
union fconv {
float number;
NXSwappedFloat sf;
} u;
u.sf = x;
return u.number;
}
static __inline__ NXSwappedDouble
NXConvertHostDoubleToSwapped(double x)
{
union dconv {
double number;
NXSwappedDouble sd;
} u;
u.number = x;
return u.sd;
}
static __inline__ double
NXConvertSwappedDoubleToHost(NXSwappedDouble x)
{
union dconv {
double number;
NXSwappedDouble sd;
} u;
u.sd = x;
return u.number;
}
static __inline__ NXSwappedFloat
NXSwapFloat(NXSwappedFloat x)
{
return (NXSwappedFloat)OSSwapInt32((uint32_t)x);
}
static __inline__ NXSwappedDouble
NXSwapDouble(NXSwappedDouble x)
{
return (NXSwappedDouble)OSSwapInt64((uint64_t)x);
}
/*
* Identify the byte order
* of the current host.
*/
enum NXByteOrder {
NX_UnknownByteOrder,
NX_LittleEndian,
NX_BigEndian
};
static __inline__
enum NXByteOrder
NXHostByteOrder(void)
{
#if defined(__LITTLE_ENDIAN__)
return NX_LittleEndian;
#elif defined(__BIG_ENDIAN__)
return NX_BigEndian;
#else
return NX_UnknownByteOrder;
#endif
}
static __inline__
unsigned short
NXSwapBigShortToHost(
unsigned short x
)
{
return (unsigned short)OSSwapBigToHostInt16((uint16_t)x);
}
static __inline__
unsigned int
NXSwapBigIntToHost(
unsigned int x
)
{
return (unsigned int)OSSwapBigToHostInt32((uint32_t)x);
}
static __inline__
unsigned long
NXSwapBigLongToHost(
unsigned long x
)
{
return (unsigned long)OSSwapBigToHostInt32((uint32_t)x);
}
static __inline__
unsigned long long
NXSwapBigLongLongToHost(
unsigned long long x
)
{
return (unsigned long long)OSSwapBigToHostInt64((uint64_t)x);
}
static __inline__
double
NXSwapBigDoubleToHost(
NXSwappedDouble x
)
{
return NXConvertSwappedDoubleToHost((NXSwappedDouble)OSSwapBigToHostInt64((uint64_t)x));
}
static __inline__
float
NXSwapBigFloatToHost(
NXSwappedFloat x
)
{
return NXConvertSwappedFloatToHost((NXSwappedFloat)OSSwapBigToHostInt32((uint32_t)x));
}
static __inline__
unsigned short
NXSwapHostShortToBig(
unsigned short x
)
{
return (unsigned short)OSSwapHostToBigInt16((uint16_t)x);
}
static __inline__
unsigned int
NXSwapHostIntToBig(
unsigned int x
)
{
return (unsigned int)OSSwapHostToBigInt32((uint32_t)x);
}
static __inline__
unsigned long
NXSwapHostLongToBig(
unsigned long x
)
{
return (unsigned long)OSSwapHostToBigInt32((uint32_t)x);
}
static __inline__
unsigned long long
NXSwapHostLongLongToBig(
unsigned long long x
)
{
return (unsigned long long)OSSwapHostToBigInt64((uint64_t)x);
}
static __inline__
NXSwappedDouble
NXSwapHostDoubleToBig(
double x
)
{
return (NXSwappedDouble)OSSwapHostToBigInt64((uint64_t)NXConvertHostDoubleToSwapped(x));
}
static __inline__
NXSwappedFloat
NXSwapHostFloatToBig(
float x
)
{
return (NXSwappedFloat)OSSwapHostToBigInt32((uint32_t)NXConvertHostFloatToSwapped(x));
}
static __inline__
unsigned short
NXSwapLittleShortToHost(
unsigned short x
)
{
return (unsigned short)OSSwapLittleToHostInt16((uint16_t)x);
}
static __inline__
unsigned int
NXSwapLittleIntToHost(
unsigned int x
)
{
return (unsigned int)OSSwapLittleToHostInt32((uint32_t)x);
}
static __inline__
unsigned long
NXSwapLittleLongToHost(
unsigned long x
)
{
return (unsigned long)OSSwapLittleToHostInt32((uint32_t)x);
}
static __inline__
unsigned long long
NXSwapLittleLongLongToHost(
unsigned long long x
)
{
return (unsigned long long)OSSwapLittleToHostInt64((uint64_t)x);
}
static __inline__
double
NXSwapLittleDoubleToHost(
NXSwappedDouble x
)
{
return NXConvertSwappedDoubleToHost((NXSwappedDouble)OSSwapLittleToHostInt64((uint64_t)x));
}
static __inline__
float
NXSwapLittleFloatToHost(
NXSwappedFloat x
)
{
return NXConvertSwappedFloatToHost((NXSwappedFloat)OSSwapLittleToHostInt32((uint32_t)x));
}
static __inline__
unsigned short
NXSwapHostShortToLittle(
unsigned short x
)
{
return (unsigned short)OSSwapHostToLittleInt16((uint16_t)x);
}
static __inline__
unsigned int
NXSwapHostIntToLittle(
unsigned int x
)
{
return (unsigned int)OSSwapHostToLittleInt32((uint32_t)x);
}
static __inline__
unsigned long
NXSwapHostLongToLittle(
unsigned long x
)
{
return (unsigned long)OSSwapHostToLittleInt32((uint32_t)x);
}
static __inline__
unsigned long long
NXSwapHostLongLongToLittle(
unsigned long long x
)
{
return (unsigned long long)OSSwapHostToLittleInt64((uint64_t)x);
}
static __inline__
NXSwappedDouble
NXSwapHostDoubleToLittle(
double x
)
{
return (NXSwappedDouble)OSSwapHostToLittleInt64((uint64_t)NXConvertHostDoubleToSwapped(x));
}
static __inline__
NXSwappedFloat
NXSwapHostFloatToLittle(
float x
)
{
return (NXSwappedFloat)OSSwapHostToLittleInt32((uint32_t)NXConvertHostFloatToSwapped(x));
}
#endif /* _ARCHITECTURE_BYTE_ORDER_H_ */

View File

@ -0,0 +1,29 @@
export MakeInc_cmd=${SRCROOT}/makedefs/MakeInc.cmd
export MakeInc_def=${SRCROOT}/makedefs/MakeInc.def
export MakeInc_rule=${SRCROOT}/makedefs/MakeInc.rule
export MakeInc_dir=${SRCROOT}/makedefs/MakeInc.dir
include $(MakeInc_cmd)
include $(MakeInc_def)
EXPORT_FILES = \
asm_help.h \
cpu.h \
io.h \
pio.h \
sel.h \
tss.h \
desc.h \
reg_help.h \
table.h
INSTALL_MD_LIST =
INSTALL_MD_DIR =
EXPORT_MD_LIST = ${EXPORT_FILES}
EXPORT_MD_DIR = architecture/i386
include $(MakeInc_rule)
include $(MakeInc_dir)

View File

@ -0,0 +1,327 @@
/*
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/* Copyright (c) 1991 NeXT Computer, Inc. All rights reserved.
*
* File: architecture/i386/asm_help.h
* Author: Mike DeMoney, NeXT Computer, Inc.
* Modified for i386 by: Bruce Martin, NeXT Computer, Inc.
*
* This header file defines macros useful when writing assembly code
* for the Intel i386 family processors.
*
* HISTORY
* 10-Mar-92 Bruce Martin (bmartin@next.com)
* Adapted to i386
* 23-Jan-91 Mike DeMoney (mike@next.com)
* Created.
*/
#ifndef _ARCH_I386_ASM_HELP_H_
#define _ARCH_I386_ASM_HELP_H_
#include <architecture/i386/reg_help.h>
#ifdef __ASSEMBLER__
#define ALIGN \
.align 2, 0x90
/* Note that ROUND_TO_STACK rounds to Intel's stack alignment requirement,
* but it is not sufficient for the Apple ABI which requires a 16-byte
* aligned stack. Various parts of the OS depend on this requirement,
* including dyld.
*/
#define ROUND_TO_STACK(len) \
(((len) + STACK_INCR - 1) / STACK_INCR * STACK_INCR)
#ifdef notdef
#define CALL_MCOUNT \
pushl %ebp ;\
movl %esp, %ebp ;\
.data ;\
1: .long 0 ;\
.text ;\
lea 9b,%edx ;\
call mcount ;\
popl %ebp ;
#else
#define CALL_MCOUNT
#endif
/*
* Prologue for functions that may call other functions. Saves
* registers and sets up a C frame.
*/
#define NESTED_FUNCTION_PROLOGUE(localvarsize) \
.set __framesize,ROUND_TO_STACK(localvarsize) ;\
.set __nested_function, 1 ;\
CALL_MCOUNT \
.if __framesize ;\
pushl %ebp ;\
movl %esp, %ebp ;\
subl $__framesize, %esp ;\
.endif ;\
pushl %edi ;\
pushl %esi ;\
pushl %ebx
/*
* Prologue for functions that do not call other functions. Does not
* save registers (this is the functions responsibility). Does set
* up a C frame.
*/
#define LEAF_FUNCTION_PROLOGUE(localvarsize) \
.set __framesize,ROUND_TO_STACK(localvarsize) ;\
.set __nested_function, 0 ;\
CALL_MCOUNT \
.if __framesize ;\
pushl %ebp ;\
movl %esp, %ebp ;\
subl $__framesize, %esp ;\
.endif
/*
* Prologue for any function.
*
* We assume that all Leaf functions will be responsible for saving any
* local registers they clobber.
*/
#define FUNCTION_EPILOGUE \
.if __nested_function ;\
popl %ebx ;\
popl %esi ;\
popl %edi ;\
.endif ;\
.if __framesize ;\
movl %ebp, %esp ;\
popl %ebp ;\
.endif ;\
ret
/*
* Macros for declaring procedures
*
* Use of these macros allows ctags to have a predictable way
* to find various types of declarations. They also simplify
* inserting appropriate symbol table information.
*
* NOTE: these simple stubs will be replaced with more
* complicated versions once we know what the linker and gdb
* will require as far as register use masks and frame declarations.
* These macros may also be ifdef'ed in the future to contain profiling
* code.
*
*/
/*
* TEXT -- declare start of text segment
*/
#define TEXT \
.text
/*
* DATA -- declare start of data segment
*/
#define DATA \
.data
/*
* LEAF -- declare global leaf procedure
* NOTE: Control SHOULD NOT FLOW into a LEAF! A LEAF should only
* be jumped to. (A leaf may do an align.) Use a LABEL() if you
* need control to flow into the label.
*/
#define LEAF(name, localvarsize) \
.globl name ;\
ALIGN ;\
name: ;\
LEAF_FUNCTION_PROLOGUE(localvarsize)
/*
* X_LEAF -- declare alternate global label for leaf
*/
#define X_LEAF(name, value) \
.globl name ;\
.set name,value
/*
* P_LEAF -- declare private leaf procedure
*/
#define P_LEAF(name, localvarsize) \
ALIGN ;\
name: ;\
LEAF_FUNCTION_PROLOGUE(localvarsize)
/*
* LABEL -- declare a global code label
* MUST be used (rather than LEAF, NESTED, etc) if control
* "flows into" the label.
*/
#define LABEL(name) \
.globl name ;\
name:
/*
* NESTED -- declare procedure that invokes other procedures
*/
#define NESTED(name, localvarsize) \
.globl name ;\
ALIGN ;\
name: ;\
NESTED_FUNCTION_PROLOGUE(localvarsize)
/*
* X_NESTED -- declare alternate global label for nested proc
*/
#define X_NESTED(name, value) \
.globl name ;\
.set name,value
/*
* P_NESTED -- declare private nested procedure
*/
#define P_NESTED(name, localvarsize) \
ALIGN ;\
name: ;\
NESTED_FUNCTION_PROLOGUE(localvarsize)
/*
* END -- mark end of procedure
*/
#define END(name) \
FUNCTION_EPILOGUE
/*
* Storage definition macros
* The main purpose of these is to allow an easy handle for ctags
*/
/*
* IMPORT -- import symbol
*/
#define IMPORT(name) \
.reference name
/*
* ABS -- declare global absolute symbol
*/
#define ABS(name, value) \
.globl name ;\
.set name,value
/*
* P_ABS -- declare private absolute symbol
*/
#define P_ABS(name, value) \
.set name,value
/*
* EXPORT -- declare global label for data
*/
#define EXPORT(name) \
.globl name ;\
name:
/*
* BSS -- declare global zero'ed storage
*/
#define BSS(name,size) \
.comm name,size
/*
* P_BSS -- declare private zero'ed storage
*/
#define P_BSS(name,size) \
.lcomm name,size
/*
* dynamic/PIC macros for routines which reference external symbols
*/
#if defined(__DYNAMIC__)
#define PICIFY(var) \
call 1f ; \
1: ; \
popl %edx ; \
movl L ## var ## $non_lazy_ptr-1b(%edx),%edx
#define CALL_EXTERN_AGAIN(func) \
PICIFY(func) ; \
call %edx
#define NON_LAZY_STUB(var) \
.non_lazy_symbol_pointer ; \
L ## var ## $non_lazy_ptr: ; \
.indirect_symbol var ; \
.long 0 ; \
.text
#define CALL_EXTERN(func) \
CALL_EXTERN_AGAIN(func) ; \
NON_LAZY_STUB(func)
#define BRANCH_EXTERN(func) \
PICIFY(func) ; \
jmp %edx ; \
NON_LAZY_STUB(func)
#define PUSH_EXTERN(var) \
PICIFY(var) ; \
movl (%edx),%edx ; \
pushl %edx ; \
NON_LAZY_STUB(var)
#define REG_TO_EXTERN(reg, var) \
PICIFY(var) ; \
movl reg, (%edx) ; \
NON_LAZY_STUB(var)
#define EXTERN_TO_REG(var, reg) \
call 1f ; \
1: ; \
popl %edx ; \
movl L ## var ##$non_lazy_ptr-1b(%edx),reg ; \
NON_LAZY_STUB(var)
#else
#define BRANCH_EXTERN(func) jmp func
#define PUSH_EXTERN(var) pushl var
#define CALL_EXTERN(func) call func
#define CALL_EXTERN_AGAIN(func) call func
#define REG_TO_EXTERN(reg, var) movl reg, var
#define EXTERN_TO_REG(var, reg) movl $ ## var, reg
#endif
#endif /* __ASSEMBLER__ */
#endif /* _ARCH_I386_ASM_HELP_H_ */

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 1992 NeXT Computer, Inc.
*
* Intel386 Family: Special processor registers.
*
* HISTORY
*
* 5 April 1992 ? at NeXT
* Created.
*/
/*
* Control register 0
*/
typedef struct _cr0 {
unsigned int pe :1,
mp :1,
em :1,
ts :1,
:1,
ne :1,
:10,
wp :1,
:1,
am :1,
:10,
nw :1,
cd :1,
pg :1;
} cr0_t;

View File

@ -0,0 +1,151 @@
/*
* Copyright (c) 2000-2019 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 1992 NeXT Computer, Inc.
*
* Intel386 Family: Segment descriptors.
*
* HISTORY
*
* 29 March 1992 ? at NeXT
* Created.
*/
/*
* Code segment descriptor.
*/
typedef struct code_desc {
unsigned short limit00;
unsigned short base00;
unsigned char base16;
unsigned char type :5,
#define DESC_CODE_EXEC 0x18
#define DESC_CODE_READ 0x1a
dpl :2,
present :1;
unsigned char limit16 :4,
:1,
Lflag :1,
opsz :1,
#define DESC_CODE_16B 0
#define DESC_CODE_32B 1
granular:1;
#define DESC_GRAN_BYTE 0
#define DESC_GRAN_PAGE 1
unsigned char base24;
} code_desc_t;
/*
* Data segment descriptor.
*/
typedef struct data_desc {
unsigned short limit00;
unsigned short base00;
unsigned char base16;
unsigned char type :5,
#define DESC_DATA_RONLY 0x10
#define DESC_DATA_WRITE 0x12
dpl :2,
present :1;
unsigned char limit16 :4,
:2,
stksz :1,
#define DESC_DATA_16B 0
#define DESC_DATA_32B 1
granular:1;
unsigned char base24;
} data_desc_t;
/*
* LDT segment descriptor.
*/
typedef struct ldt_desc {
unsigned short limit00;
unsigned short base00;
unsigned char base16;
unsigned char type :5,
#define DESC_LDT 0x02
:2,
present :1;
unsigned char limit16 :4,
:3,
granular:1;
unsigned char base24;
} ldt_desc_t;
#include <architecture/i386/sel.h>
/*
* Call gate descriptor.
*/
typedef struct call_gate {
unsigned short offset00;
sel_t seg;
unsigned int argcnt :5,
:3,
type :5,
#define DESC_CALL_GATE 0x0c
dpl :2,
present :1,
offset16:16;
} call_gate_t;
/*
* Trap gate descriptor.
*/
typedef struct trap_gate {
unsigned short offset00;
sel_t seg;
unsigned int :8,
type :5,
#define DESC_TRAP_GATE 0x0f
dpl :2,
present :1,
offset16:16;
} trap_gate_t;
/*
* Interrupt gate descriptor.
*/
typedef struct intr_gate {
unsigned short offset00;
sel_t seg;
unsigned int :8,
type :5,
#define DESC_INTR_GATE 0x0e
dpl :2,
present :1,
offset16:16;
} intr_gate_t;

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 1992 NeXT Computer, Inc.
*
* Intel 386 Family: IO space defines.
*
* HISTORY
*
* 11 August 1992 ? at NeXT
* Created.
*/
typedef unsigned short io_addr_t;
typedef unsigned short io_len_t;

View File

@ -0,0 +1,109 @@
/*
* Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* @OSF_COPYRIGHT@
*/
/*
* Mach Operating System
* Copyright (c) 1991,1990 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
*/
#ifndef _ARCH_I386_PIO_H_
#define _ARCH_I386_PIO_H_
typedef unsigned short i386_ioport_t;
#if defined(__GNUC__)
static __inline__ unsigned int inl(
i386_ioport_t port)
{
unsigned int datum;
__asm__ volatile("inl %w1, %0" : "=a" (datum) : "Nd" (port));
return(datum);
}
static __inline__ unsigned short inw(
i386_ioport_t port)
{
unsigned short datum;
__asm__ volatile("inw %w1, %w0" : "=a" (datum) : "Nd" (port));
return(datum);
}
static __inline__ unsigned char inb(
i386_ioport_t port)
{
unsigned char datum;
__asm__ volatile("inb %w1, %b0" : "=a" (datum) : "Nd" (port));
return(datum);
}
static __inline__ void outl(
i386_ioport_t port,
unsigned int datum)
{
__asm__ volatile("outl %0, %w1" : : "a" (datum), "Nd" (port));
}
static __inline__ void outw(
i386_ioport_t port,
unsigned short datum)
{
__asm__ volatile("outw %w0, %w1" : : "a" (datum), "Nd" (port));
}
static __inline__ void outb(
i386_ioport_t port,
unsigned char datum)
{
__asm__ volatile("outb %b0, %w1" : : "a" (datum), "Nd" (port));
}
#endif /* defined(__GNUC__) */
#endif /* _ARCH_I386_PIO_H_ */

View File

@ -0,0 +1,110 @@
/*
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/* Copyright (c) 1991 NeXT Computer, Inc. All rights reserved.
*
* File: architecture/i386/reg_help.h
* Author: Mike DeMoney, NeXT Computer, Inc.
* Modified for i386 by: Bruce Martin, NeXT Computer, Inc.
*
* This header file defines cpp macros useful for defining
* machine register and doing machine-level operations.
*
* HISTORY
* 10-Mar-92 Bruce Martin (bmartin@next.com)
* Adapted to i386
* 23-Jan-91 Mike DeMoney (mike@next.com)
* Created.
*/
#ifndef _ARCH_I386_REG_HELP_H_
#define _ARCH_I386_REG_HELP_H_
/* Bitfield definition aid */
#define BITS_WIDTH(msb, lsb) ((msb)-(lsb)+1)
#define BIT_WIDTH(pos) (1) /* mostly to record the position */
/* Mask creation */
#define MKMASK(width, offset) (((unsigned)-1)>>(32-(width))<<(offset))
#define BITSMASK(msb, lsb) MKMASK(BITS_WIDTH(msb, lsb), lsb & 0x1f)
#define BITMASK(pos) MKMASK(BIT_WIDTH(pos), pos & 0x1f)
/* Register addresses */
#if __ASSEMBLER__
# define REG_ADDR(type, addr) (addr)
#else /* __ASSEMBLER__ */
# define REG_ADDR(type, addr) (*(volatile type *)(addr))
#endif /* __ASSEMBLER__ */
/* Cast a register to be an unsigned */
#define CONTENTS(foo) (*(unsigned *) &(foo))
/* Stack pointer must always be a multiple of 4 */
#define STACK_INCR 4
#define ROUND_FRAME(x) ((((unsigned)(x)) + STACK_INCR - 1) & ~(STACK_INCR-1))
/* STRINGIFY -- perform all possible substitutions, then stringify */
#define __STR(x) #x /* just a helper macro */
#define STRINGIFY(x) __STR(x)
/*
* REG_PAIR_DEF -- define a register pair
* Register pairs are appropriately aligned to allow access via
* ld.d and st.d.
*
* Usage:
* struct foo {
* REG_PAIR_DEF(
* bar_t *, barp,
* afu_t, afu
* );
* };
*
* Access to individual entries of the pair is via the REG_PAIR
* macro (below).
*/
#define REG_PAIR_DEF(type0, name0, type1, name1) \
struct { \
type0 name0 __attribute__(( aligned(8) )); \
type1 name1; \
} name0##_##name1
/*
* REG_PAIR -- Macro to define names for accessing individual registers
* of register pairs.
*
* Usage:
* arg0 is first element of pair
* arg1 is second element of pair
* arg2 is desired element of pair
* eg:
* #define foo_barp REG_PAIR(barp, afu, afu)
*/
#define REG_PAIR(name0, name1, the_name) \
name0##_##name1.the_name
#endif /* _ARCH_I386_REG_HELP_H_ */

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 1992 NeXT Computer, Inc.
*
* Intel386 Family: Segment selector.
*
* HISTORY
*
* 29 March 1992 ? at NeXT
* Created.
*/
/*
* Segment selector.
*/
#ifndef __XNU_ARCH_I386_SEL_H
#define __XNU_ARCH_I386_SEL_H
typedef struct sel {
unsigned short rpl :2,
#define KERN_PRIV 0
#define USER_PRIV 3
ti :1,
#define SEL_GDT 0
#define SEL_LDT 1
index :13;
} sel_t;
#define NULL_SEL ((sel_t) { 0, 0, 0 } )
#endif /* __XNU_ARCH_I386_SEL_H */

View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 1992 NeXT Computer, Inc.
*
* Intel386 Family: Descriptor tables.
*
* HISTORY
*
* 30 March 1992 ? at NeXT
* Created.
*/
#include <architecture/i386/desc.h>
#include <architecture/i386/tss.h>
/*
* A totally generic descriptor
* table entry.
*/
typedef union dt_entry {
code_desc_t code;
data_desc_t data;
ldt_desc_t ldt;
tss_desc_t task_state;
call_gate_t call_gate;
trap_gate_t trap_gate;
intr_gate_t intr_gate;
task_gate_t task_gate;
} dt_entry_t;
#define DESC_TBL_MAX 8192
/*
* Global descriptor table.
*/
typedef union gdt_entry {
code_desc_t code;
data_desc_t data;
ldt_desc_t ldt;
call_gate_t call_gate;
task_gate_t task_gate;
tss_desc_t task_state;
} gdt_entry_t;
typedef gdt_entry_t gdt_t;
/*
* Interrupt descriptor table.
*/
typedef union idt_entry {
trap_gate_t trap_gate;
intr_gate_t intr_gate;
task_gate_t task_gate;
} idt_entry_t;
typedef idt_entry_t idt_t;
/*
* Local descriptor table.
*/
typedef union ldt_entry {
code_desc_t code;
data_desc_t data;
call_gate_t call_gate;
task_gate_t task_gate;
} ldt_entry_t;
typedef ldt_entry_t ldt_t;

View File

@ -0,0 +1,120 @@
/*
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* Copyright (c) 1992 NeXT Computer, Inc.
*
* Intel386 Family: Task State Segment.
*
* HISTORY
*
* 29 March 1992 ? at NeXT
* Created.
*/
#include <architecture/i386/sel.h>
/*
* Task State segment.
*/
typedef struct tss {
sel_t oldtss;
unsigned int :0;
unsigned int esp0;
sel_t ss0;
unsigned int :0;
unsigned int esp1;
sel_t ss1;
unsigned int :0;
unsigned int esp2;
sel_t ss2;
unsigned int :0;
unsigned int cr3;
unsigned int eip;
unsigned int eflags;
unsigned int eax;
unsigned int ecx;
unsigned int edx;
unsigned int ebx;
unsigned int esp;
unsigned int ebp;
unsigned int esi;
unsigned int edi;
sel_t es;
unsigned int :0;
sel_t cs;
unsigned int :0;
sel_t ss;
unsigned int :0;
sel_t ds;
unsigned int :0;
sel_t fs;
unsigned int :0;
sel_t gs;
unsigned int :0;
sel_t ldt;
unsigned int :0;
unsigned int t :1,
:15,
io_bmap :16;
} tss_t;
#define TSS_SIZE(n) (sizeof (struct tss) + (n))
/*
* Task State segment descriptor.
*/
typedef struct tss_desc {
unsigned short limit00;
unsigned short base00;
unsigned char base16;
unsigned char type :5,
#define DESC_TSS 0x09
dpl :2,
present :1;
unsigned char limit16 :4,
:3,
granular:1;
unsigned char base24;
} tss_desc_t;
/*
* Task gate descriptor.
*/
typedef struct task_gate {
unsigned short :16;
sel_t tss;
unsigned int :8,
type :5,
#define DESC_TASK_GATE 0x05
dpl :2,
present :1,
:0;
} task_gate_t;

View File

@ -0,0 +1,185 @@
/* Copyright (c) (2010,2011,2012,2014,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CC_H_
#define _CORECRYPTO_CC_H_
#include <corecrypto/cc_config.h>
#include <corecrypto/cc_error.h>
#include <string.h>
#include <stdint.h>
#if __has_feature(attribute_availability_with_replacement)
#if __has_feature(attribute_availability_bridgeos)
#ifndef __CC_BRIDGE_OS_DEPRECATED
#define __CC_BRIDGEOS_DEPRECATED(_dep, _msg) __attribute__((availability(bridgeos,deprecated=_dep, replacement=_msg)))
#endif
#endif
#ifndef __CC_BRIDGEOS_DEPRECATED
#define __CC_BRIDGEOS_DEPRECATED(_dep, _msg)
#endif
#define cc_deprecate_with_replacement(replacement_message, ios_version, macos_version, tvos_version, watchos_version, bridgeos_version) \
__attribute__((availability(macos,deprecated=macos_version, replacement=replacement_message)))\
__attribute__((availability(ios,deprecated=ios_version, replacement=replacement_message)))\
__attribute__((availability(watchos,deprecated=watchos_version, replacement=replacement_message)))\
__attribute__((availability(tvos,deprecated=tvos_version, replacement=replacement_message)))\
__CC_BRIDGEOS_DEPRECATED(bridgeos_version, replacement_message)
#else /* !__has_feature(attribute_availability_with_replacement) */
#define cc_deprecate_with_replacement(replacement_message, ios_version, macos_version, tvos_version, watchos_version, bridgeos_version)
#endif /* __has_feature(attribute_availability_with_replacement) */
/* Provide a general purpose macro concat method. */
#define cc_concat_(a, b) a##b
#define cc_concat(a, b) cc_concat_(a, b)
#if defined(_MSC_VER)
#define __asm__(x)
#endif
/* Manage asserts here because a few functions in header public files do use asserts */
#if CORECRYPTO_DEBUG
#define cc_assert(x) assert(x)
#else
#define cc_assert(x)
#endif
#if CC_KERNEL
#include <kern/assert.h>
#elif CC_USE_S3
#define assert(args) // No assert in S3
#else
#include <assert.h>
#endif
/* Provide a static assert that can be used to create compile-type failures. */
#define cc_static_assert(e,m) \
enum { cc_concat(static_assert_, __COUNTER__) = 1/(int)(!!(e)) }
/* Declare a struct element with a guarenteed alignment of _alignment_.
The resulting struct can be used to create arrays that are aligned by
a certain amount. */
#define cc_aligned_struct(_alignment_) \
typedef struct { \
uint8_t b[_alignment_]; \
} CC_ALIGNED(_alignment_)
#if defined(__BIGGEST_ALIGNMENT__)
#define CC_MAX_ALIGNMENT ((size_t)__BIGGEST_ALIGNMENT__)
#else
#define CC_MAX_ALIGNMENT ((size_t)16)
#endif
/* pads a given size to be a multiple of the biggest alignment for any type */
#define cc_pad_align(_size_) ((_size_ + CC_MAX_ALIGNMENT - 1) & (~(CC_MAX_ALIGNMENT - 1)))
/* number of array elements used in a cc_ctx_decl */
#define cc_ctx_n(_type_, _size_) ((_size_ + sizeof(_type_) - 1) / sizeof(_type_))
/* sizeof of a context declared with cc_ctx_decl */
#define cc_ctx_sizeof(_type_, _size_) sizeof(_type_[cc_ctx_n(_type_, _size_)])
/*
1. _alloca cannot be removed becasue this header file is compiled with both MSVC++ and with clang.
2. The _MSC_VER version of cc_ctx_decl() is not compatible with the way *_decl macros as used in CommonCrypto, AppleKeyStore and SecurityFrameworks. To observe the incompatibilities and errors, use below definition. Corecrypto itself, accepts both deinitions
#define cc_ctx_decl(_type_, _size_, _name_) _type_ _name_ ## _array[cc_ctx_n(_type_, (_size_))]; _type_ *_name_ = _name_ ## _array
3. Never use sizeof() operator for the variables declared with cc_ctx_decl(), because it is not be compatible with the _MSC_VER version of cc_ctx_decl().
*/
#if defined(_MSC_VER)
#include <malloc.h>
#define cc_ctx_decl(_type_, _size_, _name_) _type_ * _name_ = (_type_ *) _alloca(sizeof(_type_) * cc_ctx_n(_type_, _size_) )
#define cc_ctx_decl_field(_type_, _size_, _name_) _type_ _name_ [cc_ctx_n(_type_, _size_)]
#else
// FIXME <rdar://problem/57372917> this pragma is the wrong fix for VLA usage, but since this API is central to corecrypto it's difficult to remove VLAs. The macro is then used in many other projects who don't need to be warned about VLAs at the moment. It's therefore desirable to silence the diagnostic and let corecrypto deal with removing VLAs.
#define cc_ctx_decl(_type_, _size_, _name_) \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wvla\"") \
_type_ _name_ [cc_ctx_n(_type_, _size_)] \
_Pragma("GCC diagnostic pop")
#define cc_ctx_decl_field cc_ctx_decl
#endif
/*!
@brief cc_clear(len, dst) zeroizes array dst and it will not be optimized out.
@discussion It is used to clear sensitive data, particularly when the are defined in the stack
@param len number of bytes to be cleared in dst
@param dst input array
*/
CC_NONNULL((2))
void cc_clear(size_t len, void *dst);
// cc_zero is deprecated, please use cc_clear instead.
cc_deprecate_with_replacement("cc_clear", 13.0, 10.15, 13.0, 6.0, 4.0)
CC_NONNULL_ALL CC_INLINE
void cc_zero(size_t len, void *dst)
{
cc_clear(len, dst);
}
#define cc_copy(_size_, _dst_, _src_) memcpy(_dst_, _src_, _size_)
CC_INLINE CC_NONNULL((2, 3, 4))
void cc_xor(size_t size, void *r, const void *s, const void *t) {
uint8_t *_r=(uint8_t *)r;
const uint8_t *_s=(const uint8_t *)s;
const uint8_t *_t=(const uint8_t *)t;
while (size--) {
_r[size] = _s[size] ^ _t[size];
}
}
/*!
@brief cc_cmp_safe(num, pt1, pt2) compares two array ptr1 and ptr2 of num bytes.
@discussion The execution time/cycles is independent of the data and therefore guarantees no leak about the data. However, the execution time depends on num.
@param num number of bytes in each array
@param ptr1 input array
@param ptr2 input array
@return returns 0 if the num bytes starting at ptr1 are identical to the num bytes starting at ptr2 and 1 if they are different or if num is 0 (empty arrays).
*/
CC_NONNULL((2, 3))
int cc_cmp_safe (size_t num, const void * ptr1, const void * ptr2);
/* Exchange S and T of any type. NOTE: Both and S and T are evaluated
mutliple times and MUST NOT be expressions. */
#define CC_SWAP(S,T) do { \
volatile __typeof__(S) _cc_swap_tmp = S; S = T; T = _cc_swap_tmp; \
_cc_swap_tmp = 0;\
} while(0)
/* Return the maximum value between S and T. */
#define CC_MAX(S, T) ({__typeof__(S) _cc_max_s = S; __typeof__(T) _cc_max_t = T; _cc_max_s > _cc_max_t ? _cc_max_s : _cc_max_t;})
/* Clone of CC_MAX() that evalutes S and T multiple times to allow nesting. */
#define CC_MAX_EVAL(S, T) ((S) > (T) ? (S) : (T))
/* Return the minimum value between S and T. */
#define CC_MIN(S, T) ({__typeof__(S) _cc_min_s = S; __typeof__(T) _cc_min_t = T; _cc_min_s <= _cc_min_t ? _cc_min_s : _cc_min_t;})
/*
When building with "-nostdinc" (i.e. iboot), ptrauth.h is in a non-standard location.
This requires a new flag to be used when building iboot: -ibuiltininc.
This flag doesn't seem present at the moment in clang. For now lets not
diversify in iBoot.
*/
#if __has_feature(ptrauth_calls) && (CC_KERNEL || CC_USE_L4 || CC_USE_SEPROM)
#include <ptrauth.h>
#define CC_SPTR(_sn_, _n_) \
__ptrauth(ptrauth_key_process_independent_code, 1, ptrauth_string_discriminator("cc_" #_sn_ #_n_)) _n_
#else
#define CC_SPTR(_sn_, _n_) _n_
#endif
#endif /* _CORECRYPTO_CC_H_ */

View File

@ -0,0 +1,645 @@
/* Copyright (c) (2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CC_CONFIG_H_
#define _CORECRYPTO_CC_CONFIG_H_
/* A word about configuration macros:
Conditional configuration macros specific to corecrypto should be named CORECRYPTO_xxx
or CCxx_yyy and be defined to be either 0 or 1 in this file. You can add an
#ifndef #error construct at the end of this file to make sure it's always defined.
They should always be tested using the #if directive, never the #ifdef directive.
No other conditional macros shall ever be used (except in this file)
Configuration Macros that are defined outside of corecrypto (eg: KERNEL, DEBUG, ...)
shall only be used in this file to define CCxxx macros.
External macros should be assumed to be either undefined, defined with no value,
or defined as true or false. We shall strive to build with -Wundef whenever possible,
so the following construct should be used to test external macros in this file:
#if defined(DEBUG) && (DEBUG)
#define CORECRYPTO_DEBUG 1
#else
#define CORECRYPTO_DEBUG 0
#endif
It is acceptable to define a conditional CC_xxxx macro in an implementation file,
to be used only in this file.
The current code is not guaranteed to follow those rules, but should be fixed to.
Corecrypto requires GNU and C99 compatibility.
Typically enabled by passing --gnu --c99 to the compiler (eg. armcc)
*/
//Do not set this macros to 1, unless you are developing/testing for Linux under macOS
#define CORECRYPTO_SIMULATE_POSIX_ENVIRONMENT 0
//Do not set these macros to 1, unless you are developing/testing for Windows under macOS
#define CORECRYPTO_SIMULATE_WINDOWS_ENVIRONMENT 0
#define CORECRYPTO_HACK_FOR_WINDOWS_DEVELOPMENT 0
#if (defined(DEBUG) && (DEBUG)) || defined(_DEBUG) //MSVC defines _DEBUG
/* CC_DEBUG is already used in CommonCrypto */
#define CORECRYPTO_DEBUG 1
#else
#define CORECRYPTO_DEBUG 0
#endif
// This macro can be used to enable prints when a condition in the macro "cc_require"
// is false. This is especially useful to confirm that negative testing fails
// at the intended location
#define CORECRYPTO_DEBUG_ENABLE_CC_REQUIRE_PRINTS 0
#if defined(KERNEL) && (KERNEL)
#define CC_KERNEL 1 // KEXT, XNU repo or kernel components such as AppleKeyStore
#else
#define CC_KERNEL 0
#endif
#if defined(LINUX_SGX) && (LINUX_SGX)
#define CC_SGX 1
#else
#define CC_SGX 0
#endif
#if (defined(__linux__) && !(CC_SGX)) || CORECRYPTO_SIMULATE_POSIX_ENVIRONMENT
#define CC_LINUX 1
#else
#define CC_LINUX 0
#endif
#if defined(__ANDROID__) && (__ANDROID__)
#define CC_ANDROID 1
#else
#define CC_ANDROID 0
#endif
#if defined(USE_L4) && (USE_L4)
#define CC_USE_L4 1
#else
#define CC_USE_L4 0
#endif
#if defined(RTKIT) && (RTKIT)
#define CC_RTKIT 1
#else
#define CC_RTKIT 0
#endif
#if defined(RTKITROM) && (RTKITROM)
#define CC_RTKITROM 1
#else
#define CC_RTKITROM 0
#endif
#if defined(USE_SEPROM) && (USE_SEPROM)
#define CC_USE_SEPROM 1
#else
#define CC_USE_SEPROM 0
#endif
#if defined(USE_S3) && (USE_S3)
#define CC_USE_S3 1
#else
#define CC_USE_S3 0
#endif
#if (defined(ICE_FEATURES_ENABLED)) || (defined(MAVERICK) && (MAVERICK))
#define CC_BASEBAND 1
#else
#define CC_BASEBAND 0
#endif
#if defined(EFI) && (EFI)
#define CC_EFI 1
#else
#define CC_EFI 0
#endif
#if defined(IBOOT) && (IBOOT)
#define CC_IBOOT 1
#else
#define CC_IBOOT 0
#endif
#if defined(TARGET_OS_BRIDGE)
#define CC_BRIDGE TARGET_OS_BRIDGE
#else
#define CC_BRIDGE 0
#endif
// Check if we're running on a generic, userspace platform, i.e., not in the kernel, SEP, etc.
#ifndef CC_GENERIC_PLATFORM
#define CC_GENERIC_PLATFORM \
(!CC_RTKIT && !CC_KERNEL && !CC_USE_L4 && \
!CC_RTKITROM && !CC_EFI && !CC_IBOOT && \
!CC_USE_SEPROM && !CC_ANDROID && !CC_LINUX && \
!CC_BRIDGE)
#endif
// Check for availability of internal Darwin SPIs.
#ifndef CC_DARWIN_SPIS_AVAILABLE
#if defined(__has_include)
#define CC_DARWIN_SPIS_AVAILABLE __has_include(<os/log_private.h>)
#else
#define CC_DARWIN_SPIS_AVAILABLE 0
#endif
#endif
// Check for open source builds
// ccringbuffer availability
// Only enable the ccringbuffer data structure in generic, userspace builds where memory allocation is not an issue.
#ifndef CC_RINGBUFFER_AVAILABLE
#define CC_RINGBUFFER_AVAILABLE (CC_GENERIC_PLATFORM && CC_DARWIN_SPIS_AVAILABLE && !CC_OPEN_SOURCE)
#endif
// os_log integration
// Only enable logging support in generic, userspace builds with the desired Darwin SPIs.
#ifndef CC_LOGGING_AVAILABLE
#define CC_LOGGING_AVAILABLE (CC_GENERIC_PLATFORM && CC_DARWIN_SPIS_AVAILABLE && !CC_OPEN_SOURCE)
#endif
// FeatureFlag integration
// Only enable feature flag support in generic, userspace builds with the desired Darwin SPIs.
// This requires linking against libsystem_featureflags to function correctly.
#ifndef CC_FEATURE_FLAGS_AVAILABLE
#if defined(__has_include)
#define CC_FEATURE_FLAGS_AVAILABLE __has_include(<os/feature_private.h>)
#else
#define CC_FEATURE_FLAGS_AVAILABLE 0
#endif
#endif
// Macro to determine if a specific feature is available.
// Turn off all features at compile time if desired and avoid the runtime check by changing this
// definition to 0. Limit this functionality to the same environments wherein the ringbuffer is available.
#ifndef CC_FEATURE_ENABLED
#if (CC_RINGBUFFER_AVAILABLE && CC_FEATURE_FLAGS_AVAILABLE && !defined(__i386__))
#define CC_FEATURE_ENABLED(FEATURE) os_feature_enabled(Cryptography, FEATURE)
#else
#define CC_FEATURE_ENABLED(FEATURE) 0
#endif
#endif
// Trace usage of deprecated or obscure functions. For now, this is
// completely disabled.
#ifndef CC_LOG_TRACE
#define CC_LOG_TRACE 0
#endif
// Defined by the XNU build scripts
// Applies to code embedded in XNU but NOT to the kext
#if defined(XNU_KERNEL_PRIVATE)
#define CC_XNU_KERNEL_PRIVATE 1
#else
#define CC_XNU_KERNEL_PRIVATE 0
#endif
// handle unaligned data, if the cpu cannot. Currently for gladman AES and the C version of the SHA256
#define CC_HANDLE_UNALIGNED_DATA CC_BASEBAND
// BaseBand configuration
#if CC_BASEBAND
// -- ENDIANESS
#if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
#if defined(ENDIAN_LITTLE) || (defined(__arm__) && !defined(__BIG_ENDIAN))
#define __LITTLE_ENDIAN__
#elif !defined(ENDIAN_BIG) && !defined(__BIG_ENDIAN)
#error Baseband endianess not defined.
#endif
#define AESOPT_ENDIAN_NO_FILE
#endif
// -- Architecture
#define CCN_UNIT_SIZE 4 // 32 bits
// -- External function
#define assert ASSERT // sanity
// -- Warnings
// Ignore irrelevant warnings after verification
// #1254-D: arithmetic on pointer to void or function type
// #186-D: pointless comparison of unsigned integer with zero
// #546-D: transfer of control bypasses initialization of
#ifdef __arm__
#pragma diag_suppress 186, 1254,546
#elif defined(__GNUC__)
// warning: pointer of type 'void *' used in arithmetic
#pragma GCC diagnostic ignored "-Wpointer-arith"
#endif // __arm__
#define CC_SMALL_CODE 1
#endif // CC_BASEBAND
#if CC_RTKIT || CC_RTKITROM
#define CC_SMALL_CODE 1
#endif
#ifndef CC_SMALL_CODE
#define CC_SMALL_CODE 0
#endif
//CC_XNU_KERNEL_AVAILABLE indicates the availibity of XNU kernel functions,
//like what we have on OSX, iOS, tvOS, Watch OS
#if defined(__APPLE__) && defined(__MACH__)
#define CC_XNU_KERNEL_AVAILABLE 1
#else
#define CC_XNU_KERNEL_AVAILABLE 0
#endif
//arm arch64 definition for gcc
#if defined(__GNUC__) && defined(__aarch64__) && !defined(__arm64__)
#define __arm64__
#endif
#if !defined(CCN_UNIT_SIZE)
#if defined(__arm64__) || defined(__x86_64__) || defined(_WIN64)
#define CCN_UNIT_SIZE 8
#elif defined(__arm__) || defined(__i386__) || defined(_WIN32)
#define CCN_UNIT_SIZE 4
#else
#error undefined architecture
#endif
#endif /* !defined(CCN_UNIT_SIZE) */
//this allows corecrypto Windows development using xcode
#if defined(CORECRYPTO_SIMULATE_WINDOWS_ENVIRONMENT)
#if CORECRYPTO_SIMULATE_WINDOWS_ENVIRONMENT && CC_XNU_KERNEL_AVAILABLE && CORECRYPTO_DEBUG
#define CC_USE_ASM 0
#define CC_USE_HEAP_FOR_WORKSPACE 1
#if (CCN_UNIT_SIZE==8)
#define CCN_UINT128_SUPPORT_FOR_64BIT_ARCH 0
#else
#define CCN_UINT128_SUPPORT_FOR_64BIT_ARCH 1
#endif
#endif
#endif
#if !defined(CCN_UINT128_SUPPORT_FOR_64BIT_ARCH)
#if defined(_WIN64) && defined(_WIN32) && (CCN_UNIT_SIZE==8)
#define CCN_UINT128_SUPPORT_FOR_64BIT_ARCH 0
#elif defined(_WIN32)
#define CCN_UINT128_SUPPORT_FOR_64BIT_ARCH 1//should not be a problem
#else
#define CCN_UINT128_SUPPORT_FOR_64BIT_ARCH 1
#endif
#endif
#if defined(_MSC_VER)
#if defined(__clang__)
#define CC_ALIGNED(x) __attribute__ ((aligned(x))) //clang compiler
#else
#define CC_ALIGNED(x) __declspec(align(x)) //MS complier
#endif
#else
#if __clang__ || CCN_UNIT_SIZE==8
#define CC_ALIGNED(x) __attribute__ ((aligned(x)))
#else
#define CC_ALIGNED(x) __attribute__ ((aligned((x)>8?8:(x))))
#endif
#endif
#if defined(__arm__)
//this is copied from <arm/arch.h>, because <arm/arch.h> is not available on SEPROM environment
#if defined (__ARM_ARCH_7A__) || defined (__ARM_ARCH_7S__) || defined (__ARM_ARCH_7F__) || defined (__ARM_ARCH_7K__) || defined(__ARM_ARCH_7EM__)
#define _ARM_ARCH_7
#endif
#if defined(__ARM_ARCH_6M__) || defined(__TARGET_ARCH_6S_M) || defined (__armv6m__)
#define _ARM_ARCH_6M
#endif
#endif
#if defined(__arm64__) || defined(__arm__)
#define CCN_IOS 1
#define CCN_OSX 0
#elif defined(__x86_64__) || defined(__i386__)
#define CCN_IOS 0
#define CCN_OSX 1
#endif
#if CC_USE_S3
/* For corecrypto kext, CC_STATIC should be undefined */
#define CC_STATIC 1
#endif
#if !defined(CC_USE_HEAP_FOR_WORKSPACE)
#if CC_USE_S3 || CC_USE_SEPROM || CC_RTKITROM
#define CC_USE_HEAP_FOR_WORKSPACE 0
#else
#define CC_USE_HEAP_FOR_WORKSPACE 1
#endif
#endif
/* memset_s is only available in few target */
#if CC_USE_SEPROM || defined(__CC_ARM) \
|| defined(__hexagon__) || CC_EFI
#define CC_HAS_MEMSET_S 0
#else
#define CC_HAS_MEMSET_S 1
#endif
// Include target conditionals if available.
#if defined(__has_include) /* portability */
#if __has_include(<TargetConditionals.h>)
#include <TargetConditionals.h>
#endif /* __has_include(<TargetConditionals.h>) */
#endif /* defined(__has_include) */
// Disable RSA Keygen on iBridge
#if defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE && CC_KERNEL
#define CC_DISABLE_RSAKEYGEN 1 /* for iBridge */
#else
#define CC_DISABLE_RSAKEYGEN 0 /* default */
#endif
#if (CCN_UNIT_SIZE == 8) && !( defined(_MSC_VER) && defined(__clang__))
#define CCEC25519_CURVE25519_64BIT 1
#else
#define CCEC25519_CURVE25519_64BIT 0
#endif
//- functions implemented in assembly ------------------------------------------
//this the list of corecrypto clients that use assembly and the clang compiler
#if !(CC_XNU_KERNEL_AVAILABLE || CC_KERNEL || CC_USE_L4 || CC_IBOOT || CC_RTKIT || CC_RTKITROM || CC_USE_SEPROM || CC_USE_S3) && !defined(_WIN32) && CORECRYPTO_DEBUG
#warning "You are using the default corecrypto configuration, assembly optimizations may not be available for your platform"
#endif
// Enable assembler in Linux if CC_LINUX_ASM is defined
#if (CC_LINUX || CC_SGX) && defined(CC_LINUX_ASM) && CC_LINUX_ASM
#define CC_USE_ASM 1
#endif
// Use this macro to strictly disable assembly regardless of cpu/os/compiler/etc.
// Our assembly code is not gcc compatible. Clang defines the __GNUC__ macro as well.
#if !defined(CC_USE_ASM)
#if defined(_WIN32) || CC_EFI || CC_BASEBAND || CC_XNU_KERNEL_PRIVATE || (defined(__GNUC__) && !defined(__clang__)) || defined(__ANDROID_API__) || CC_LINUX
#define CC_USE_ASM 0
#else
#define CC_USE_ASM 1
#endif
#endif
#define CC_CACHE_DESCRIPTORS CC_KERNEL
//-(1) ARM V7
#if defined(_ARM_ARCH_7) && __clang__ && CC_USE_ASM
#define CCN_DEDICATED_SQR CC_SMALL_CODE
#define CCN_MUL_KARATSUBA 0 // no performance improvement
#define CCN_ADD_ASM 1
#define CCN_SUB_ASM 1
#define CCN_MUL_ASM 0
#define CCN_ADDMUL1_ASM 1
#define CCN_MUL1_ASM 1
#define CCN_CMP_ASM 1
#define CCN_ADD1_ASM 1
#define CCN_SUB1_ASM 1
#define CCN_N_ASM 1
#define CCN_SET_ASM 1
#define CCN_SHIFT_RIGHT_ASM 1
#if defined(__ARM_NEON__)
#define CCN_SHIFT_LEFT_ASM 1
#else
#define CCN_SHIFT_LEFT_ASM 0
#endif
#define CCN_MULMOD_224_ASM 1
#define CCN_MULMOD_256_ASM 1
#define CCAES_ARM_ASM 1
#define CCAES_INTEL_ASM 0
#if CC_KERNEL || CC_USE_L4 || CC_IBOOT || CC_RTKIT || CC_RTKITROM || CC_USE_SEPROM || CC_USE_S3
#define CCAES_MUX 0
#else
#define CCAES_MUX 1
#endif
#define CCN_USE_BUILTIN_CLZ 1
#define CCSHA1_VNG_INTEL 0
#define CCSHA2_VNG_INTEL 0
#if defined(__ARM_NEON__) || CC_KERNEL
#define CCSHA1_VNG_ARM 1
#define CCSHA2_VNG_ARM 1
#else /* !defined(__ARM_NEON__) */
#define CCSHA1_VNG_ARM 0
#define CCSHA2_VNG_ARM 0
#endif /* !defined(__ARM_NEON__) */
#define CCSHA256_ARMV6M_ASM 0
#define CC_ACCELERATECRYPTO 1
//-(2) ARM 64
#elif defined(__arm64__) && __clang__ && CC_USE_ASM
#define CCN_DEDICATED_SQR CC_SMALL_CODE
#define CCN_MUL_KARATSUBA 0 // 4*n CCN_UNIT extra memory required.
#define CCN_ADD_ASM 1
#define CCN_SUB_ASM 1
#define CCN_MUL_ASM 1
#define CCN_ADDMUL1_ASM 0
#define CCN_MUL1_ASM 0
#define CCN_CMP_ASM 1
#define CCN_ADD1_ASM 0
#define CCN_SUB1_ASM 0
#define CCN_N_ASM 1
#define CCN_SET_ASM 0
#define CCN_SHIFT_RIGHT_ASM 1
#define CCN_SHIFT_LEFT_ASM 1
#define CCN_MULMOD_224_ASM 1
#define CCN_MULMOD_256_ASM 1
#define CCAES_ARM_ASM 1
#define CCAES_INTEL_ASM 0
#define CCAES_MUX 0 // On 64bit SoC, asm is much faster than HW
#define CCN_USE_BUILTIN_CLZ 1
#define CCSHA1_VNG_INTEL 0
#define CCSHA2_VNG_INTEL 0
#define CCSHA1_VNG_ARM 1
#define CCSHA2_VNG_ARM 1
#define CCSHA256_ARMV6M_ASM 0
#define CC_ACCELERATECRYPTO 1
//-(3) Intel 32/64
#elif (defined(__x86_64__) || defined(__i386__)) && __clang__ && CC_USE_ASM
#define CCN_DEDICATED_SQR 1
#define CCN_MUL_KARATSUBA 0 // 4*n CCN_UNIT extra memory required.
/* These assembly routines only work for a single CCN_UNIT_SIZE. */
#if (defined(__x86_64__) && CCN_UNIT_SIZE == 8) || (defined(__i386__) && CCN_UNIT_SIZE == 4)
#define CCN_ADD_ASM 1
#define CCN_SUB_ASM 1
#define CCN_MUL_ASM 1
#else
#define CCN_ADD_ASM 0
#define CCN_SUB_ASM 0
#define CCN_MUL_ASM 0
#endif
#if (defined(__x86_64__) && CCN_UNIT_SIZE == 8)
#define CCN_CMP_ASM 1
#define CCN_N_ASM 1
#define CCN_SHIFT_RIGHT_ASM 1
#define CCN_SHIFT_LEFT_ASM 1
#else
#define CCN_CMP_ASM 0
#define CCN_N_ASM 0
#define CCN_SHIFT_RIGHT_ASM 0
#define CCN_SHIFT_LEFT_ASM 0
#endif
#define CCN_MULMOD_224_ASM 0
#if defined(__x86_64__) && CCN_UNIT_SIZE == 8 && !CC_SGX
#define CCN_MULMOD_256_ASM 1
#define CCN_ADDMUL1_ASM 1
#define CCN_MUL1_ASM 1
#else
#define CCN_MULMOD_256_ASM 0
#define CCN_ADDMUL1_ASM 0
#define CCN_MUL1_ASM 0
#endif
#define CCN_ADD1_ASM 0
#define CCN_SUB1_ASM 0
#define CCN_SET_ASM 0
#define CCAES_ARM_ASM 0
#define CCAES_INTEL_ASM 1
#define CCAES_MUX 0
#define CCN_USE_BUILTIN_CLZ 0
#define CCSHA1_VNG_INTEL 1
#define CCSHA2_VNG_INTEL 1
#define CCSHA1_VNG_ARM 0
#define CCSHA2_VNG_ARM 0
#define CCSHA256_ARMV6M_ASM 0
#define CC_ACCELERATECRYPTO 1
//-(4) disable assembly
#else
#if CCN_UINT128_SUPPORT_FOR_64BIT_ARCH
#define CCN_DEDICATED_SQR 1
#else
#define CCN_DEDICATED_SQR 0 //when assembly is off and 128-bit integers are not supported, dedicated square is off. This is the case on Windows
#endif
#define CCN_MUL_KARATSUBA 0 // 4*n CCN_UNIT extra memory required.
#define CCN_ADD_ASM 0
#define CCN_SUB_ASM 0
#define CCN_MUL_ASM 0
#define CCN_ADDMUL1_ASM 0
#define CCN_MUL1_ASM 0
#define CCN_CMP_ASM 0
#define CCN_ADD1_ASM 0
#define CCN_SUB1_ASM 0
#define CCN_N_ASM 0
#define CCN_SET_ASM 0
#define CCN_SHIFT_RIGHT_ASM 0
#define CCN_SHIFT_LEFT_ASM 0
#define CCN_MULMOD_224_ASM 0
#define CCN_MULMOD_256_ASM 0
#define CCAES_ARM_ASM 0
#define CCAES_INTEL_ASM 0
#define CCAES_MUX 0
#define CCN_USE_BUILTIN_CLZ 0
#define CCSHA1_VNG_INTEL 0
#define CCSHA2_VNG_INTEL 0
#define CCSHA1_VNG_ARM 0
#define CCSHA2_VNG_ARM 0
#define CCSHA256_ARMV6M_ASM 0
#define CC_ACCELERATECRYPTO 0
#endif
#define CC_INLINE static inline
#ifdef __GNUC__
#define CC_NORETURN __attribute__((__noreturn__))
#define CC_NOTHROW __attribute__((__nothrow__))
#define CC_NONNULL(N) __attribute__((__nonnull__ N))
#define CC_NONNULL4 CC_NONNULL((4))
#define CC_NONNULL_ALL __attribute__((__nonnull__))
#define CC_SENTINEL __attribute__((__sentinel__))
// Only apply the `CC_CONST` attribute to functions with no side-effects where the output is a strict function of pass by value input vars with no exterior side-effects.
// Specifically, do not apply CC_CONST if the function has any arguments that are pointers (directly, or indirectly)
#define CC_CONST __attribute__((__const__))
#define CC_PURE __attribute__((__pure__))
#define CC_WARN_RESULT __attribute__((__warn_unused_result__))
#define CC_MALLOC_CLEAR __attribute__((__malloc__))
#define CC_UNUSED __attribute__((unused))
#else /* !__GNUC__ */
/*! @parseOnly */
#define CC_UNUSED
/*! @parseOnly */
#define CC_NONNULL(N)
/*! @parseOnly */
#define CC_NONNULL4
/*! @parseOnly */
#define CC_NORETURN
/*! @parseOnly */
#define CC_NOTHROW
/*! @parseOnly */
#define CC_NONNULL_ALL
/*! @parseOnly */
#define CC_SENTINEL
/*! @parseOnly */
#define CC_CONST
/*! @parseOnly */
#define CC_PURE
/*! @parseOnly */
#define CC_WARN_RESULT
/*! @parseOnly */
#define CC_MALLOC_CLEAR
#endif /* !__GNUC__ */
// Bridge differences between MachO and ELF compiler/assemblers. */
#if CC_LINUX || CC_SGX
#define CC_ASM_SECTION_CONST .rodata
#define CC_ASM_PRIVATE_EXTERN .hidden
#if CC_LINUX
// We need to be sure that assembler can access relocated C
// symbols. Sad but this is the quickest way to do that, at least with
// our current linux compiler (clang-3.4).
#define CC_C_LABEL(_sym) _sym@PLT
#else /* CC_SGX */
#define CC_C_LABEL(_sym) _sym
#endif
#define _IMM(x) $(x)
#else /* !CC_LINUX && !CC_SGX */
#define CC_ASM_SECTION_CONST .const
#define CC_ASM_PRIVATE_EXTERN .private_extern
#define CC_C_LABEL(_sym) _##_sym
#define _IMM(x) $$(x)
#endif /* !CC_LINUX && !CC_SGX */
// Enable FIPSPOST function tracing only when supported. */
#ifdef CORECRYPTO_POST_TRACE
#define CC_FIPSPOST_TRACE 1
#else
#define CC_FIPSPOST_TRACE 0
#endif
#ifndef CC_INTERNAL_SDK
#if __has_include(<System/i386/cpu_capabilities.h>)
#define CC_INTERNAL_SDK 1
#elif __has_include(<System/arm/cpu_capabilities.h>)
#define CC_INTERNAL_SDK 1
#else
#define CC_INTERNAL_SDK 0
#endif
#endif
#endif /* _CORECRYPTO_CC_CONFIG_H_ */

View File

@ -0,0 +1,174 @@
/* Copyright (c) (2017,2018,2019,2020) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CC_ERROR_H_
#define _CORECRYPTO_CC_ERROR_H_
enum {
CCERR_OK = 0,
/* the default error code */
CCERR_INTERNAL = -1,
CCERR_INTEGRITY = -2,
CCERR_DEVICE = -3,
CCERR_INTERRUPTS = -4,
CCERR_CRYPTO_CONFIG = -5,
CCERR_PERMS = -6,
CCERR_PARAMETER = -7,
CCERR_MEMORY = -8,
CCERR_FILEDESC = -9,
CCERR_OUT_OF_ENTROPY = -10,
CCERR_ATFORK = -11,
CCERR_OVERFLOW = -12,
CCERR_MEMORY_ALLOC_FAIL = -13,
CCEC_GENERATE_KEY_DEFAULT_ERR = -14,
CCEC_GENERATE_KEY_TOO_MANY_TRIES = -15,
CCEC_GENERATE_KEY_MULT_FAIL = -16,
CCEC_GENERATE_KEY_AFF_FAIL = -17,
CCEC_GENERATE_KEY_CONSISTENCY = -18,
CCEC_GENERATE_NOT_ON_CURVE = -19,
CCEC_GENERATE_NOT_ENOUGH_ENTROPY = -20,
CCEC_GENERATE_NOT_SUPPORTED = -21,
CCEC_GENERATE_INVALID_INPUT = -22,
// Program error: buffer too small or encrypted message is too small
CCRSA_INVALID_INPUT = -23,
// Invalid crypto configuration: Hash length versus RSA key size
CCRSA_INVALID_CONFIG = -24,
CCRSA_ENCODING_ERROR = -25,
CCRSA_DECODING_ERROR = -26,
// The data is invalid (we won't say more for security)
CCRSA_PRIVATE_OP_ERROR = -27,
CCRSA_KEY_ERROR = -28,
// Key generation specific
CCRSA_KEYGEN_PRIME_NOT_FOUND = -29,
CCRSA_KEYGEN_PRIME_NEED_NEW_SEED = -30,
CCRSA_KEYGEN_PRIME_TOO_MANY_ITERATIONS = -31,
CCRSA_KEYGEN_PRIME_SEED_GENERATION_ERROR = -32,
CCRSA_KEYGEN_MODULUS_CRT_INV_ERROR = -33,
CCRSA_KEYGEN_NEXT_PRIME_ERROR = -34,
CCRSA_KEYGEN_SEED_X_ERROR = -35,
CCRSA_KEYGEN_SEED_r_ERROR = -36,
CCRSA_KEYGEN_KEYGEN_CONSISTENCY_FAIL = -37,
CCRSA_KEYGEN_R1R2_SIZE_ERROR = -38,
CCRSA_KEYGEN_PQ_DELTA_ERROR = -39,
CCRSA_FIPS_KEYGEN_DISABLED = -40,
CCZP_INV_ERROR = -41,
CCZP_INV_NO_INVERSE = -42,
CCZP_INV_INVALID_INPUT = -43,
CCZ_INVALID_INPUT_ERROR = -44,
CCZ_INVALID_RADIX_ERROR = -45,
CCDH_ERROR_DEFAULT = -46,
CCDH_GENERATE_KEY_TOO_MANY_TRIES = -47,
CCDH_NOT_SUPPORTED_CONFIGURATION = -48,
CCDH_SAFETY_CHECK = -49,
CCDH_PUBLIC_KEY_MISSING = -50,
CCDH_INVALID_DOMAIN_PARAMETER = -51,
CCDH_INVALID_INPUT = -52,
CCDH_DOMAIN_PARAMETER_MISMATCH = -53,
CCDH_GENERATE_KEY_CONSISTENCY = -54,
CCSRP_ERROR_DEFAULT = -55,
CCSRP_GENERATE_KEY_TOO_MANY_TRIES = -56,
CCSRP_NOT_SUPPORTED_CONFIGURATION = -57,
CCSRP_SAFETY_CHECK = -58,
CCSRP_PUBLIC_KEY_MISSING = -59,
CCSRP_INVALID_DOMAIN_PARAMETER = -60,
CCDRBG_STATUS_ERROR = -61,
CCDRBG_STATUS_NEED_RESEED = -62,
CCDRBG_STATUS_PARAM_ERROR = -63,
// If this value is returned, the caller must abort or panic the process for
// security reasons. for example in the case of catastrophic error in
// http://csrc.nist.gov/publications/drafts/800-90/sp800_90a_r1_draft.pdf
// ccdrbg calls abort() or panic(), if they are available in the system.
CCDRBG_STATUS_ABORT = -64,
CCKPRNG_NEED_ENTROPY = -65,
CCKPRNG_ABORT = -66,
CCMODE_INVALID_INPUT = -67,
CCMODE_INVALID_CALL_SEQUENCE = -68,
CCMODE_INTEGRITY_FAILURE = -69,
CCMODE_NOT_SUPPORTED = -70,
CCMODE_INTERNAL_ERROR = -71,
// Configuration or unexpected issue
CCPOST_GENERIC_FAILURE = -72,
CCPOST_LIBRARY_ERROR = -73,
CCPOST_INTEGRITY_ERROR = -74,
// Output of the algo is not as expected
CCPOST_KAT_FAILURE = -75,
CCKPRNG_SEEDFILE_OPEN = -76,
CCKPRNG_SEEDFILE_READ = -78,
CCKPRNG_SEEDFILE_WRITE = -79,
CCKPRNG_SEEDFILE_CHMOD = -80,
CCKPRNG_SEEDFILE_CHOWN = -81,
CCKPRNG_RANDOMDEV_OPEN = -82,
CCKPRNG_RANDOMDEV_WRITE = -83,
CCKPRNG_GETENTROPY = -84,
CCSAE_HUNTPECK_EXCEEDED_MAX_TRIALS = -85,
CCERR_CALL_SEQUENCE = -86,
CCVRF_POINT_DECODE_FAILURE = -87,
CCVRF_POINT_INVALID_PUBLIC_KEY = -88,
CCVRF_VERIFY_FAILURE = -89,
// Error codes for Authenticated Encryption Modes
CCMODE_TAG_LENGTH_REQUEST_TOO_LONG = -100,
CCMODE_TAG_LENGTH_TOO_SHORT = -101,
CCMODE_NONCE_EMPTY = -102,
CCMODE_AD_EMPTY = -103,
CCMODE_DECRYPTION_OR_VERIFICATION_ERR=-104,
CCMODE_BUFFER_OUT_IN_OVERLAP = -105,
// Error codes for Secret Sharing
CCSS_ELEMENT_TOO_LARGE_FOR_FIELD = -120,
CCSS_NOT_ENOUGH_SHARES = -121,
CCSS_TOO_MANY_SHARES = -122,
CCSS_IMPROPER_DEGREE = -123,
CCSS_TWO_SHARES_FOR_SAME_X = -124,
CCSS_THRESHOLD_NOT_LARGE_ENOUGH = -125,
CCSS_SHARE_BAG_FULL = -126,
CCSS_SHARE_ALREADY_PRESENT_IN_SHARE_BAG = -127,
CCSS_THRESHOLD_LARGER_OR_EQUAL_TO_FIELD = -128,
CCSS_TOO_MANY_SHARES_REQUESTED = -129,
CCSS_FIELD_MISMATCH = -130,
CCSS_INDEX_OUT_OF_RANGE = -131,
CCSAE_NOT_ENOUGH_COMMIT_PARTIAL_CALLS = -132,
CCSAE_GENERATE_COMMIT_CALL_AGAIN = -133,
CCERR_VALID_SIGNATURE = CCERR_OK,
CCERR_INVALID_SIGNATURE = -146,
CCERR_IOSERVICE_GETMATCHING = -147,
CCERR_IOSERVICE_OPEN = -148,
CCERR_IOCONNECT_CALL = -149,
};
#define CCDRBG_STATUS_OK CCERR_OK
#define CCKPRNG_OK CCERR_OK
#endif /* _CORECRYPTO_CC_ERROR_H_ */

View File

@ -0,0 +1,30 @@
/* Copyright (c) (2020) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef corecrypto_cc_fault_canary_h
#define corecrypto_cc_fault_canary_h
#include "cc.h"
#define CC_FAULT_CANARY_SIZE 16
typedef uint8_t cc_fault_canary_t[CC_FAULT_CANARY_SIZE];
extern const cc_fault_canary_t CCEC_FAULT_CANARY;
extern const cc_fault_canary_t CCRSA_PKCS1_FAULT_CANARY;
extern const cc_fault_canary_t CCRSA_PSS_FAULT_CANARY;
#define CC_FAULT_CANARY_MEMCPY(_dst_, _src_) memcpy(_dst_, _src_, CC_FAULT_CANARY_SIZE)
#define CC_FAULT_CANARY_CLEAR(_name_) memset(_name_, 0x00, CC_FAULT_CANARY_SIZE)
#define CC_FAULT_CANARY_EQUAL(_a_, _b_) (cc_cmp_safe(CC_FAULT_CANARY_SIZE, _a_, _b_) == 0)
#endif /* corecrypto_cc_fault_canary_h */

View File

@ -0,0 +1,150 @@
/* Copyright (c) (2012,2015,2016,2017,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CC_MACROS_H_
#define _CORECRYPTO_CC_MACROS_H_
#include <corecrypto/cc_config.h>
#ifndef __CC_DEBUG_ASSERT_COMPONENT_NAME_STRING
#define __CC_DEBUG_ASSERT_COMPONENT_NAME_STRING ""
#endif
#ifndef __CC_DEBUG_ASSERT_PRODUCTION_CODE
#define __CC_DEBUG_ASSERT_PRODUCTION_CODE !CORECRYPTO_DEBUG
#endif
#if CORECRYPTO_DEBUG_ENABLE_CC_REQUIRE_PRINTS
#if !CC_KERNEL
#include <string.h> // for strstr
#endif // !CC_KERNEL
CC_UNUSED static char *cc_strstr(const char *file) {
#if CC_KERNEL
(void) file;
#else
const char cc_char []="corecrypto";
char *p=strstr(file, cc_char);
if (p) return (p+strlen(cc_char)+1);
#endif
return NULL;
}
#define __CC_DEBUG_REQUIRE_MESSAGE(name, assertion, label, message, file, line, value) \
{char *___t = cc_strstr(file); cc_printf( "require: %s, %s%s:%d\n", assertion, (message!=0) ? message : "", ___t==NULL?file:___t, line);}
#endif // CORECRYPTO_DEBUG_ENABLE_CC_REQUIRE_PRINTS
#ifndef cc_require
#if (__CC_DEBUG_ASSERT_PRODUCTION_CODE) || (!CORECRYPTO_DEBUG_ENABLE_CC_REQUIRE_PRINTS)
#if defined(_WIN32) && defined (__clang__)
#define cc_require(assertion, exceptionLabel) \
do { \
if (!(assertion) ) { \
goto exceptionLabel; \
} \
} while ( 0 )
#else
#define cc_require(assertion, exceptionLabel) \
do { \
if ( __builtin_expect(!(assertion), 0) ) { \
goto exceptionLabel; \
} \
} while ( 0 )
#endif
#else
#define cc_require(assertion, exceptionLabel) \
do { \
if ( __builtin_expect(!(assertion), 0) ) { \
__CC_DEBUG_REQUIRE_MESSAGE(__CC_DEBUG_ASSERT_COMPONENT_NAME_STRING, \
#assertion, #exceptionLabel, 0, __FILE__, __LINE__, 0); \
goto exceptionLabel; \
} \
} while ( 0 )
#endif
#endif
#ifndef cc_require_action
#if __CC_DEBUG_ASSERT_PRODUCTION_CODE || (!CORECRYPTO_DEBUG_ENABLE_CC_REQUIRE_PRINTS)
#if defined(_WIN32) && defined(__clang__)
#define cc_require_action(assertion, exceptionLabel, action) \
do \
{ \
if (!(assertion)) \
{ \
{ \
action; \
} \
goto exceptionLabel; \
} \
} while ( 0 )
#else
#define cc_require_action(assertion, exceptionLabel, action) \
do \
{ \
if ( __builtin_expect(!(assertion), 0) ) \
{ \
{ \
action; \
} \
goto exceptionLabel; \
} \
} while ( 0 )
#endif
#else
#define cc_require_action(assertion, exceptionLabel, action) \
do \
{ \
if ( __builtin_expect(!(assertion), 0) ) \
{ \
__CC_DEBUG_REQUIRE_MESSAGE( \
__CC_DEBUG_ASSERT_COMPONENT_NAME_STRING, \
#assertion, #exceptionLabel, 0, __FILE__, __LINE__, 0); \
{ \
action; \
} \
goto exceptionLabel; \
} \
} while ( 0 )
#endif
#endif
#ifndef cc_require_or_return
#if (__CC_DEBUG_ASSERT_PRODUCTION_CODE) || (!CORECRYPTO_DEBUG_ENABLE_CC_REQUIRE_PRINTS)
#if defined(_WIN32) && defined (__clang__)
#define cc_require_or_return(assertion, value) \
do { \
if (!(assertion) ) { \
return value; \
} \
} while ( 0 )
#else
#define cc_require_or_return(assertion, value) \
do { \
if ( __builtin_expect(!(assertion), 0) ) { \
return value; \
} \
} while ( 0 )
#endif
#else
#define cc_require_or_return(assertion, value) \
do { \
if ( __builtin_expect(!(assertion), 0) ) { \
__CC_DEBUG_REQUIRE_MESSAGE(__CC_DEBUG_ASSERT_COMPONENT_NAME_STRING, \
#assertion, #exceptionLabel, 0, __FILE__, __LINE__, 0); \
return value; \
} \
} while ( 0 )
#endif
#endif
#endif /* _CORECRYPTO_CC_MACROS_H_ */

View File

@ -0,0 +1,818 @@
/* Copyright (c) (2010,2011,2012,2014,2015,2016,2017,2018,2019,2020) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CC_PRIV_H_
#define _CORECRYPTO_CC_PRIV_H_
#include <corecrypto/cc.h>
#include <stdbool.h>
#include <stdint.h>
// Fork handlers for the stateful components of corecrypto.
void cc_atfork_prepare(void);
void cc_atfork_parent(void);
void cc_atfork_child(void);
#ifndef __has_builtin
#define __has_builtin(x) 0
#endif
#ifndef __DECONST
#define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var))
#endif
/* defines the following macros :
CC_ARRAY_LEN: returns the number of elements in an array
CC_STORE32_BE : store 32 bit value in big endian in unaligned buffer.
CC_STORE32_LE : store 32 bit value in little endian in unaligned buffer.
CC_STORE64_BE : store 64 bit value in big endian in unaligned buffer.
CC_STORE64_LE : store 64 bit value in little endian in unaligned buffer.
CC_LOAD32_BE : load 32 bit value in big endian from unaligned buffer.
CC_LOAD32_LE : load 32 bit value in little endian from unaligned buffer.
CC_LOAD64_BE : load 64 bit value in big endian from unaligned buffer.
CC_LOAD64_LE : load 64 bit value in little endian from unaligned buffer.
CC_ROR : Rotate Right 32 bits. Rotate count can be a variable.
CC_ROL : Rotate Left 32 bits. Rotate count can be a variable.
CC_RORc : Rotate Right 32 bits. Rotate count must be a constant.
CC_ROLc : Rotate Left 32 bits. Rotate count must be a constant.
CC_ROR64 : Rotate Right 64 bits. Rotate count can be a variable.
CC_ROL64 : Rotate Left 64 bits. Rotate count can be a variable.
CC_ROR64c : Rotate Right 64 bits. Rotate count must be a constant.
CC_ROL64c : Rotate Left 64 bits. Rotate count must be a constant.
CC_BSWAP : byte swap a 32 bits variable.
CC_H2BE32 : convert a 32 bits value between host and big endian order.
CC_H2LE32 : convert a 32 bits value between host and little endian order.
CC_BSWAP64 : byte swap a 64 bits variable
CC_READ_LE32 : read a 32 bits little endian value
CC_WRITE_LE32 : write a 32 bits little endian value
CC_WRITE_LE64 : write a 64 bits little endian value
CC_H2BE64 : convert a 64 bits value between host and big endian order
CC_H2LE64 : convert a 64 bits value between host and little endian order
*/
// RTKitOSPlatform should replace CC_MEMCPY with memcpy
#define CC_MEMCPY(D,S,L) cc_memcpy((D),(S),(L))
#define CC_MEMMOVE(D,S,L) cc_memmove((D),(S),(L))
#define CC_MEMSET(D,V,L) cc_memset((D),(V),(L))
#if __has_builtin(__builtin___memcpy_chk) && !defined(_MSC_VER)
#define cc_memcpy(dst, src, len) __builtin___memcpy_chk((dst), (src), (len), __builtin_object_size((dst), 1))
#define cc_memcpy_nochk(dst, src, len) __builtin___memcpy_chk((dst), (src), (len), __builtin_object_size((dst), 0))
#else
#define cc_memcpy(dst, src, len) memcpy((dst), (src), (len))
#define cc_memcpy_nochk(dst, src, len) memcpy((dst), (src), (len))
#endif
#if __has_builtin(__builtin___memmove_chk) && !defined(_MSC_VER)
#define cc_memmove(dst, src, len) __builtin___memmove_chk((dst), (src), (len), __builtin_object_size((dst), 1))
#else
#define cc_memmove(dst, src, len) memmove((dst), (src), (len))
#endif
#if __has_builtin(__builtin___memset_chk) && !defined(_MSC_VER)
#define cc_memset(dst, val, len) __builtin___memset_chk((dst), (val), (len), __builtin_object_size((dst), 1))
#else
#define cc_memset(dst, val, len) memset((dst), (val), (len))
#endif
#define CC_ARRAY_LEN(x) (sizeof((x))/sizeof((x)[0]))
// MARK: - Loads and Store
// MARK: -- 32 bits - little endian
// MARK: --- Default version
#define CC_STORE32_LE(x, y) do { \
((unsigned char *)(y))[3] = (unsigned char)(((x)>>24)&255); \
((unsigned char *)(y))[2] = (unsigned char)(((x)>>16)&255); \
((unsigned char *)(y))[1] = (unsigned char)(((x)>>8)&255); \
((unsigned char *)(y))[0] = (unsigned char)((x)&255); \
} while(0)
#define CC_LOAD32_LE(x, y) do { \
x = ((uint32_t)(((const unsigned char *)(y))[3] & 255)<<24) | \
((uint32_t)(((const unsigned char *)(y))[2] & 255)<<16) | \
((uint32_t)(((const unsigned char *)(y))[1] & 255)<<8) | \
((uint32_t)(((const unsigned char *)(y))[0] & 255)); \
} while(0)
// MARK: -- 64 bits - little endian
#define CC_STORE64_LE(x, y) do { \
((unsigned char *)(y))[7] = (unsigned char)(((x)>>56)&255); \
((unsigned char *)(y))[6] = (unsigned char)(((x)>>48)&255); \
((unsigned char *)(y))[5] = (unsigned char)(((x)>>40)&255); \
((unsigned char *)(y))[4] = (unsigned char)(((x)>>32)&255); \
((unsigned char *)(y))[3] = (unsigned char)(((x)>>24)&255); \
((unsigned char *)(y))[2] = (unsigned char)(((x)>>16)&255); \
((unsigned char *)(y))[1] = (unsigned char)(((x)>>8)&255); \
((unsigned char *)(y))[0] = (unsigned char)((x)&255); \
} while(0)
#define CC_LOAD64_LE(x, y) do { \
x = (((uint64_t)(((const unsigned char *)(y))[7] & 255))<<56) | \
(((uint64_t)(((const unsigned char *)(y))[6] & 255))<<48) | \
(((uint64_t)(((const unsigned char *)(y))[5] & 255))<<40) | \
(((uint64_t)(((const unsigned char *)(y))[4] & 255))<<32) | \
(((uint64_t)(((const unsigned char *)(y))[3] & 255))<<24) | \
(((uint64_t)(((const unsigned char *)(y))[2] & 255))<<16) | \
(((uint64_t)(((const unsigned char *)(y))[1] & 255))<<8) | \
(((uint64_t)(((const unsigned char *)(y))[0] & 255))); \
} while(0)
// MARK: -- 32 bits - big endian
// MARK: --- intel version
#if (defined(__i386__) || defined(__x86_64__)) && !defined(_MSC_VER)
#define CC_STORE32_BE(x, y) \
__asm__ __volatile__ ( \
"bswapl %0 \n\t" \
"movl %0,(%1)\n\t" \
"bswapl %0 \n\t" \
::"r"(x), "r"(y))
#define CC_LOAD32_BE(x, y) \
__asm__ __volatile__ ( \
"movl (%1),%0\n\t" \
"bswapl %0\n\t" \
:"=r"(x): "r"(y))
#else
// MARK: --- default version
#define CC_STORE32_BE(x, y) do { \
((unsigned char *)(y))[0] = (unsigned char)(((x)>>24)&255); \
((unsigned char *)(y))[1] = (unsigned char)(((x)>>16)&255); \
((unsigned char *)(y))[2] = (unsigned char)(((x)>>8)&255); \
((unsigned char *)(y))[3] = (unsigned char)((x)&255); \
} while(0)
#define CC_LOAD32_BE(x, y) do { \
x = ((uint32_t)(((const unsigned char *)(y))[0] & 255)<<24) | \
((uint32_t)(((const unsigned char *)(y))[1] & 255)<<16) | \
((uint32_t)(((const unsigned char *)(y))[2] & 255)<<8) | \
((uint32_t)(((const unsigned char *)(y))[3] & 255)); \
} while(0)
#endif
// MARK: -- 64 bits - big endian
// MARK: --- intel 64 bits version
#if defined(__x86_64__) && !defined (_MSC_VER)
#define CC_STORE64_BE(x, y) \
__asm__ __volatile__ ( \
"bswapq %0 \n\t" \
"movq %0,(%1)\n\t" \
"bswapq %0 \n\t" \
::"r"(x), "r"(y))
#define CC_LOAD64_BE(x, y) \
__asm__ __volatile__ ( \
"movq (%1),%0\n\t" \
"bswapq %0\n\t" \
:"=r"(x): "r"(y))
#else
// MARK: --- default version
#define CC_STORE64_BE(x, y) do { \
((unsigned char *)(y))[0] = (unsigned char)(((x)>>56)&255); \
((unsigned char *)(y))[1] = (unsigned char)(((x)>>48)&255); \
((unsigned char *)(y))[2] = (unsigned char)(((x)>>40)&255); \
((unsigned char *)(y))[3] = (unsigned char)(((x)>>32)&255); \
((unsigned char *)(y))[4] = (unsigned char)(((x)>>24)&255); \
((unsigned char *)(y))[5] = (unsigned char)(((x)>>16)&255); \
((unsigned char *)(y))[6] = (unsigned char)(((x)>>8)&255); \
((unsigned char *)(y))[7] = (unsigned char)((x)&255); \
} while(0)
#define CC_LOAD64_BE(x, y) do { \
x = (((uint64_t)(((const unsigned char *)(y))[0] & 255))<<56) | \
(((uint64_t)(((const unsigned char *)(y))[1] & 255))<<48) | \
(((uint64_t)(((const unsigned char *)(y))[2] & 255))<<40) | \
(((uint64_t)(((const unsigned char *)(y))[3] & 255))<<32) | \
(((uint64_t)(((const unsigned char *)(y))[4] & 255))<<24) | \
(((uint64_t)(((const unsigned char *)(y))[5] & 255))<<16) | \
(((uint64_t)(((const unsigned char *)(y))[6] & 255))<<8) | \
(((uint64_t)(((const unsigned char *)(y))[7] & 255))); \
} while(0)
#endif
// MARK: - 32-bit Rotates
#if defined(_MSC_VER)
// MARK: -- MSVC version
#include <stdlib.h>
#if !defined(__clang__)
#pragma intrinsic(_lrotr,_lrotl)
#endif
#define CC_ROR(x,n) _lrotr(x,n)
#define CC_ROL(x,n) _lrotl(x,n)
#define CC_RORc(x,n) _lrotr(x,n)
#define CC_ROLc(x,n) _lrotl(x,n)
#elif (defined(__i386__) || defined(__x86_64__))
// MARK: -- intel asm version
CC_INLINE uint32_t CC_ROL(uint32_t word, int i)
{
__asm__ ("roll %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
}
CC_INLINE uint32_t CC_ROR(uint32_t word, int i)
{
__asm__ ("rorl %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
}
/* Need to be a macro here, because 'i' is an immediate (constant) */
#define CC_ROLc(word, i) \
({ uint32_t _word=(word); \
__asm__ __volatile__ ("roll %2,%0" \
:"=r" (_word) \
:"0" (_word),"I" (i)); \
_word; \
})
#define CC_RORc(word, i) \
({ uint32_t _word=(word); \
__asm__ __volatile__ ("rorl %2,%0" \
:"=r" (_word) \
:"0" (_word),"I" (i)); \
_word; \
})
#else
// MARK: -- default version
CC_INLINE uint32_t CC_ROL(uint32_t word, int i)
{
return ( (word<<(i&31)) | (word>>(32-(i&31))) );
}
CC_INLINE uint32_t CC_ROR(uint32_t word, int i)
{
return ( (word>>(i&31)) | (word<<(32-(i&31))) );
}
#define CC_ROLc(x, y) CC_ROL(x, y)
#define CC_RORc(x, y) CC_ROR(x, y)
#endif
// MARK: - 64 bits rotates
#if defined(__x86_64__) && !defined(_MSC_VER) //clang _MSVC doesn't support GNU-style inline assembly
// MARK: -- intel 64 asm version
CC_INLINE uint64_t CC_ROL64(uint64_t word, int i)
{
__asm__("rolq %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
}
CC_INLINE uint64_t CC_ROR64(uint64_t word, int i)
{
__asm__("rorq %%cl,%0"
:"=r" (word)
:"0" (word),"c" (i));
return word;
}
/* Need to be a macro here, because 'i' is an immediate (constant) */
#define CC_ROL64c(word, i) \
({ \
uint64_t _word=(word); \
__asm__("rolq %2,%0" \
:"=r" (_word) \
:"0" (_word),"J" (i)); \
_word; \
})
#define CC_ROR64c(word, i) \
({ \
uint64_t _word=(word); \
__asm__("rorq %2,%0" \
:"=r" (_word) \
:"0" (_word),"J" (i)); \
_word; \
})
#else /* Not x86_64 */
// MARK: -- default C version
CC_INLINE uint64_t CC_ROL64(uint64_t word, int i)
{
return ( (word<<(i&63)) | (word>>(64-(i&63))) );
}
CC_INLINE uint64_t CC_ROR64(uint64_t word, int i)
{
return ( (word>>(i&63)) | (word<<(64-(i&63))) );
}
#define CC_ROL64c(x, y) CC_ROL64(x, y)
#define CC_ROR64c(x, y) CC_ROR64(x, y)
#endif
// MARK: - Byte Swaps
#if __has_builtin(__builtin_bswap32)
#define CC_BSWAP32(x) __builtin_bswap32(x)
#else
CC_INLINE uint32_t CC_BSWAP32(uint32_t x)
{
return
((x & 0xff000000) >> 24) |
((x & 0x00ff0000) >> 8) |
((x & 0x0000ff00) << 8) |
((x & 0x000000ff) << 24);
}
#endif
#if __has_builtin(__builtin_bswap64)
#define CC_BSWAP64(x) __builtin_bswap64(x)
#else
CC_INLINE uint64_t CC_BSWAP64(uint64_t x)
{
return
((x & 0xff00000000000000ULL) >> 56) |
((x & 0x00ff000000000000ULL) >> 40) |
((x & 0x0000ff0000000000ULL) >> 24) |
((x & 0x000000ff00000000ULL) >> 8) |
((x & 0x00000000ff000000ULL) << 8) |
((x & 0x0000000000ff0000ULL) << 24) |
((x & 0x000000000000ff00ULL) << 40) |
((x & 0x00000000000000ffULL) << 56);
}
#endif
#ifdef __LITTLE_ENDIAN__
#define CC_H2BE32(x) CC_BSWAP32(x)
#define CC_H2LE32(x) (x)
#define CC_H2BE64(x) CC_BSWAP64(x)
#define CC_H2LE64(x) (x)
#else
#define CC_H2BE32(x) (x)
#define CC_H2LE32(x) CC_BSWAP32(x)
#define CC_H2BE64(x) (x)
#define CC_H2LE64(x) CC_BSWAP64(x)
#endif
#define CC_READ_LE32(ptr) \
( (uint32_t)( \
((uint32_t)((const uint8_t *)(ptr))[0]) | \
(((uint32_t)((const uint8_t *)(ptr))[1]) << 8) | \
(((uint32_t)((const uint8_t *)(ptr))[2]) << 16) | \
(((uint32_t)((const uint8_t *)(ptr))[3]) << 24)))
#define CC_WRITE_LE32(ptr, x) \
do { \
((uint8_t *)(ptr))[0] = (uint8_t)( (x) & 0xFF); \
((uint8_t *)(ptr))[1] = (uint8_t)(((x) >> 8) & 0xFF); \
((uint8_t *)(ptr))[2] = (uint8_t)(((x) >> 16) & 0xFF); \
((uint8_t *)(ptr))[3] = (uint8_t)(((x) >> 24) & 0xFF); \
} while(0)
#define CC_WRITE_LE64(ptr, x) \
do { \
((uint8_t *)(ptr))[0] = (uint8_t)( (x) & 0xFF); \
((uint8_t *)(ptr))[1] = (uint8_t)(((x) >> 8) & 0xFF); \
((uint8_t *)(ptr))[2] = (uint8_t)(((x) >> 16) & 0xFF); \
((uint8_t *)(ptr))[3] = (uint8_t)(((x) >> 24) & 0xFF); \
((uint8_t *)(ptr))[4] = (uint8_t)(((x) >> 32) & 0xFF); \
((uint8_t *)(ptr))[5] = (uint8_t)(((x) >> 40) & 0xFF); \
((uint8_t *)(ptr))[6] = (uint8_t)(((x) >> 48) & 0xFF); \
((uint8_t *)(ptr))[7] = (uint8_t)(((x) >> 56) & 0xFF); \
} while(0)
/* extract a byte portably */
#ifdef _MSC_VER
#define cc_byte(x, n) ((unsigned char)((x) >> (8 * (n))))
#else
#define cc_byte(x, n) (((x) >> (8 * (n))) & 255)
#endif
/* Count leading zeros (for nonzero inputs) */
/*
* On i386 and x86_64, we know clang and GCC will generate BSR for
* __builtin_clzl. This instruction IS NOT constant time on all micro-
* architectures, but it *is* constant time on all micro-architectures that
* have been used by Apple, and we expect that to continue to be the case.
*
* When building for x86_64h with clang, this produces LZCNT, which is exactly
* what we want.
*
* On arm and arm64, we know that clang and GCC generate the constant-time CLZ
* instruction from __builtin_clzl( ).
*/
#if defined(_WIN32)
/* We use the Windows implementations below. */
#elif defined(__x86_64__) || defined(__i386__) || defined(__arm64__) || defined(__arm__)
/* We use a thought-to-be-good version of __builtin_clz. */
#elif defined __GNUC__
#warning Using __builtin_clz() on an unknown architecture; it may not be constant-time.
/* If you find yourself seeing this warning, file a radar for someone to
* check whether or not __builtin_clz() generates a constant-time
* implementation on the architecture you are targeting. If it does, append
* the name of that architecture to the list of "safe" architectures above. */
#endif
CC_INLINE CC_CONST unsigned cc_clz32_fallback(uint32_t data)
{
unsigned int b = 0;
unsigned int bit = 0;
// Work from LSB to MSB
for (int i = 0; i < 32; i++) {
bit = (data >> i) & 1;
// If the bit is 0, update the "leading bits are zero" counter "b".
b += (1 - bit);
/* If the bit is 0, (bit - 1) is 0xffff... therefore b is retained.
* If the bit is 1, (bit - 1) is 0 therefore b is set to 0.
*/
b &= (bit - 1);
}
return b;
}
CC_INLINE CC_CONST unsigned cc_clz64_fallback(uint64_t data)
{
unsigned int b = 0;
unsigned int bit = 0;
// Work from LSB to MSB
for (int i = 0; i < 64; i++) {
bit = (data >> i) & 1;
// If the bit is 0, update the "leading bits are zero" counter.
b += (1 - bit);
/* If the bit is 0, (bit - 1) is 0xffff... therefore b is retained.
* If the bit is 1, (bit - 1) is 0 therefore b is set to 0.
*/
b &= (bit - 1);
}
return b;
}
CC_INLINE CC_CONST unsigned cc_ctz32_fallback(uint32_t data)
{
unsigned int b = 0;
unsigned int bit = 0;
// Work from MSB to LSB
for (int i = 31; i >= 0; i--) {
bit = (data >> i) & 1;
// If the bit is 0, update the "trailing zero bits" counter.
b += (1 - bit);
/* If the bit is 0, (bit - 1) is 0xffff... therefore b is retained.
* If the bit is 1, (bit - 1) is 0 therefore b is set to 0.
*/
b &= (bit - 1);
}
return b;
}
CC_INLINE CC_CONST unsigned cc_ctz64_fallback(uint64_t data)
{
unsigned int b = 0;
unsigned int bit = 0;
// Work from MSB to LSB
for (int i = 63; i >= 0; i--) {
bit = (data >> i) & 1;
// If the bit is 0, update the "trailing zero bits" counter.
b += (1 - bit);
/* If the bit is 0, (bit - 1) is 0xffff... therefore b is retained.
* If the bit is 1, (bit - 1) is 0 therefore b is set to 0.
*/
b &= (bit - 1);
}
return b;
}
/*!
@function cc_clz32
@abstract Count leading zeros of a nonzero 32-bit value
@param data A nonzero 32-bit value
@result Count of leading zeros of @p data
@discussion @p data is assumed to be nonzero.
*/
CC_INLINE CC_CONST unsigned cc_clz32(uint32_t data) {
cc_assert(data != 0);
#if defined(_WIN32)
return cc_clz32_fallback(data);
#elif defined(__x86_64__) || defined(__i386__) || defined(__arm64__) || defined(__arm__) || defined(__GNUC__)
cc_static_assert(sizeof(unsigned) == 4, "clz relies on an unsigned int being 4 bytes");
return (unsigned)__builtin_clz(data);
#else
return cc_clz32_fallback(data);
#endif
}
/*!
@function cc_clz64
@abstract Count leading zeros of a nonzero 64-bit value
@param data A nonzero 64-bit value
@result Count of leading zeros of @p data
@discussion @p data is assumed to be nonzero.
*/
CC_INLINE CC_CONST unsigned cc_clz64(uint64_t data) {
cc_assert(data != 0);
#if defined(_WIN32)
return cc_clz64_fallback(data);
#elif defined(__x86_64__) || defined(__i386__) || defined(__arm64__) || defined(__arm__) || defined(__GNUC__)
return (unsigned)__builtin_clzll(data);
#else
return cc_clz64_fallback(data);
#endif
}
/*!
@function cc_ctz32
@abstract Count trailing zeros of a nonzero 32-bit value
@param data A nonzero 32-bit value
@result Count of trailing zeros of @p data
@discussion @p data is assumed to be nonzero.
*/
CC_INLINE CC_CONST unsigned cc_ctz32(uint32_t data) {
cc_assert(data != 0);
#if defined(_WIN32)
return cc_ctz32_fallback(data);
#elif defined(__x86_64__) || defined(__i386__) || defined(__arm64__) || defined(__arm__) || defined(__GNUC__)
cc_static_assert(sizeof(unsigned) == 4, "ctz relies on an unsigned int being 4 bytes");
return (unsigned)__builtin_ctz(data);
#else
return cc_ctz32_fallback(data);
#endif
}
/*!
@function cc_ctz64
@abstract Count trailing zeros of a nonzero 64-bit value
@param data A nonzero 64-bit value
@result Count of trailing zeros of @p data
@discussion @p data is assumed to be nonzero.
*/
CC_INLINE CC_CONST unsigned cc_ctz64(uint64_t data) {
cc_assert(data != 0);
#if defined(_WIN32)
return cc_ctz64_fallback(data);
#elif defined(__x86_64__) || defined(__i386__) || defined(__arm64__) || defined(__arm__) || defined(__GNUC__)
return (unsigned)__builtin_ctzll(data);
#else
return cc_ctz64_fallback(data);
#endif
}
/*!
@function cc_ffs32_fallback
@abstract Find first bit set in a 32-bit value
@param data A 32-bit value
@result One plus the index of the least-significant bit set in @p data or, if @p data is zero, zero
*/
CC_INLINE CC_CONST unsigned cc_ffs32_fallback(int32_t data)
{
unsigned b = 0;
unsigned bit = 0;
unsigned seen = 0;
// Work from LSB to MSB
for (int i = 0; i < 32; i++) {
bit = ((uint32_t)data >> i) & 1;
// Track whether we've seen a 1 bit.
seen |= bit;
// If the bit is 0 and we haven't seen a 1 yet, increment b.
b += (1 - bit) & (seen - 1);
}
// If we saw a 1, return b + 1, else 0.
return (~(seen - 1)) & (b + 1);
}
/*!
@function cc_ffs64_fallback
@abstract Find first bit set in a 64-bit value
@param data A 64-bit value
@result One plus the index of the least-significant bit set in @p data or, if @p data is zero, zero
*/
CC_INLINE CC_CONST unsigned cc_ffs64_fallback(int64_t data)
{
unsigned b = 0;
unsigned bit = 0;
unsigned seen = 0;
// Work from LSB to MSB
for (int i = 0; i < 64; i++) {
bit = ((uint64_t)data >> i) & 1;
// Track whether we've seen a 1 bit.
seen |= bit;
// If the bit is 0 and we haven't seen a 1 yet, increment b.
b += (1 - bit) & (seen - 1);
}
// If we saw a 1, return b + 1, else 0.
return (~(seen - 1)) & (b + 1);
}
/*!
@function cc_ffs32
@abstract Find first bit set in a 32-bit value
@param data A 32-bit value
@result One plus the index of the least-significant bit set in @p data or, if @p data is zero, zero
*/
CC_INLINE CC_CONST unsigned cc_ffs32(int32_t data)
{
cc_static_assert(sizeof(int) == 4, "ffs relies on an int being 4 bytes");
#ifdef _WIN32
return cc_ffs32_fallback(data);
#else
return (unsigned)__builtin_ffs(data);
#endif
}
/*!
@function cc_ffs64
@abstract Find first bit set in a 64-bit value
@param data A 64-bit value
@result One plus the index of the least-significant bit set in @p data or, if @p data is zero, zero
*/
CC_INLINE CC_CONST unsigned cc_ffs64(int64_t data)
{
#ifdef _WIN32
return cc_ffs64_fallback(data);
#else
return (unsigned)__builtin_ffsll(data);
#endif
}
#define cc_add_overflow __builtin_add_overflow
#define cc_mul_overflow __builtin_mul_overflow
/* HEAVISIDE_STEP (shifted by one)
function f(x): x->0, when x=0
x->1, when x>0
Can also be seen as a bitwise operation:
f(x): x -> y
y[0]=(OR x[i]) for all i (all bits)
y[i]=0 for all i>0
Run in constant time (log2(<bitsize of x>))
Useful to run constant time checks
*/
#define CC_HEAVISIDE_STEP(r, s) { \
const uint64_t _s = (uint64_t)s; \
const uint64_t _t = (_s & 0xffffffff) | (_s >> 32); \
r = (__typeof__(r))((0xffffffff + _t) >> 32); \
}
/* Return 1 if x mod 4 =1,2,3, 0 otherwise */
#define CC_CARRY_2BITS(x) (((x>>1) | x) & 0x1)
#define CC_CARRY_3BITS(x) (((x>>2) | (x>>1) | x) & 0x1)
#define cc_ceiling(a,b) (((a)+((b)-1))/(b))
#define CC_BITLEN_TO_BYTELEN(x) cc_ceiling((x), 8)
/*!
@brief cc_muxp(s, a, b) is equivalent to z = s ? a : b, but it executes in constant time
@param a input pointer
@param b input pointer
@param s The selection parameter s must be 0 or 1. if s is integer 1 a is returned. If s is integer 0, b is returned. Otherwise, the output is undefined.
@return Returns a, if s is 1 and b if s is 0
*/
void *cc_muxp(int s, const void *a, const void *b);
/*!
@brief CC_MUXU(r, s, a, b) is equivalent to r = s ? a : b, but executes in constant time
@param a Input a
@param b Input b
@param s Selection parameter s. Must be 0 or 1.
@param r Output, set to a if s=1, or b if s=0.
*/
#define CC_MUXU(r, s, a, b) \
{ \
__typeof__(r) _cond = (__typeof__(r))((s)-1); \
r = (~_cond & (a)) | (_cond & (b)); \
}
#define CC_PROVIDES_ABORT (!(CC_USE_SEPROM || CC_USE_S3 || CC_BASEBAND || CC_EFI || CC_IBOOT || CC_RTKITROM))
/*!
@function cc_abort
@abstract Abort execution unconditionally
*/
CC_NORETURN
void cc_abort(const char *msg);
/*!
@function cc_try_abort
@abstract Abort execution iff the platform provides a function like @p abort() or @p panic()
@discussion If the platform does not provide a means to abort execution, this function does nothing; therefore, callers should return an error code after calling this function.
*/
#if CC_PROVIDES_ABORT
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-noreturn"
CC_INLINE
void cc_try_abort(const char *msg)
{
cc_abort(msg);
}
#pragma clang diagnostic pop
#else
CC_INLINE
void cc_try_abort(CC_UNUSED const char *msg)
{
}
#endif
#if __has_builtin(__builtin_expect)
#define CC_UNLIKELY(cond) __builtin_expect(cond, 0)
#else
#define CC_UNLIKELY(cond) cond
#endif
CC_INLINE
void cc_try_abort_if(bool condition, const char *msg)
{
if (CC_UNLIKELY(condition)) {
cc_try_abort(msg);
}
}
/*
Unfortunately, since we export this symbol, this declaration needs
to be in a public header to satisfy TAPI.
See fipspost_trace_priv.h for more details.
*/
extern const void *fipspost_trace_vtable;
#endif /* _CORECRYPTO_CC_PRIV_H_ */

View File

@ -0,0 +1,89 @@
/* Copyright (c) (2012,2014,2015,2016,2017,2018,2019,2020) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef CORECRYPTO_CC_RUNTIME_CONFIG_H_
#define CORECRYPTO_CC_RUNTIME_CONFIG_H_
#include <corecrypto/cc_config.h>
/* Only intel systems have these runtime switches today. */
#if defined(__x86_64__) || defined(__i386__)
#if CC_KERNEL
#include <i386/cpuid.h>
#define CC_HAS_RDRAND() ((cpuid_features() & CPUID_FEATURE_RDRAND) != 0)
#define CC_HAS_AESNI() ((cpuid_features() & CPUID_FEATURE_AES) != 0)
#define CC_HAS_SupplementalSSE3() ((cpuid_features() & CPUID_FEATURE_SSSE3) != 0)
#define CC_HAS_AVX1() ((cpuid_features() & CPUID_FEATURE_AVX1_0) != 0)
#define CC_HAS_AVX2() ((cpuid_info()->cpuid_leaf7_features & CPUID_LEAF7_FEATURE_AVX2) != 0)
#define CC_HAS_AVX512_AND_IN_KERNEL() ((cpuid_info()->cpuid_leaf7_features & CPUID_LEAF7_FEATURE_AVX512F) !=0)
#define CC_HAS_BMI2() ((cpuid_info()->cpuid_leaf7_features & CPUID_LEAF7_FEATURE_BMI2) != 0)
#define CC_HAS_ADX() ((cpuid_info()->cpuid_leaf7_features & CPUID_LEAF7_FEATURE_ADX) != 0)
#elif CC_XNU_KERNEL_AVAILABLE && CC_INTERNAL_SDK
#include <System/i386/cpu_capabilities.h>
#define CC_HAS_RDRAND() (_get_cpu_capabilities() & kHasRDRAND)
#define CC_HAS_AESNI() (_get_cpu_capabilities() & kHasAES)
#define CC_HAS_SupplementalSSE3() (_get_cpu_capabilities() & kHasSupplementalSSE3)
#define CC_HAS_AVX1() (_get_cpu_capabilities() & kHasAVX1_0)
#define CC_HAS_AVX2() (_get_cpu_capabilities() & kHasAVX2_0)
#define CC_HAS_AVX512_AND_IN_KERNEL() 0
#define CC_HAS_BMI2() (_get_cpu_capabilities() & kHasBMI2)
#define CC_HAS_ADX() (_get_cpu_capabilities() & kHasADX)
#elif CC_SGX
// SGX has no cpuid function, so these will fail
#define CC_HAS_AESNI() 0
#define CC_HAS_SupplementalSSE3() 0
#define CC_HAS_AVX1() 0
#define CC_HAS_AVX2() 0
#define CC_HAS_AVX512_AND_IN_KERNEL() 0
#define CC_HAS_BMI2() 0
#define CC_HAS_RDRAND() 0
#define CC_HAS_ADX() 0
#else
#define CC_HAS_AESNI() __builtin_cpu_supports("aes")
#define CC_HAS_SupplementalSSE3() __builtin_cpu_supports("ssse3")
#define CC_HAS_AVX1() __builtin_cpu_supports("avx")
#define CC_HAS_AVX2() __builtin_cpu_supports("avx2")
#define CC_HAS_AVX512_AND_IN_KERNEL() 0
#define CC_HAS_BMI2() __builtin_cpu_supports("bmi2")
#if CC_LINUX || !CC_INTERNAL_SDK
#include <cpuid.h>
#include <stdbool.h>
CC_INLINE bool _cpu_supports_rdrand()
{
unsigned int eax, ebx, ecx, edx;
__cpuid(1, eax, ebx, ecx, edx);
return ecx & bit_RDRND;
}
CC_INLINE bool _cpu_supports_adx()
{
unsigned int eax, ebx, ecx, edx;
__cpuid_count(7, 0, eax, ebx, ecx, edx);
return ebx & bit_ADX;
}
#define CC_HAS_RDRAND() _cpu_supports_rdrand()
#define CC_HAS_ADX() _cpu_supports_adx()
#else
#define CC_HAS_RDRAND() 0
#define CC_HAS_ADX() 0
#endif
#endif
#endif // defined(__x86_64__) || defined(__i386__)
#endif /* CORECRYPTO_CC_RUNTIME_CONFIG_H_ */

View File

@ -0,0 +1,133 @@
/* Copyright (c) (2010,2011,2012,2013,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCAES_H_
#define _CORECRYPTO_CCAES_H_
#include <corecrypto/cc_config.h>
#include <corecrypto/ccmode.h>
#define CCAES_BLOCK_SIZE 16
#define CCAES_KEY_SIZE_128 16
#define CCAES_KEY_SIZE_192 24
#define CCAES_KEY_SIZE_256 32
#define CCAES_CTR_MAX_PARALLEL_NBLOCKS 8
extern const struct ccmode_ecb ccaes_ltc_ecb_decrypt_mode;
extern const struct ccmode_ecb ccaes_ltc_ecb_encrypt_mode;
extern const struct ccmode_cbc ccaes_gladman_cbc_encrypt_mode;
extern const struct ccmode_cbc ccaes_gladman_cbc_decrypt_mode;
#if CCAES_ARM_ASM
extern const struct ccmode_ecb ccaes_arm_ecb_encrypt_mode;
extern const struct ccmode_ecb ccaes_arm_ecb_decrypt_mode;
extern const struct ccmode_cbc ccaes_arm_cbc_encrypt_mode;
extern const struct ccmode_cbc ccaes_arm_cbc_decrypt_mode;
extern const struct ccmode_xts ccaes_arm_xts_encrypt_mode;
extern const struct ccmode_xts ccaes_arm_xts_decrypt_mode;
extern const struct ccmode_cfb ccaes_arm_cfb_encrypt_mode;
extern const struct ccmode_cfb ccaes_arm_cfb_decrypt_mode;
extern const struct ccmode_ofb ccaes_arm_ofb_crypt_mode;
#endif
#if CCAES_MUX
/* Runtime check to see if hardware should be used */
int ccaes_ios_hardware_enabled(int operation);
extern const struct ccmode_cbc ccaes_ios_hardware_cbc_encrypt_mode;
extern const struct ccmode_cbc ccaes_ios_hardware_cbc_decrypt_mode;
extern const struct ccmode_ctr ccaes_ios_hardware_ctr_crypt_mode;
extern const struct ccmode_cbc *ccaes_ios_mux_cbc_encrypt_mode(void);
extern const struct ccmode_cbc *ccaes_ios_mux_cbc_decrypt_mode(void);
extern const struct ccmode_ctr *ccaes_ios_mux_ctr_crypt_mode(void);
#endif
#if CCAES_INTEL_ASM
extern const struct ccmode_ecb ccaes_intel_ecb_encrypt_opt_mode;
extern const struct ccmode_ecb ccaes_intel_ecb_encrypt_aesni_mode;
extern const struct ccmode_ecb ccaes_intel_ecb_decrypt_opt_mode;
extern const struct ccmode_ecb ccaes_intel_ecb_decrypt_aesni_mode;
extern const struct ccmode_cbc ccaes_intel_cbc_encrypt_opt_mode;
extern const struct ccmode_cbc ccaes_intel_cbc_encrypt_aesni_mode;
extern const struct ccmode_cbc ccaes_intel_cbc_decrypt_opt_mode;
extern const struct ccmode_cbc ccaes_intel_cbc_decrypt_aesni_mode;
extern const struct ccmode_xts ccaes_intel_xts_encrypt_opt_mode;
extern const struct ccmode_xts ccaes_intel_xts_encrypt_aesni_mode;
extern const struct ccmode_xts ccaes_intel_xts_decrypt_opt_mode;
extern const struct ccmode_xts ccaes_intel_xts_decrypt_aesni_mode;
#endif
#if CC_USE_L4
extern const struct ccmode_cbc ccaes_skg_cbc_encrypt_mode;
extern const struct ccmode_cbc ccaes_skg_cbc_decrypt_mode;
extern const struct ccmode_ecb ccaes_skg_ecb_encrypt_mode;
extern const struct ccmode_ecb ccaes_skg_ecb_decrypt_mode;
extern const struct ccmode_ecb ccaes_trng_ecb_encrypt_mode;
#endif
/* Implementation Selectors: */
const struct ccmode_ecb *ccaes_ecb_encrypt_mode(void);
const struct ccmode_cbc *ccaes_cbc_encrypt_mode(void);
const struct ccmode_cfb *ccaes_cfb_encrypt_mode(void);
const struct ccmode_cfb8 *ccaes_cfb8_encrypt_mode(void);
const struct ccmode_xts *ccaes_xts_encrypt_mode(void);
const struct ccmode_gcm *ccaes_gcm_encrypt_mode(void);
const struct ccmode_ccm *ccaes_ccm_encrypt_mode(void);
const struct ccmode_ecb *ccaes_ecb_decrypt_mode(void);
const struct ccmode_cbc *ccaes_cbc_decrypt_mode(void);
const struct ccmode_cfb *ccaes_cfb_decrypt_mode(void);
const struct ccmode_cfb8 *ccaes_cfb8_decrypt_mode(void);
const struct ccmode_xts *ccaes_xts_decrypt_mode(void);
const struct ccmode_gcm *ccaes_gcm_decrypt_mode(void);
const struct ccmode_ccm *ccaes_ccm_decrypt_mode(void);
const struct ccmode_ctr *ccaes_ctr_crypt_mode(void);
const struct ccmode_ofb *ccaes_ofb_crypt_mode(void);
const struct ccmode_siv *ccaes_siv_encrypt_mode(void);
const struct ccmode_siv *ccaes_siv_decrypt_mode(void);
const struct ccmode_siv_hmac *ccaes_siv_hmac_sha256_encrypt_mode(void);
const struct ccmode_siv_hmac *ccaes_siv_hmac_sha256_decrypt_mode(void);
/*!
@function ccaes_unwind
@abstract "Unwind" an AES encryption key to the equivalent decryption key.
@param key_nbytes Length in bytes of both the input and output keys
@param key The input AES encryption key
@param out The output AES decryption key
@result @p CCERR_OK iff successful.
@discussion Only AES256 (i.e. 32-byte) keys are supported. This function is not necessary in typical AES usage; consult the maintainers before using it.
*/
int ccaes_unwind(size_t key_nbytes, const void *key, void *out);
#endif /* _CORECRYPTO_CCAES_H_ */

View File

@ -0,0 +1,88 @@
/* Copyright (c) (2010,2011,2012,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCASN1_H_
#define _CORECRYPTO_CCASN1_H_
#include <corecrypto/cc.h>
#include <stdbool.h>
#include <string.h>
/* ASN.1 types for on the fly ASN.1 BER/DER encoding/decoding. Don't use
these with the ccder interface, use the CCDER_ types instead. */
enum {
CCASN1_EOL = 0x00,
CCASN1_BOOLEAN = 0x01,
CCASN1_INTEGER = 0x02,
CCASN1_BIT_STRING = 0x03,
CCASN1_OCTET_STRING = 0x04,
CCASN1_NULL = 0x05,
CCASN1_OBJECT_IDENTIFIER = 0x06,
CCASN1_OBJECT_DESCRIPTOR = 0x07,
/* External or instance-of 0x08 */
CCASN1_REAL = 0x09,
CCASN1_ENUMERATED = 0x0a,
CCASN1_EMBEDDED_PDV = 0x0b,
CCASN1_UTF8_STRING = 0x0c,
/* 0x0d */
/* 0x0e */
/* 0x0f */
CCASN1_SEQUENCE = 0x10,
CCASN1_SET = 0x11,
CCASN1_NUMERIC_STRING = 0x12,
CCASN1_PRINTABLE_STRING = 0x13,
CCASN1_T61_STRING = 0x14,
CCASN1_VIDEOTEX_STRING = 0x15,
CCASN1_IA5_STRING = 0x16,
CCASN1_UTC_TIME = 0x17,
CCASN1_GENERALIZED_TIME = 0x18,
CCASN1_GRAPHIC_STRING = 0x19,
CCASN1_VISIBLE_STRING = 0x1a,
CCASN1_GENERAL_STRING = 0x1b,
CCASN1_UNIVERSAL_STRING = 0x1c,
/* 0x1d */
CCASN1_BMP_STRING = 0x1e,
CCASN1_HIGH_TAG_NUMBER = 0x1f,
CCASN1_TELETEX_STRING = CCASN1_T61_STRING,
CCASN1_TAG_MASK = 0xff,
CCASN1_TAGNUM_MASK = 0x1f,
CCASN1_METHOD_MASK = 0x20,
CCASN1_PRIMITIVE = 0x00,
CCASN1_CONSTRUCTED = 0x20,
CCASN1_CLASS_MASK = 0xc0,
CCASN1_UNIVERSAL = 0x00,
CCASN1_APPLICATION = 0x40,
CCASN1_CONTEXT_SPECIFIC = 0x80,
CCASN1_PRIVATE = 0xc0,
CCASN1_CONSTRUCTED_SET = CCASN1_SET | CCASN1_CONSTRUCTED,
CCASN1_CONSTRUCTED_SEQUENCE = CCASN1_SEQUENCE | CCASN1_CONSTRUCTED,
};
typedef const unsigned char * ccoid_t;
#define CCOID(oid) (oid)
/* Returns the size of an oid including it's tag and length. */
CC_INLINE CC_PURE CC_NONNULL((1))
size_t ccoid_size(ccoid_t oid) {
return 2 + CCOID(oid)[1];
}
CC_INLINE CC_PURE CC_NONNULL((1, 2))
bool ccoid_equal(ccoid_t oid1, ccoid_t oid2) {
return (ccoid_size(oid1) == ccoid_size(oid2)
&& memcmp(CCOID(oid1), CCOID(oid2), ccoid_size(oid1))== 0);
}
#endif /* _CORECRYPTO_CCASN1_H_ */

View File

@ -0,0 +1,297 @@
/* Copyright (c) (2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCCHACHA20POLY1305_H_
#define _CORECRYPTO_CCCHACHA20POLY1305_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#define CCCHACHA20_KEY_NBYTES 32
#define CCCHACHA20_BLOCK_NBYTES 64
#define CCCHACHA20_BLOCK_NBITS (CCCHACHA20_BLOCK_NBYTES * 8)
#define CCCHACHA20_NONCE_NBYTES 12
typedef struct {
uint32_t state[16];
uint8_t buffer[CCCHACHA20_BLOCK_NBYTES];
size_t leftover;
} ccchacha20_ctx;
#define CCPOLY1305_TAG_NBYTES 16
typedef struct {
uint32_t r0, r1, r2, r3, r4;
uint32_t s1, s2, s3, s4;
uint32_t h0, h1, h2, h3, h4;
uint8_t buf[16];
size_t buf_used;
uint8_t key[16];
} ccpoly1305_ctx;
/*!
@group ccchacha20poly1305
@abstract Encrypts and authenticates or decrypts and verifies data.
@discussion See RFC 7539 for details.
@warning The key-nonce pair must be unique per encryption.
@warning A single message can be at most (2^38 - 64) bytes in length.
The correct sequence of calls to encrypt is:
@code ccchacha20poly1305_init(...)
ccchacha20poly1305_setnonce(...)
ccchacha20poly1305_aad(...) (may be called zero or more times)
ccchacha20poly1305_encrypt(...) (may be called zero or more times)
ccchacha20poly1305_finalize(...)
To reuse the context for additional encryptions, follow this sequence:
@code ccchacha20poly1305_reset(...)
ccchacha20poly1305_setnonce(...)
ccchacha20poly1305_aad(...) (may be called zero or more times)
ccchacha20poly1305_encrypt(...) (may be called zero or more times)
ccchacha20poly1305_finalize(...)
To decrypt, follow this call sequence:
@code ccchacha20poly1305_init(...)
ccchacha20poly1305_setnonce(...)
ccchacha20poly1305_aad(...) (may be called zero or more times)
ccchacha20poly1305_decrypt(...) (may be called zero or more times)
ccchacha20poly1305_verify(...) (returns zero on successful decryption)
To reuse the context for additional encryptions, follow this sequence:
@code ccchacha20poly1305_reset(...)
ccchacha20poly1305_setnonce(...)
ccchacha20poly1305_aad(...) (may be called zero or more times)
ccchacha20poly1305_decrypt(...) (may be called zero or more times)
ccchacha20poly1305_verify(...) (returns zero on successful decryption)
*/
#define CCCHACHA20POLY1305_KEY_NBYTES (CCCHACHA20_KEY_NBYTES)
#define CCCHACHA20POLY1305_NONCE_NBYTES (CCCHACHA20_NONCE_NBYTES)
#define CCCHACHA20POLY1305_TAG_NBYTES (CCPOLY1305_TAG_NBYTES)
/* (2^32 - 1) blocks */
/* (2^38 - 64) bytes */
/* (2^41 - 512) bits */
/* Exceeding this figure breaks confidentiality and authenticity. */
#define CCCHACHA20POLY1305_TEXT_MAX_NBYTES ((1ULL << 38) - 64ULL)
#define CCCHACHA20POLY1305_STATE_SETNONCE 1
#define CCCHACHA20POLY1305_STATE_AAD 2
#define CCCHACHA20POLY1305_STATE_ENCRYPT 3
#define CCCHACHA20POLY1305_STATE_DECRYPT 4
#define CCCHACHA20POLY1305_STATE_FINAL 5
typedef struct {
ccchacha20_ctx chacha20_ctx;
ccpoly1305_ctx poly1305_ctx;
uint64_t aad_nbytes;
uint64_t text_nbytes;
uint8_t state;
} ccchacha20poly1305_ctx;
// This is just a stub right now.
// Eventually we will optimize by platform.
struct ccchacha20poly1305_info {
};
const struct ccchacha20poly1305_info *ccchacha20poly1305_info(void);
/*!
@function ccchacha20poly1305_init
@abstract Initialize a chacha20poly1305 context.
@param info Implementation descriptor
@param ctx Context for this instance
@param key Secret chacha20 key
@result 0 iff successful.
@discussion The key is 32 bytes in length.
@warning The key-nonce pair must be unique per encryption.
*/
int ccchacha20poly1305_init(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, const uint8_t *key);
/*!
@function ccchacha20poly1305_reset
@abstract Reset a chacha20poly1305 context for reuse.
@param info Implementation descriptor
@param ctx Context for this instance
@result 0 iff successful.
*/
int ccchacha20poly1305_reset(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx);
/*!
@function ccchacha20poly1305_setnonce
@abstract Set the nonce for encryption or decryption.
@param info Implementation descriptor
@param ctx Context for this instance
@param nonce Unique nonce per encryption
@result 0 iff successful.
@discussion The nonce is 12 bytes in length.
@warning The key-nonce pair must be unique per encryption.
*/
int ccchacha20poly1305_setnonce(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, const uint8_t *nonce);
int ccchacha20poly1305_incnonce(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, uint8_t *nonce);
/*!
@function ccchacha20poly1305_aad
@abstract Authenticate additional data.
@param info Descriptor for the mode
@param ctx Context for this instance
@param nbytes Length of the additional data in bytes
@param aad Additional data to authenticate
@result 0 iff successful.
@discussion This is typically used to authenticate data that cannot be encrypted (e.g. packet headers).
This function may be called zero or more times.
*/
int ccchacha20poly1305_aad(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, size_t nbytes, const void *aad);
/*!
@function ccchacha20poly1305_encrypt
@abstract Encrypt data.
@param info Descriptor for the mode
@param ctx Context for this instance
@param nbytes Length of the plaintext in bytes
@param ptext Input plaintext
@param ctext Output ciphertext
@result 0 iff successful.
@discussion In-place processing is supported.
This function may be called zero or more times.
*/
int ccchacha20poly1305_encrypt(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, size_t nbytes, const void *ptext, void *ctext);
/*!
@function ccchacha20poly1305_finalize
@abstract Finalize encryption.
@param info Descriptor for the mode
@param ctx Context for this instance
@param tag Generated authentication tag
@result 0 iff successful.
@discussion The generated tag is 16 bytes in length.
*/
int ccchacha20poly1305_finalize(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, uint8_t *tag);
/*!
@function ccchacha20poly1305_decrypt
@abstract Decrypt data.
@param info Descriptor for the mode
@param ctx Context for this instance
@param nbytes Length of the ciphertext in bytes
@param ctext Input ciphertext
@param ptext Output plaintext
@result 0 iff successful.
@discussion In-place processing is supported.
This function may be called zero or more times.
*/
int ccchacha20poly1305_decrypt(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, size_t nbytes, const void *ctext, void *ptext);
/*!
@function ccchacha20poly1305_verify
@abstract Verify authenticity.
@param info Descriptor for the mode
@param ctx Context for this instance
@param tag Expected authentication tag
@result 0 iff authentic and otherwise successful.
@discussion The expected tag is 16 bytes in length.
*/
int ccchacha20poly1305_verify(const struct ccchacha20poly1305_info *info, ccchacha20poly1305_ctx *ctx, const uint8_t *tag);
/*!
@function ccchacha20poly1305_encrypt_oneshot
@abstract Encrypt with chacha20poly1305.
@param info Descriptor for the mode
@param key Secret chacha20 key
@param nonce Unique nonce per encryption
@param aad_nbytes Length of the additional data in bytes
@param aad Additional data to authenticate
@param ptext_nbytes Length of the plaintext in bytes
@param ptext Input plaintext
@param ctext Output ciphertext
@param tag Generated authentication tag
@discussion See RFC 7539 for details.
The key is 32 bytes in length.
The nonce is 12 bytes in length.
The generated tag is 16 bytes in length.
In-place processing is supported.
@warning The key-nonce pair must be unique per encryption.
@warning A single message can be at most (2^38 - 64) bytes in length.
*/
int ccchacha20poly1305_encrypt_oneshot(const struct ccchacha20poly1305_info *info, const uint8_t *key, const uint8_t *nonce, size_t aad_nbytes, const void *aad, size_t ptext_nbytes, const void *ptext, void *ctext, uint8_t *tag);
/*!
@function ccchacha20poly1305_decrypt_oneshot
@abstract Decrypt with chacha20poly1305.
@param info Descriptor for the mode
@param key Secret chacha20 key
@param nonce Unique nonce per encryption
@param aad_nbytes Length of the additional data in bytes
@param aad Additional data to authenticate
@param ctext_nbytes Length of the ciphertext in bytes
@param ctext Input ciphertext
@param ptext Output plaintext
@param tag Expected authentication tag
@discussion See RFC 7539 for details.
The key is 32 bytes in length.
The nonce is 12 bytes in length.
The generated tag is 16 bytes in length.
In-place processing is supported.
*/
int ccchacha20poly1305_decrypt_oneshot(const struct ccchacha20poly1305_info *info, const uint8_t *key, const uint8_t *nonce, size_t aad_nbytes, const void *aad, size_t ctext_nbytes, const void *ctext, void *ptext, const uint8_t *tag);
#endif

View File

@ -0,0 +1,181 @@
/* Copyright (c) (2013,2014,2015,2016,2017,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_cccmac_H_
#define _CORECRYPTO_cccmac_H_
#include <corecrypto/cc.h>
#include <corecrypto/ccmode.h>
#include <corecrypto/ccaes.h>
#define CMAC_BLOCKSIZE 16
struct cccmac_ctx {
uint8_t k1[CMAC_BLOCKSIZE];
uint8_t k2[CMAC_BLOCKSIZE];
uint8_t block[CMAC_BLOCKSIZE];
size_t block_nbytes; // Number of byte occupied in block
size_t cumulated_nbytes; // Total size processed
const struct ccmode_cbc *cbc;
uint8_t ctx[1];
} CC_ALIGNED(8);// cccmac_ctx_hdr;
typedef struct cccmac_ctx* cccmac_ctx_t;
#define cccmac_hdr_size sizeof(struct cccmac_ctx)
#define cccmac_iv_size(_mode_) ((_mode_)->block_size)
#define cccmac_cbc_size(_mode_) ((_mode_)->size)
#define cccmac_ctx_size(_mode_) (cccmac_hdr_size + cccmac_iv_size(_mode_) + cccmac_cbc_size(_mode_))
#define cccmac_ctx_n(_mode_) ccn_nof_size(cccmac_ctx_size(_mode_))
#define cccmac_mode_decl(_mode_, _name_) cc_ctx_decl(struct cccmac_ctx, cccmac_ctx_size(_mode_), _name_)
#define cccmac_mode_clear(_mode_, _name_) cc_clear(cccmac_ctx_size(_mode_), _name_)
/* Return a cccbc_ctx * which can be accesed with the macros in ccmode.h */
#define cccmac_mode_ctx_start(_mode_, HC) (HC->ctx)
#define CCCMAC_HDR(HC) (HC)
#define cccmac_mode_sym_ctx(_mode_, HC) (cccbc_ctx *)(cccmac_mode_ctx_start(_mode_, HC))
#define cccmac_mode_iv(_mode_, HC) (cccbc_iv *)(cccmac_mode_ctx_start(_mode_, HC)+cccmac_cbc_size(_mode_))
#define cccmac_k1(HC) (CCCMAC_HDR(HC)->k1)
#define cccmac_k2(HC) (CCCMAC_HDR(HC)->k2)
#define cccmac_block(HC) (CCCMAC_HDR(HC)->block)
#define cccmac_cbc(HC) (CCCMAC_HDR(HC)->cbc)
#define cccmac_block_nbytes(HC) (CCCMAC_HDR(HC)->block_nbytes)
#define cccmac_cumulated_nbytes(HC) (CCCMAC_HDR(HC)->cumulated_nbytes)
/* CMAC as defined in NIST SP800-38B - 2005 */
/* =============================================================================
ONE SHOT
==============================================================================*/
/*!
@function cccmac_one_shot_generate
@abstract CMAC generation in one call
@param cbc CBC and block cipher specification
@param key_nbytes Length of the key in bytes
@param key Pointer to the key of length key_nbytes
@param data_nbytes Length of the data in bytes
@param data Pointer to the data in bytes
@param mac_nbytes Length in byte of the mac, > 0
@param mac Output of length cbc->block_size
@result 0 iff successful.
@discussion Only supports CMAC_BLOCKSIZE block ciphers
*/
int cccmac_one_shot_generate(const struct ccmode_cbc *cbc,
size_t key_nbytes, const void *key,
size_t data_nbytes, const void *data,
size_t mac_nbytes, void *mac);
/*!
@function cccmac_one_shot_verify
@abstract CMAC verification in one call
@param cbc CBC and block cipher specification
@param key_nbytes Length of the key in bytes
@param key Pointer to the key of length key_nbytes
@param data_nbytes Length of the data in bytes
@param data Pointer to the data in bytes
@param expected_mac_nbytes Length in byte of the mac, > 0
@param expected_mac Mac value expected
@result 0 iff successful.
@discussion Only supports CMAC_BLOCKSIZE block ciphers
*/
int cccmac_one_shot_verify(const struct ccmode_cbc *cbc,
size_t key_nbytes, const void *key,
size_t data_nbytes, const void *data,
size_t expected_mac_nbytes, const void *expected_mac);
/* =============================================================================
STREAMING
Init - Update - Final
==============================================================================*/
/*!
@function cccmac_init
@abstract Init CMAC context with CBC mode and key
@param cbc CBC and block cipher specification
@param ctx Context use to store internal state
@param key_nbytes Length of the key in bytes
@param key Full key
@result 0 iff successful.
@discussion Only supports CMAC_BLOCKSIZE block ciphers
*/
int cccmac_init(const struct ccmode_cbc *cbc,
cccmac_ctx_t ctx,
size_t key_nbytes, const void *key);
/*!
@function cccmac_update
@abstract Process data
@param ctx Context use to store internal state
@param data_nbytes Length in byte of the data
@param data Data to process
@result 0 iff successful.
@discussion Only supports CMAC_BLOCKSIZE block ciphers
*/
int cccmac_update(cccmac_ctx_t ctx,
size_t data_nbytes, const void *data);
/*!
@function cccmac_final_generate
@abstract Final step for generation
@param ctx Context use to store internal state
@param mac_nbytes Length in byte of the mac, > 0
@param mac Output of length mac_nbytes
@result 0 iff successful.
@discussion Only supports CMAC_BLOCKSIZE block ciphers
*/
int cccmac_final_generate(cccmac_ctx_t ctx,
size_t mac_nbytes, void *mac);
/*!
@function cccmac_final_verify
@abstract Final step and verification
@param ctx Context use to store internal state
@param expected_mac_nbytes Length in byte of the mac, > 0
@param expected_mac Mac value expected
@result 0 iff successful.
@discussion Only supports CMAC_BLOCKSIZE block ciphers
*/
int cccmac_final_verify(cccmac_ctx_t ctx,
size_t expected_mac_nbytes, const void *expected_mac);
#endif /* _CORECRYPTO_cccmac_H_ */

View File

@ -0,0 +1,65 @@
/* Copyright (c) (2010,2012,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCDES_H_
#define _CORECRYPTO_CCDES_H_
#include <corecrypto/ccmode.h>
#define CCDES_BLOCK_SIZE 8
#define CCDES_KEY_SIZE 8
extern const struct ccmode_ecb ccdes3_ltc_ecb_decrypt_mode;
extern const struct ccmode_ecb ccdes3_ltc_ecb_encrypt_mode;
const struct ccmode_ecb *ccdes_ecb_decrypt_mode(void);
const struct ccmode_ecb *ccdes_ecb_encrypt_mode(void);
const struct ccmode_cbc *ccdes_cbc_decrypt_mode(void);
const struct ccmode_cbc *ccdes_cbc_encrypt_mode(void);
const struct ccmode_cfb *ccdes_cfb_decrypt_mode(void);
const struct ccmode_cfb *ccdes_cfb_encrypt_mode(void);
const struct ccmode_cfb8 *ccdes_cfb8_decrypt_mode(void);
const struct ccmode_cfb8 *ccdes_cfb8_encrypt_mode(void);
const struct ccmode_ctr *ccdes_ctr_crypt_mode(void);
const struct ccmode_ofb *ccdes_ofb_crypt_mode(void);
const struct ccmode_ecb *ccdes3_ecb_decrypt_mode(void);
const struct ccmode_ecb *ccdes3_ecb_encrypt_mode(void);
const struct ccmode_cbc *ccdes3_cbc_decrypt_mode(void);
const struct ccmode_cbc *ccdes3_cbc_encrypt_mode(void);
const struct ccmode_cfb *ccdes3_cfb_decrypt_mode(void);
const struct ccmode_cfb *ccdes3_cfb_encrypt_mode(void);
const struct ccmode_cfb8 *ccdes3_cfb8_decrypt_mode(void);
const struct ccmode_cfb8 *ccdes3_cfb8_encrypt_mode(void);
const struct ccmode_ctr *ccdes3_ctr_crypt_mode(void);
const struct ccmode_ofb *ccdes3_ofb_crypt_mode(void);
int ccdes_key_is_weak( void *key, size_t length);
void ccdes_key_set_odd_parity(void *key, size_t length);
uint32_t
ccdes_cbc_cksum(const void *in, void *out, size_t length,
const void *key, size_t key_nbytes, const void *ivec);
#endif /* _CORECRYPTO_CCDES_H_ */

View File

@ -0,0 +1,115 @@
/* Copyright (c) (2010,2011,2012,2014,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCDIGEST_H_
#define _CORECRYPTO_CCDIGEST_H_
#include <corecrypto/cc.h>
#include <corecrypto/ccn.h>
/* To malloc a digest context for a given di, use malloc(ccdigest_di_size(di))
and assign the result to a pointer to a struct ccdigest_ctx. */
struct ccdigest_ctx {
union {
uint8_t u8;
uint32_t u32;
uint64_t u64;
cc_unit ccn;
} state;
} CC_ALIGNED(8);
typedef struct ccdigest_ctx *ccdigest_ctx_t ;
struct ccdigest_state {
union {
uint8_t u8;
uint32_t u32;
uint64_t u64;
cc_unit ccn;
} state;
} CC_ALIGNED(8);
typedef struct ccdigest_state *ccdigest_state_t;
struct ccdigest_info {
size_t output_size;
size_t state_size;
size_t block_size;
size_t oid_size;
const unsigned char *oid;
const void *initial_state;
void(* CC_SPTR(ccdigest_info, compress))(ccdigest_state_t state, size_t nblocks,
const void *data);
void(* CC_SPTR(ccdigest_info, final))(const struct ccdigest_info *di, ccdigest_ctx_t ctx,
unsigned char *digest);
};
/* Return sizeof a ccdigest_ctx for a given size_t _state_size_ and
size_t _block_size_. */
#define ccdigest_ctx_size(_state_size_, _block_size_) ((_state_size_) + sizeof(uint64_t) + (_block_size_) + sizeof(unsigned int))
/* Return sizeof a ccdigest_ctx for a given struct ccdigest_info *_di_. */
#define ccdigest_di_size(_di_) (ccdigest_ctx_size((_di_)->state_size, (_di_)->block_size))
/* Declare a ccdigest_ctx for a given size_t _state_size_ and
size_t _block_size_, named _name_. Can be used in structs or on the
stack. */
#define ccdigest_ctx_decl(_state_size_, _block_size_, _name_) cc_ctx_decl(struct ccdigest_ctx, ccdigest_ctx_size(_state_size_, _block_size_), _name_)
#define ccdigest_ctx_clear(_state_size_, _block_size_, _name_) cc_clear(ccdigest_ctx_size(_state_size_, _block_size_), _name_)
/* Declare a ccdigest_ctx for a given size_t _state_size_ and
size_t _block_size_, named _name_. Can be used on the stack. */
#define ccdigest_di_decl(_di_, _name_) cc_ctx_decl(struct ccdigest_ctx, ccdigest_di_size(_di_), _name_)
#define ccdigest_di_clear(_di_, _name_) cc_clear(ccdigest_di_size(_di_), _name_)
/* Digest context field accessors. Consider the implementation private. */
#define ccdigest_state(_di_, _ctx_) ((struct ccdigest_state *)(&((ccdigest_ctx_t)(_ctx_))->state.u8 + sizeof(uint64_t)))
#define ccdigest_state_u8(_di_, _ctx_) ccdigest_u8(ccdigest_state((_di_), (_ctx_)))
#define ccdigest_state_u32(_di_, _ctx_) ccdigest_u32(ccdigest_state((_di_), (_ctx_)))
#define ccdigest_state_u64(_di_, _ctx_) ccdigest_u64(ccdigest_state((_di_), (_ctx_)))
#define ccdigest_state_ccn(_di_, _ctx_) ccdigest_ccn(ccdigest_state((_di_), (_ctx_)))
#define ccdigest_nbits(_di_, _ctx_) (((uint64_t *)(&((ccdigest_ctx_t)(_ctx_))->state.u8))[0])
#define ccdigest_data(_di_, _ctx_) (&((ccdigest_ctx_t)(_ctx_))->state.u8 + (_di_)->state_size + sizeof(uint64_t))
#define ccdigest_num(_di_, _ctx_) (((unsigned int *)(&((ccdigest_ctx_t)(_ctx_))->state.u8 + (_di_)->state_size + sizeof(uint64_t) + (_di_)->block_size))[0])
/* Digest state field accessors. Consider the implementation private. */
#define ccdigest_u8(_state_) (&((ccdigest_state_t)(_state_))->state.u8)
#define ccdigest_u32(_state_) (&((ccdigest_state_t)(_state_))->state.u32)
#define ccdigest_u64(_state_) (&((ccdigest_state_t)(_state_))->state.u64)
#define ccdigest_ccn(_state_) (&((ccdigest_state_t)(_state_))->state.ccn)
void ccdigest_init(const struct ccdigest_info *di, ccdigest_ctx_t ctx);
void ccdigest_update(const struct ccdigest_info *di, ccdigest_ctx_t ctx,
size_t len, const void *data);
CC_INLINE
void ccdigest_final(const struct ccdigest_info *di, ccdigest_ctx_t ctx, unsigned char *digest)
{
di->final(di,ctx,digest);
}
void ccdigest(const struct ccdigest_info *di, size_t len,
const void *data, void *digest);
#define OID_DEF(_VALUE_) ((const unsigned char *)_VALUE_)
#define CC_DIGEST_OID_MD2 OID_DEF("\x06\x08\x2A\x86\x48\x86\xF7\x0D\x02\x02")
#define CC_DIGEST_OID_MD4 OID_DEF("\x06\x08\x2A\x86\x48\x86\xF7\x0D\x02\x04")
#define CC_DIGEST_OID_MD5 OID_DEF("\x06\x08\x2A\x86\x48\x86\xF7\x0D\x02\x05")
#define CC_DIGEST_OID_SHA1 OID_DEF("\x06\x05\x2b\x0e\x03\x02\x1a")
#define CC_DIGEST_OID_SHA224 OID_DEF("\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04")
#define CC_DIGEST_OID_SHA256 OID_DEF("\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01")
#define CC_DIGEST_OID_SHA384 OID_DEF("\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02")
#define CC_DIGEST_OID_SHA512 OID_DEF("\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03")
#define CC_DIGEST_OID_SHA512_256 OID_DEF("\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06")
#define CC_DIGEST_OID_RMD160 OID_DEF("\x06\x05\x2B\x24\x03\x02\x01")
#endif /* _CORECRYPTO_CCDIGEST_H_ */

View File

@ -0,0 +1,33 @@
/* Copyright (c) (2010,2011,2012,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCDIGEST_PRIV_H_
#define _CORECRYPTO_CCDIGEST_PRIV_H_
#include <corecrypto/cc_priv.h>
#include <corecrypto/ccdigest.h>
#include <corecrypto/ccasn1.h>
CC_INLINE CC_NONNULL((1))
bool ccdigest_oid_equal(const struct ccdigest_info *di, ccoid_t oid) {
if(di->oid == NULL && CCOID(oid) == NULL) return true;
if(di->oid == NULL || CCOID(oid) == NULL) return false;
return ccoid_equal(di->oid, oid);
}
typedef const struct ccdigest_info *(ccdigest_lookup)(ccoid_t oid);
#include <stdarg.h>
const struct ccdigest_info *ccdigest_oid_lookup(ccoid_t oid, ...);
#define ccdigest_copy_state(_di_, _dst_, _src_) cc_memcpy_nochk(_dst_, _src_, (_di_)->state_size)
#endif /* _CORECRYPTO_CCDIGEST_PRIV_H_ */

View File

@ -0,0 +1,111 @@
/* Copyright (c) (2010,2011,2012,2014,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
/*!
@header corecrypto/ccdrbg.h
@abstract The functions provided in ccdrbg.h implement high-level accessors
to cryptographically secure random numbers.
*/
#ifndef _CORECRYPTO_CCDRBG_H_
#define _CORECRYPTO_CCDRBG_H_
#include <corecrypto/cc.h>
#include <corecrypto/ccdrbg_impl.h>
/*
* The maximum length of the entropy_input, additional_input (max_additional_input_length) , personalization string
* (max_personalization_string_length) and max_number_of_bits_per_request are implementation dependent
* but shall fit in a 32 bit register and be be less than or equal to the specified maximum length for the
* selected DRBG mechanism (NIST 800-90A Section 10).
*/
#define CCDRBG_MAX_ENTROPY_SIZE ((uint32_t)1<<16)
#define CCDRBG_MAX_ADDITIONALINPUT_SIZE ((uint32_t)1<<16)
#define CCDRBG_MAX_PSINPUT_SIZE ((uint32_t)1<<16)
#define CCDRBG_MAX_REQUEST_SIZE ((uint32_t)1<<16) //this is the absolute maximum in NIST 800-90A
#define CCDRBG_RESEED_INTERVAL ((uint64_t)1<<48) // must be able to fit the NIST maximum of 2^48
/*
* The entropyLength is forced to be greater or equal than the security strength.
* Nonce is not forced. It either needs to have 0.5*security strength entropy. Or, a vale that is repeated
* less than a 0.5*security strength bit random string.
* see below or NIST 800-90A for the definition of security strength
*/
CC_INLINE int ccdrbg_init(const struct ccdrbg_info *info,
struct ccdrbg_state *drbg,
size_t entropyLength, const void* entropy,
size_t nonceLength, const void* nonce,
size_t psLength, const void* ps)
{
return info->init(info, drbg, entropyLength, entropy, nonceLength, nonce, psLength, ps);
}
/*
* The entropyLength is forced to be greater or equal than the security strength.
*/
CC_INLINE int ccdrbg_reseed(const struct ccdrbg_info *info,
struct ccdrbg_state *drbg,
size_t entropyLength, const void *entropy,
size_t additionalLength, const void *additional)
{
return info->reseed(drbg, entropyLength, entropy, additionalLength, additional);
}
CC_INLINE int ccdrbg_generate(const struct ccdrbg_info *info,
struct ccdrbg_state *drbg,
size_t dataOutLength, void *dataOut,
size_t additionalLength, const void *additional)
{
return info->generate(drbg, dataOutLength, dataOut, additionalLength, additional);
}
CC_INLINE void ccdrbg_done(const struct ccdrbg_info *info,
struct ccdrbg_state *drbg)
{
info->done(drbg);
}
CC_INLINE size_t ccdrbg_context_size(const struct ccdrbg_info *info)
{
return info->size;
}
/*
* NIST SP 800-90 CTR_DRBG
* the maximum security strengh of drbg equals to the block size of the corresponding ECB.
*/
struct ccdrbg_nistctr_custom {
const struct ccmode_ctr *ctr_info;
size_t keylen;
int strictFIPS;
int use_df;
};
void ccdrbg_factory_nistctr(struct ccdrbg_info *info, const struct ccdrbg_nistctr_custom *custom);
/*
* NIST SP 800-90 HMAC_DRBG
* the maximum security strengh of drbg is half of output size of the input hash function and it internally is limited to 256 bits
*/
struct ccdrbg_nisthmac_custom {
const struct ccdigest_info *di;
int strictFIPS;
};
void ccdrbg_factory_nisthmac(struct ccdrbg_info *info, const struct ccdrbg_nisthmac_custom *custom);
#endif /* _CORECRYPTO_CCDRBG_H_ */

View File

@ -0,0 +1,70 @@
/* Copyright (c) (2012,2015,2016,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCDRBG_IMPL_H_
#define _CORECRYPTO_CCDRBG_IMPL_H_
/* opaque drbg structure */
struct ccdrbg_state;
struct ccdrbg_info {
/*! Size of the DRBG state in bytes **/
size_t size;
/*! Instantiate the PRNG
@param prng The PRNG state
@param entropylen Length of entropy
@param entropy Entropy bytes
@param inlen Length of additional input
@param in Additional input bytes
@return 0 if successful
*/
int (*CC_SPTR(ccdrbg_info, init))(const struct ccdrbg_info *info, struct ccdrbg_state *drbg,
size_t entropyLength, const void* entropy,
size_t nonceLength, const void* nonce,
size_t psLength, const void* ps);
/*! Add entropy to the PRNG
@param prng The PRNG state
@param entropylen Length of entropy
@param entropy Entropy bytes
@param inlen Length of additional input
@param in Additional input bytes
@return 0 if successful
*/
int (*CC_SPTR(ccdrbg_info, reseed))(struct ccdrbg_state *prng,
size_t entropylen, const void *entropy,
size_t inlen, const void *in);
/*! Read from the PRNG in a FIPS Testing compliant manor
@param prng The PRNG state to read from
@param out [out] Where to store the data
@param outlen Length of data desired (octets)
@param inlen Length of additional input
@param in Additional input bytes
@return 0 if successfull
*/
int (*CC_SPTR(ccdrbg_info, generate))(struct ccdrbg_state *prng,
size_t outlen, void *out,
size_t inlen, const void *in);
/*! Terminate a PRNG state
@param prng The PRNG state to terminate
*/
void (*CC_SPTR(ccdrbg_info, done))(struct ccdrbg_state *prng);
/** private parameters */
const void *custom;
};
#endif // _CORECRYPTO_CCDRBG_IMPL_H_

View File

@ -0,0 +1,67 @@
/* Copyright (c) (2010,2011,2012,2014,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCHMAC_H_
#define _CORECRYPTO_CCHMAC_H_
#include <corecrypto/cc.h>
#include <corecrypto/ccdigest.h>
/* An hmac_ctx_t is normally allocated as an array of these. */
struct cchmac_ctx {
uint8_t b[1];
} CC_ALIGNED(8);
typedef struct cchmac_ctx* cchmac_ctx_t;
#define cchmac_ctx_size(STATE_SIZE, BLOCK_SIZE) (cc_pad_align(ccdigest_ctx_size(STATE_SIZE, BLOCK_SIZE)) + (STATE_SIZE))
#define cchmac_di_size(_di_) (cchmac_ctx_size((_di_)->state_size, (_di_)->block_size))
#define cchmac_ctx_n(STATE_SIZE, BLOCK_SIZE) ccn_nof_size(cchmac_ctx_size((STATE_SIZE), (BLOCK_SIZE)))
#define cchmac_ctx_decl(STATE_SIZE, BLOCK_SIZE, _name_) cc_ctx_decl(struct cchmac_ctx, cchmac_ctx_size(STATE_SIZE, BLOCK_SIZE), _name_)
#define cchmac_ctx_clear(STATE_SIZE, BLOCK_SIZE, _name_) cc_clear(cchmac_ctx_size(STATE_SIZE, BLOCK_SIZE), _name_)
#define cchmac_di_decl(_di_, _name_) cchmac_ctx_decl((_di_)->state_size, (_di_)->block_size, _name_)
#define cchmac_di_clear(_di_, _name_) cchmac_ctx_clear((_di_)->state_size, (_di_)->block_size, _name_)
/* Return a ccdigest_ctx_t which can be accesed with the macros in ccdigest.h */
#define cchmac_digest_ctx(_di_, HC) ((ccdigest_ctx_t)(HC))
/* Accesors for ostate fields, this is all cchmac_ctx_t adds to the ccdigest_ctx_t. */
#define cchmac_ostate(_di_, HC) ((struct ccdigest_state *)(((cchmac_ctx_t)(HC))->b + cc_pad_align(ccdigest_di_size(_di_))))
#define cchmac_ostate8(_di_, HC) (ccdigest_u8(cchmac_ostate(_di_, HC)))
#define cchmac_ostate32(_di_, HC) (ccdigest_u32(cchmac_ostate(_di_, HC)))
#define cchmac_ostate64(_di_, HC) (ccdigest_u64(cchmac_ostate(_di_, HC)))
#define cchmac_ostateccn(_di_, HC) (ccdigest_ccn(cchmac_ostate(_di_, HC)))
/* Convenience accessors for ccdigest_ctx_t fields. */
#define cchmac_istate(_di_, HC) ccdigest_state(_di_, ((ccdigest_ctx_t)(HC)))
#define cchmac_istate8(_di_, HC) ccdigest_u8(cchmac_istate(_di_, HC))
#define cchmac_istate32(_di_, HC) ccdigest_u32(cchmac_istate(_di_, HC))
#define cchmac_istate64(_di_, HC) ccdigest_u64(cchmac_istate(_di_, HC))
#define cchmac_istateccn(_di_, HC) ccdigest_ccn(cchmac_istate(_di_, HC))
#define cchmac_data(_di_, HC) ccdigest_data(_di_, ((ccdigest_ctx_t)(HC)))
#define cchmac_num(_di_, HC) ccdigest_num(_di_, ((ccdigest_ctx_t)(HC)))
#define cchmac_nbits(_di_, HC) ccdigest_nbits(_di_, ((ccdigest_ctx_t)(HC)))
void cchmac_init(const struct ccdigest_info *di, cchmac_ctx_t ctx,
size_t key_len, const void *key);
void cchmac_update(const struct ccdigest_info *di, cchmac_ctx_t ctx,
size_t data_len, const void *data);
void cchmac_final(const struct ccdigest_info *di, cchmac_ctx_t ctx,
unsigned char *mac);
void cchmac(const struct ccdigest_info *di, size_t key_len,
const void *key, size_t data_len, const void *data,
unsigned char *mac);
#endif /* _CORECRYPTO_CCHMAC_H_ */

View File

@ -0,0 +1,398 @@
/* Copyright (c) (2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCKPRNG_H_
#define _CORECRYPTO_CCKPRNG_H_
#include <stdbool.h>
#include <corecrypto/cc.h>
// This is a Fortuna-inspired PRNG. While it differs from Fortuna in
// many minor details, the biggest difference is its support for
// multiple independent output generators. This is to make it suitable
// for use in concurrent environments.
//
// This PRNG targets a 256-bit security level.
//
// First, the user should call cckprng_init. The user must specify the
// maximum number of output generators that might be
// needed. (Typically, users should align this argument with the
// number of available CPUs.)
//
// The user must also provide a read-only handle to an entropy
// source. This is a fixed-size buffer that will receive entropy
// updates out of band from the PRNG (e.g. in an interrupt
// handler). The PRNG will consume entropy from this buffer according
// to an internal schedule driven by calls to cckprng_refresh (see
// below).
//
// The user should call cckprng_initgen for as many output generators
// as are needed. The numeric argument is an identifier to be reused
// during calls to cckprng_generate (see below) and must be less than
// the maximum number of generators specified to cckprng_init.
//
// After initialization, the user is free to call cckprng_generate to
// generate random bytes. The user must specify the generator in this
// call using a numeric identifier passed in the call to
// cckprng_initgen.
//
// Output generation is limited to 256 bytes per request. Users should
// make multiple requests if more output is needed.
//
// The user is expected to call cckprng_refresh regularly. This
// function consumes entropy and mixes it into the output generators
// according to an internal schedule.
//
// This implementation is thread-safe. Internally, a set of mutexes
// guard access to internal state. Most functions rely on a single
// mutex to protect shared state. The main exception is the
// cckprng_generate function, which uses a per-generator mutex to
// allow concurrent output generation on different threads.
//
// Another important exception is cckprng_refresh. While this function
// relies on the shared mutex, it returns immediately if it cannot
// acquire it.
//
// The PRNG also supports user-initiated reseeds. This is to support a
// user-writable random device.
//
// This PRNG supports reseeds concurrent with output generation,
// i.e. it is safe to call cckprng_reseed or cckprng_refresh while
// another thread is calling cckprng_generate.
#define CCKPRNG_NPOOLS 32
#define CCKPRNG_SEED_NBYTES 32
#define CCKPRNG_POOL_NBYTES 32
#define CCKPRNG_KEY_NBYTES 32
struct cckprng_gen_diag {
// The number of times this generator has been rekeyed from the master seed
uint64_t nrekeys;
// The number of requests this generator has fulfilled
uint64_t out_nreqs;
// The total number of bytes this generator has generated over all requests
uint64_t out_nbytes;
// The maximum number of bytes this generator has generated in any one request
uint64_t out_nbytes_req_max;
// The total number of bytes this generator has generated since the last rekey
uint64_t out_nbytes_key;
// The maximum total number of bytes this generator has generated between two rekeys
uint64_t out_nbytes_key_max;
};
struct cckprng_pool_diag {
// The number of samples currently resident in the pool
uint64_t nsamples;
// The number of times this pool has been drained in a reseed
uint64_t ndrains;
// The maximum number of samples this pool has held at any one time
uint64_t nsamples_max;
};
struct cckprng_diag {
// The number of reseeds via user input (e.g. by writing to /dev/random)
uint64_t userreseed_nreseeds;
// The number of reseeds via the scheduler
uint64_t schedreseed_nreseeds;
// The maximum number of samples included in any one scheduler reseed
uint64_t schedreseed_nsamples_max;
// The maximum number of samples included in any one entropy input
uint64_t addentropy_nsamples_max;
// Diagnostics corresponding to individual output generators
unsigned ngens;
CC_ALIGNED(8) struct cckprng_gen_diag *gens;
// Diagnostics corresponding to internal entropy pools
struct cckprng_pool_diag pools[CCKPRNG_NPOOLS];
};
#if CC_KERNEL
#include <kern/locks.h>
typedef lck_grp_t *cckprng_lock_group;
typedef lck_mtx_t *cckprng_lock_mutex;
struct cckprng_lock_ctx {
cckprng_lock_group group;
cckprng_lock_mutex mutex;
};
#elif CC_ANDROID || CC_LINUX
#include <pthread.h>
typedef pthread_mutex_t cckprng_lock_mutex;
struct cckprng_lock_ctx {
cckprng_lock_mutex mutex;
};
#else
#include <os/lock.h>
typedef os_unfair_lock cckprng_lock_mutex;
struct cckprng_lock_ctx {
cckprng_lock_mutex mutex;
};
#endif
struct cckprng_key_ctx {
uint8_t data[CCKPRNG_KEY_NBYTES];
};
struct cckprng_gen_ctx {
// We maintain two keys (one live and one idle) to allow
// concurrent generation and reseeding
struct cckprng_key_ctx keys[2];
_Atomic unsigned swap;
unsigned key_live_idx;
unsigned key_idle_idx;
// A counter used in CTR mode
uint8_t ctr[16];
// Whether the generator has been initialized
bool init;
// A mutex governing this generator's state (but note the idle key
// context is under control of the PRNG's shared mutex)
struct {
cckprng_lock_mutex mutex;
} lock;
};
struct cckprng_pool_ctx {
uint8_t data[CCKPRNG_POOL_NBYTES];
};
// This is a handle to an "entropy buffer" to be managed externally
// (i.e. in xnu). This is a non-cryptographic
// accumulator. Practically, the buffer is filled with timestamps
// collected during interrupts. The existing state of the buffer is
// rotated and new timestamps are added in. A counter of raw timing
// samples is also managed externally. The buffer and the counter are
// both subject to data races, which we tolerate.
struct cckprng_entropybuf {
// A read-only handle to an "entropy buffer" (a non-cryptographic accumulator) to be managed externally
const void *buf;
// The size of the entropy buffer
size_t nbytes;
// A read-only handle to a count of raw samples in the buffer
const uint32_t *nsamples;
// The count of raw samples in the buffer at time of last read
uint32_t nsamples_last;
};
struct cckprng_sched_ctx {
// A counter governing the set of entropy pools to drain
uint64_t reseed_sched;
// An index used to add entropy to pools in a round-robin style
unsigned pool_idx;
};
// A function pointer to fill an entropy buffer. It should return some
// estimate of entropy (e.g. the number of timing samples resident in
// the buffer). The implementation may return zero if no entropy is
// available. The implementation should return negative in case of an
// error (e.g. a failure in continuous health tests).
//
// The caller should set entropy_nbytes to the maximum size of the
// input buffer, and the implementation should set it to the number of
// bytes it has initialized. The third argument is arbitrary state the
// implementation provides and receives back on each call.
typedef int32_t (*cckprng_getentropy)(size_t *entropy_nbytes,
void *entropy,
void *arg);
struct cckprng_ctx {
// The master secret of the PRNG
struct cckprng_key_ctx key;
// A counter used in CTR mode (with the master secret)
uint8_t ctr[16];
// State used to schedule entropy consumption and reseeds
struct cckprng_sched_ctx sched;
// A mutex governing access to shared state
struct cckprng_lock_ctx lock;
// The maximum number of generators that may be allocated
unsigned max_ngens;
// The actual number of generators that have been initialized
unsigned ngens;
// An array of output generators (allocated dynamically) of length max_ngens
struct cckprng_gen_ctx *gens;
// A set of entropy pools
struct cckprng_pool_ctx pools[CCKPRNG_NPOOLS];
// A handle to an entropy source managed externally
struct cckprng_entropybuf entropybuf;
// Diagnostics for the PRNG
struct cckprng_diag diag;
// A function pointer to get entropy
cckprng_getentropy getentropy;
// An arbitrary piece of state to be provided to the entropy function
void *getentropy_arg;
};
// This collection of function pointers is just a convenience for
// registering the PRNG with xnu
struct cckprng_funcs {
void (*CC_SPTR(cckprng_funcs, init))(struct cckprng_ctx *ctx,
unsigned max_ngens,
size_t entropybuf_nbytes,
const void *entropybuf,
const uint32_t *entropybuf_nsamples,
size_t seed_nbytes,
const void *seed,
size_t nonce_nbytes,
const void *nonce);
void (*CC_SPTR(cckprng_funcs, initgen))(struct cckprng_ctx *ctx, unsigned gen_idx);
void (*CC_SPTR(cckprng_funcs, reseed))(struct cckprng_ctx *ctx, size_t nbytes, const void *seed);
void (*CC_SPTR(cckprng_funcs, refresh))(struct cckprng_ctx *ctx);
void (*CC_SPTR(cckprng_funcs, generate))(struct cckprng_ctx *ctx, unsigned gen_idx, size_t nbytes, void *out);
void (*CC_SPTR(cckprng_funcs, init_with_getentropy))(struct cckprng_ctx *ctx,
unsigned max_ngens,
size_t seed_nbytes,
const void *seed,
size_t nonce_nbytes,
const void *nonce,
cckprng_getentropy getentropy,
void *getentropy_arg);
};
/*
@function cckprng_init
@abstract Initialize a kernel PRNG context.
@param ctx Context for this instance
@param max_ngens Maximum count of generators that may be allocated
@param entropybuf_nbytes Length of the entropy buffer in bytes
@param entropybuf Read-only pointer to a long-lived entropy buffer
@param entropybuf_nsamples Read-only pointer to a counter of samples in the entropy buffer
@param seed_nbytes Length of the seed in bytes
@param seed Pointer to a high-entropy seed
@param nonce_nbytes Length of the nonce in bytes
@discussion @p max_ngens should be set based on an upper bound of CPUs available on the device. The entropy buffer should be managed outside the PRNG and updated continuously (e.g. by an interrupt handler). The count of samples in the entropy buffer needn't be better than a rough estimate.
*/
void cckprng_init(struct cckprng_ctx *ctx,
unsigned max_ngens,
size_t entropybuf_nbytes,
const void *entropybuf,
const uint32_t *entropybuf_nsamples,
size_t seed_nbytes,
const void *seed,
size_t nonce_nbytes,
const void *nonce);
/*
@function cckprng_init_with_getentropy
@abstract Initialize a kernel PRNG context.
@param ctx Context for this instance
@param max_ngens Maximum count of generators that may be allocated
@param seed_nbytes Length of the seed in bytes
@param seed Pointer to a high-entropy seed
@param nonce_nbytes Length of the nonce in bytes
@param seed Pointer to a single-use nonce
@param getentropy A function pointer to fill an entropy buffer
@param getentropy_arg State provided to the entropy function
@discussion @p max_ngens should be set based on an upper bound of CPUs available on the device. See the @p cckprng_getentropy type definition for discussion on its semantics.
*/
void cckprng_init_with_getentropy(struct cckprng_ctx *ctx,
unsigned max_ngens,
size_t seed_nbytes,
const void *seed,
size_t nonce_nbytes,
const void *nonce,
cckprng_getentropy getentropy,
void *getentropy_arg);
/*
@function cckprng_initgen
@abstract Initialize an output generator.
@param ctx Context for this instance
@param gen_idx Index of the generator
@discussion @p gen_idx must be less than @p max_ngens provided to @cckprng_init and must be unique within the lifetime of a PRNG context. This function will abort if these contracts are violated.
*/
void cckprng_initgen(struct cckprng_ctx *ctx, unsigned gen_idx);
/*
@function cckprng_reseed
@abstract Reseed a kernel PRNG context with a user-supplied seed.
@param ctx Context for this instance
@param nbytes Length of the seed in bytes
@param seed Pointer to a high-entropy seed
@discussion It is safe to expose this function to attacker-controlled requests (e.g. writes to /dev/random).
*/
void cckprng_reseed(struct cckprng_ctx *ctx, size_t nbytes, const void *seed);
/*
@function cckprng_refresh
@abstract Consume entropy and reseed according to an internal schedule.
@param ctx Context for this instance
@discussion This function should be called on a regular basis. (For example, it is reasonable to call this inline before a call to @p cckprng_generate.) This function will not necessarily consume entropy or reseed the internal state on any given invocation. To force an immediate reseed, call @p cckprng_reseed.
*/
void cckprng_refresh(struct cckprng_ctx *ctx);
#define CCKPRNG_GENERATE_MAX_NBYTES 256
/*
@function cckprng_generate
@abstract Generate random values for use in applications.
@param ctx Context for this instance
@param gen_idx Index of the output generator
@param nbytes Length of the desired output in bytes
@param out Pointer to the output buffer
@discussion @p gen_idx must be a previous argument to @p cckprng_initgen. @p nbytes must be less than or equal to @p CCKPRNG_GENERATE_MAX_NBYTES. (Callers may invoke this function in a loop to generate larger outputs.) This function will abort if these contracts are violated.
*/
void cckprng_generate(struct cckprng_ctx *ctx, unsigned gen_idx, size_t nbytes, void *out);
#endif /* _CORECRYPTO_CCKPRNG_H_ */

View File

@ -0,0 +1,26 @@
/* Copyright (c) (2010,2015,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCMD4_H_
#define _CORECRYPTO_CCMD4_H_
#include <corecrypto/ccdigest.h>
#define CCMD4_BLOCK_SIZE 64
#define CCMD4_OUTPUT_SIZE 16
#define CCMD4_STATE_SIZE 16
extern const struct ccdigest_info ccmd4_ltc_di;
/* default is libtomcrypt */
#define ccmd4_di ccmd4_ltc_di
#endif /* _CORECRYPTO_CCMD4_H_ */

View File

@ -0,0 +1,925 @@
/* Copyright (c) (2010,2011,2012,2014,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCMODE_H_
#define _CORECRYPTO_CCMODE_H_
#include <corecrypto/cc.h>
#include <corecrypto/ccmode_impl.h>
#include <corecrypto/ccmode_siv.h>
#include <corecrypto/ccmode_siv_hmac.h>
/* ECB mode. */
/* Declare a ecb key named _name_. Pass the size field of a struct ccmode_ecb
for _size_. */
#define ccecb_ctx_decl(_size_, _name_) cc_ctx_decl(ccecb_ctx, _size_, _name_)
#define ccecb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
CC_INLINE size_t ccecb_context_size(const struct ccmode_ecb *mode)
{
return mode->size;
}
CC_INLINE size_t ccecb_block_size(const struct ccmode_ecb *mode)
{
return mode->block_size;
}
CC_INLINE int ccecb_init(const struct ccmode_ecb *mode, ccecb_ctx *ctx, size_t key_len, const void *key)
{
return mode->init(mode, ctx, key_len, key);
}
CC_INLINE int ccecb_update(const struct ccmode_ecb *mode, const ccecb_ctx *ctx, size_t nblocks, const void *in, void *out)
{
return mode->ecb(ctx, nblocks, in, out);
}
CC_INLINE int
ccecb_one_shot(const struct ccmode_ecb *mode, size_t key_len, const void *key, size_t nblocks, const void *in, void *out)
{
int rc;
ccecb_ctx_decl(mode->size, ctx);
rc = mode->init(mode, ctx, key_len, key);
if (rc == 0) {
rc = mode->ecb(ctx, nblocks, in, out);
}
ccecb_ctx_clear(mode->size, ctx);
return rc;
}
/* CBC mode. */
#define __CC_HAS_FIX_FOR_11468135__ 1
/* Declare a cbc key named _name_. Pass the size field of a struct ccmode_cbc
for _size_. */
#define cccbc_ctx_decl(_size_, _name_) cc_ctx_decl(cccbc_ctx, _size_, _name_)
#define cccbc_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
/* Declare a cbc iv tweak named _name_. Pass the blocksize field of a
struct ccmode_cbc for _size_. */
#define cccbc_iv_decl(_size_, _name_) cc_ctx_decl(cccbc_iv, _size_, _name_)
#define cccbc_iv_clear(_size_, _name_) cc_clear(_size_, _name_)
/* Actual symmetric algorithm implementation can provide you one of these.
Alternatively you can create a ccmode_cbc instance from any ccmode_ecb
cipher. To do so, statically initialize a struct ccmode_cbc using the
CCMODE_FACTORY_CBC_DECRYPT or CCMODE_FACTORY_CBC_ENCRYPT macros.
Alternatively you can dynamically initialize a struct ccmode_cbc
ccmode_factory_cbc_decrypt() or ccmode_factory_cbc_encrypt(). */
CC_INLINE size_t cccbc_context_size(const struct ccmode_cbc *mode)
{
return mode->size;
}
CC_INLINE size_t cccbc_block_size(const struct ccmode_cbc *mode)
{
return mode->block_size;
}
CC_INLINE int cccbc_init(const struct ccmode_cbc *mode, cccbc_ctx *ctx, size_t key_len, const void *key)
{
return mode->init(mode, ctx, key_len, key);
}
CC_INLINE int cccbc_set_iv(const struct ccmode_cbc *mode, cccbc_iv *iv_ctx, const void *iv)
{
if (iv) {
cc_copy(mode->block_size, iv_ctx, iv);
} else {
cc_clear(mode->block_size, iv_ctx);
}
return 0;
}
CC_INLINE int cccbc_update(const struct ccmode_cbc *mode, cccbc_ctx *ctx, cccbc_iv *iv, size_t nblocks, const void *in, void *out)
{
return mode->cbc(ctx, iv, nblocks, in, out);
}
int cccbc_one_shot(const struct ccmode_cbc *mode,
size_t key_len,
const void *key,
const void *iv,
size_t nblocks,
const void *in,
void *out);
/* CFB mode. */
/* Declare a cfb key named _name_. Pass the size field of a struct ccmode_cfb
for _size_. */
#define cccfb_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb_ctx, _size_, _name_)
#define cccfb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
CC_INLINE size_t cccfb_context_size(const struct ccmode_cfb *mode)
{
return mode->size;
}
CC_INLINE size_t cccfb_block_size(const struct ccmode_cfb *mode)
{
return mode->block_size;
}
CC_INLINE int cccfb_init(const struct ccmode_cfb *mode, cccfb_ctx *ctx, size_t key_len, const void *key, const void *iv)
{
return mode->init(mode, ctx, key_len, key, iv);
}
CC_INLINE int cccfb_update(const struct ccmode_cfb *mode, cccfb_ctx *ctx, size_t nbytes, const void *in, void *out)
{
return mode->cfb(ctx, nbytes, in, out);
}
CC_INLINE int cccfb_one_shot(const struct ccmode_cfb *mode,
size_t key_len,
const void *key,
const void *iv,
size_t nbytes,
const void *in,
void *out)
{
int rc;
cccfb_ctx_decl(mode->size, ctx);
rc = mode->init(mode, ctx, key_len, key, iv);
if (rc == 0) {
rc = mode->cfb(ctx, nbytes, in, out);
}
cccfb_ctx_clear(mode->size, ctx);
return rc;
}
/* CFB8 mode. */
/* Declare a cfb8 key named _name_. Pass the size field of a struct ccmode_cfb8
for _size_. */
#define cccfb8_ctx_decl(_size_, _name_) cc_ctx_decl(cccfb8_ctx, _size_, _name_)
#define cccfb8_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
CC_INLINE size_t cccfb8_context_size(const struct ccmode_cfb8 *mode)
{
return mode->size;
}
CC_INLINE size_t cccfb8_block_size(const struct ccmode_cfb8 *mode)
{
return mode->block_size;
}
CC_INLINE int cccfb8_init(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx, size_t key_len, const void *key, const void *iv)
{
return mode->init(mode, ctx, key_len, key, iv);
}
CC_INLINE int cccfb8_update(const struct ccmode_cfb8 *mode, cccfb8_ctx *ctx, size_t nbytes, const void *in, void *out)
{
return mode->cfb8(ctx, nbytes, in, out);
}
CC_INLINE int cccfb8_one_shot(const struct ccmode_cfb8 *mode,
size_t key_len,
const void *key,
const void *iv,
size_t nbytes,
const void *in,
void *out)
{
int rc;
cccfb8_ctx_decl(mode->size, ctx);
rc = mode->init(mode, ctx, key_len, key, iv);
if (rc == 0) {
rc = mode->cfb8(ctx, nbytes, in, out);
}
cccfb8_ctx_clear(mode->size, ctx);
return rc;
}
/* CTR mode. */
/* Declare a ctr key named _name_. Pass the size field of a struct ccmode_ctr
for _size_. */
#define ccctr_ctx_decl(_size_, _name_) cc_ctx_decl(ccctr_ctx, _size_, _name_)
#define ccctr_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
/* This is Integer Counter Mode: The IV is the initial value of the counter
that is incremented by 1 for each new block. Use the mode flags to select
if the IV/Counter is stored in big or little endian. */
CC_INLINE size_t ccctr_context_size(const struct ccmode_ctr *mode)
{
return mode->size;
}
CC_INLINE size_t ccctr_block_size(const struct ccmode_ctr *mode)
{
return mode->block_size;
}
CC_INLINE int ccctr_init(const struct ccmode_ctr *mode, ccctr_ctx *ctx, size_t key_len, const void *key, const void *iv)
{
return mode->init(mode, ctx, key_len, key, iv);
}
CC_INLINE int ccctr_update(const struct ccmode_ctr *mode, ccctr_ctx *ctx, size_t nbytes, const void *in, void *out)
{
return mode->ctr(ctx, nbytes, in, out);
}
CC_INLINE int ccctr_one_shot(const struct ccmode_ctr *mode,
size_t key_len,
const void *key,
const void *iv,
size_t nbytes,
const void *in,
void *out)
{
int rc;
ccctr_ctx_decl(mode->size, ctx);
rc = mode->init(mode, ctx, key_len, key, iv);
if (rc == 0) {
rc = mode->ctr(ctx, nbytes, in, out);
}
ccctr_ctx_clear(mode->size, ctx);
return rc;
}
/* OFB mode. */
/* Declare a ofb key named _name_. Pass the size field of a struct ccmode_ofb
for _size_. */
#define ccofb_ctx_decl(_size_, _name_) cc_ctx_decl(ccofb_ctx, _size_, _name_)
#define ccofb_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
CC_INLINE size_t ccofb_context_size(const struct ccmode_ofb *mode)
{
return mode->size;
}
CC_INLINE size_t ccofb_block_size(const struct ccmode_ofb *mode)
{
return mode->block_size;
}
CC_INLINE int ccofb_init(const struct ccmode_ofb *mode, ccofb_ctx *ctx, size_t key_len, const void *key, const void *iv)
{
return mode->init(mode, ctx, key_len, key, iv);
}
CC_INLINE int ccofb_update(const struct ccmode_ofb *mode, ccofb_ctx *ctx, size_t nbytes, const void *in, void *out)
{
return mode->ofb(ctx, nbytes, in, out);
}
CC_INLINE int ccofb_one_shot(const struct ccmode_ofb *mode,
size_t key_len,
const void *key,
const void *iv,
size_t nbytes,
const void *in,
void *out)
{
int rc;
ccofb_ctx_decl(mode->size, ctx);
rc = mode->init(mode, ctx, key_len, key, iv);
if (rc == 0) {
rc = mode->ofb(ctx, nbytes, in, out);
}
ccofb_ctx_clear(mode->size, ctx);
return rc;
}
/* XTS mode. */
/* Declare a xts key named _name_. Pass the size field of a struct ccmode_xts
for _size_. */
#define ccxts_ctx_decl(_size_, _name_) cc_ctx_decl(ccxts_ctx, _size_, _name_)
#define ccxts_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
/* Declare a xts tweak named _name_. Pass the tweak_size field of a
struct ccmode_xts for _size_. */
#define ccxts_tweak_decl(_size_, _name_) cc_ctx_decl(ccxts_tweak, _size_, _name_)
#define ccxts_tweak_clear(_size_, _name_) cc_clear(_size_, _name_)
/* Actual symmetric algorithm implementation can provide you one of these.
Alternatively you can create a ccmode_xts instance from any ccmode_ecb
cipher. To do so, statically initialize a struct ccmode_xts using the
CCMODE_FACTORY_XTS_DECRYPT or CCMODE_FACTORY_XTS_ENCRYPT macros. Alternatively
you can dynamically initialize a struct ccmode_xts
ccmode_factory_xts_decrypt() or ccmode_factory_xts_encrypt(). */
/* NOTE that xts mode does not do cts padding. It's really an xex mode.
If you need cts padding use the ccpad_xts_encrypt and ccpad_xts_decrypt
functions. Also note that xts only works for ecb modes with a block_size
of 16. */
CC_INLINE size_t ccxts_context_size(const struct ccmode_xts *mode)
{
return mode->size;
}
CC_INLINE size_t ccxts_block_size(const struct ccmode_xts *mode)
{
return mode->block_size;
}
/*!
@function ccxts_init
@abstract Initialize an XTS context.
@param mode Descriptor for the mode
@param ctx Context for this instance
@param key_nbytes Length of the key arguments in bytes
@param data_key Key for data encryption
@param tweak_key Key for tweak generation
@result 0 iff successful.
@discussion For security reasons, the two keys must be different.
*/
CC_INLINE int
ccxts_init(const struct ccmode_xts *mode, ccxts_ctx *ctx, size_t key_nbytes, const void *data_key, const void *tweak_key)
{
return mode->init(mode, ctx, key_nbytes, data_key, tweak_key);
}
/*!
@function ccxts_set_tweak
@abstract Initialize the tweak for a sector.
@param mode Descriptor for the mode
@param ctx Context for this instance
@param tweak Context for the tweak for this sector
@param iv Data used to generate the tweak
@discussion The IV must be exactly one block in length.
*/
CC_INLINE int ccxts_set_tweak(const struct ccmode_xts *mode, ccxts_ctx *ctx, ccxts_tweak *tweak, const void *iv)
{
return mode->set_tweak(ctx, tweak, iv);
}
/*!
@function ccxts_update
@abstract Encrypt or decrypt data.
@param mode Descriptor for the mode
@param ctx Context for an instance
@param tweak Context for the tweak for this sector
@param nblocks Length of the data in blocks
@param in Input data
@param out Output buffer
@result The updated internal buffer of the tweak context. May be ignored.
*/
CC_INLINE void *
ccxts_update(const struct ccmode_xts *mode, ccxts_ctx *ctx, ccxts_tweak *tweak, size_t nblocks, const void *in, void *out)
{
return mode->xts(ctx, tweak, nblocks, in, out);
}
/*!
@function ccxts_one_shot
@abstract Encrypt or decrypt data in XTS mode.
@param mode Descriptor for the mode
@param key_nbytes Length of the key arguments in bytes
@param data_key Key for data encryption
@param tweak_key Key for tweak generation
@param iv Data used to generate the tweak
@param nblocks Length of the data in blocks
@param in Input data
@param out Output buffer
@result 0 iff successful.
@discussion For security reasons, the two keys must be different.
*/
int ccxts_one_shot(const struct ccmode_xts *mode,
size_t key_nbytes,
const void *data_key,
const void *tweak_key,
const void *iv,
size_t nblocks,
const void *in,
void *out);
/* Authenticated cipher modes. */
/* GCM mode. */
/* Declare a gcm key named _name_. Pass the size field of a struct ccmode_gcm
for _size_. */
#define ccgcm_ctx_decl(_size_, _name_) cc_ctx_decl(ccgcm_ctx, _size_, _name_)
#define ccgcm_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
#define CCGCM_IV_NBYTES 12
#define CCGCM_BLOCK_NBYTES 16
/* (2^32 - 2) blocks */
/* (2^36 - 32) bytes */
/* (2^39 - 256) bits */
/* Exceeding this figure breaks confidentiality and authenticity. */
#define CCGCM_TEXT_MAX_NBYTES ((1ULL << 36) - 32ULL)
CC_INLINE size_t ccgcm_context_size(const struct ccmode_gcm *mode)
{
return mode->size;
}
CC_INLINE size_t ccgcm_block_size(const struct ccmode_gcm *mode)
{
return mode->block_size;
}
/*!
@function ccgcm_init
@abstract Initialize a GCM context.
@param mode Descriptor for the mode
@param ctx Context for this instance
@param key_nbytes Length of the key in bytes
@param key Key for the underlying blockcipher (AES)
@result 0 iff successful.
@discussion The correct sequence of calls is:
@code ccgcm_init(...)
ccgcm_set_iv(...)
ccgcm_aad(...) (may be called zero or more times)
ccgcm_update(...) (may be called zero or more times)
ccgcm_finalize(...)
To reuse the context for additional encryptions, follow this sequence:
@code ccgcm_reset(...)
ccgcm_set_iv(...)
ccgcm_aad(...) (may be called zero or more times)
ccgcm_update(...) (may be called zero or more times)
ccgcm_finalize(...)
@warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
@warning It is not permitted to call @p ccgcm_inc_iv after initializing the cipher via the @p ccgcm_init interface. Nonzero is
returned in the event of an improper call sequence.
@warning This function is not FIPS-compliant. Use @p ccgcm_init_with_iv instead.
*/
CC_INLINE int ccgcm_init(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t key_nbytes, const void *key)
{
return mode->init(mode, ctx, key_nbytes, key);
}
/*!
@function ccgcm_init_with_iv
@abstract Initialize a GCM context to manage IVs internally.
@param mode Descriptor for the mode
@param ctx Context for this instance
@param key_nbytes Length of the key in bytes
@param key Key for the underlying blockcipher (AES)
@param iv IV for the first encryption
@result 0 iff successful.
@discussion The correct sequence of calls is:
@code ccgcm_init_with_iv(...)
ccgcm_aad(...) (may be called zero or more times)
ccgcm_update(...) (may be called zero or more times)
ccgcm_finalize(...)
To reuse the context for additional encryptions, follow this sequence:
@code ccgcm_reset(...)
ccgcm_inc_iv(...)
ccgcm_aad(...) (may be called zero or more times)
ccgcm_update(...) (may be called zero or more times)
ccgcm_finalize(...)
The IV must be exactly 12 bytes in length.
Internally, the IV is treated as a four-byte salt followed by an eight-byte counter. This is to match the behavior of certain
protocols (e.g. TLS). In the call to @p ccgcm_inc_iv, the counter component will be interpreted as a big-endian, unsigned value
and incremented in place.
@warning It is not permitted to call @p ccgcm_set_iv after initializing the cipher via the @p ccgcm_init_with_iv interface.
Nonzero is returned in the event of an improper call sequence.
@warning The security of GCM depends on the uniqueness of key-IV pairs. To avoid key-IV repetition, callers should not initialize
multiple contexts with the same key material via the @p ccgcm_init_with_iv interface.
*/
int ccgcm_init_with_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t key_nbytes, const void *key, const void *iv);
/*!
@function ccgcm_set_iv
@abstract Set the IV for encryption.
@param mode Descriptor for the mode
@param ctx Context for this instance
@param iv_nbytes Length of the IV in bytes
@param iv Initialization vector
@result 0 iff successful.
@discussion Set the initialization vector for encryption.
@warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
In stateful protocols, if each packet exposes a guaranteed-unique value, it is recommended to format this as a 12-byte value for
use as the IV.
In stateless protocols, it is recommended to choose a 16-byte value using a cryptographically-secure pseudorandom number
generator (e.g. @p ccrng).
@warning This function may not be used after initializing the cipher via @p ccgcm_init_with_iv. Nonzero is returned in the event
of an improper call sequence.
@warning This function is not FIPS-compliant. Use @p ccgcm_init_with_iv instead.
*/
CC_INLINE int ccgcm_set_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t iv_nbytes, const void *iv)
{
return mode->set_iv(ctx, iv_nbytes, iv);
}
/*!
@function ccgcm_set_iv_legacy
@abstract Set the IV for encryption.
@param mode Descriptor for the mode
@param ctx Context for this instance
@param iv_nbytes Length of the IV in bytes
@param iv Initialization vector
@result 0 iff successful.
@discussion Identical to @p ccgcm_set_iv except that it allows zero-length IVs.
@warning Zero-length IVs nullify the authenticity guarantees of GCM.
@warning Do not use this function in new applications.
*/
int ccgcm_set_iv_legacy(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t iv_nbytes, const void *iv);
/*!
@function ccgcm_inc_iv
@abstract Increment the IV for another encryption.
@param mode Descriptor for the mode
@param ctx Context for this instance
@param iv Updated initialization vector
@result 0 iff successful.
@discussion Updates the IV internally for another encryption.
Internally, the IV is treated as a four-byte salt followed by an eight-byte counter. This is to match the behavior of certain
protocols (e.g. TLS). The counter component is interpreted as a big-endian, unsigned value and incremented in place.
The updated IV is copied to @p iv. This is to support protocols that require part of the IV to be specified explicitly in each
packet (e.g. TLS).
@warning This function may be used only after initializing the cipher via @p ccgcm_init_with_iv.
*/
int ccgcm_inc_iv(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, void *iv);
/*!
@function ccgcm_aad
@abstract Authenticate additional data.
@param mode Descriptor for the mode
@param ctx Context for this instance
@param nbytes Length of the additional data in bytes
@param additional_data Additional data to authenticate
@result 0 iff successful.
@discussion This is typically used to authenticate data that cannot be encrypted (e.g. packet headers).
This function may be called zero or more times.
*/
CC_INLINE int ccgcm_aad(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t nbytes, const void *additional_data)
{
return mode->gmac(ctx, nbytes, additional_data);
}
/*!
@function ccgcm_gmac
@discussion ccgcm_gmac is deprecated. Use the drop-in replacement 'ccgcm_aad' instead.
*/
CC_INLINE int ccgcm_gmac (const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t nbytes, const void *in)
cc_deprecate_with_replacement("ccgcm_aad", 13.0, 10.15, 13.0, 6.0, 4.0)
{
return mode->gmac(ctx, nbytes, in);
}
/*!
@function ccgcm_update
@abstract Encrypt or decrypt data.
@param mode Descriptor for the mode
@param ctx Context for this instance
@param nbytes Length of the data in bytes
@param in Input plaintext or ciphertext
@param out Output ciphertext or plaintext
@result 0 iff successful.
@discussion In-place processing is supported.
This function may be called zero or more times.
*/
CC_INLINE int ccgcm_update(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t nbytes, const void *in, void *out)
{
return mode->gcm(ctx, nbytes, in, out);
}
/*!
@function ccgcm_finalize
@abstract Finish processing and authenticate.
@param mode Descriptor for the mode
@param ctx Context for this instance
@param tag_nbytes Length of the tag in bytes
@param tag Authentication tag
@result 0 iff successful.
@discussion Finish processing a packet and generate the authentication tag.
On encryption, @p tag is purely an output parameter. The generated tag is written to @p tag.
On decryption, @p tag is both an input and an output parameter. Well-behaved callers should provide the authentication tag
generated during encryption. The function will return nonzero if the input tag does not match the generated tag. The generated
tag will be written into the @p tag buffer whether authentication succeeds or fails.
@warning The generated tag is written to @p tag to support legacy applications that perform authentication manually. Do not
follow this usage pattern in new applications. Rely on the function's error code to verify authenticity.
*/
CC_INLINE int ccgcm_finalize(const struct ccmode_gcm *mode, ccgcm_ctx *ctx, size_t tag_nbytes, void *tag)
{
return mode->finalize(ctx, tag_nbytes, tag);
}
/*!
@function ccgcm_reset
@abstract Reset the context for another encryption.
@param mode Descriptor for the mode
@param ctx Context for this instance
@result 0 iff successful.
@discussion Refer to @p ccgcm_init for correct usage.
*/
CC_INLINE int ccgcm_reset(const struct ccmode_gcm *mode, ccgcm_ctx *ctx)
{
return mode->reset(ctx);
}
/*!
@function ccgcm_one_shot
@abstract Encrypt or decrypt with GCM.
@param mode Descriptor for the mode
@param key_nbytes Length of the key in bytes
@param key Key for the underlying blockcipher (AES)
@param iv_nbytes Length of the IV in bytes
@param iv Initialization vector
@param adata_nbytes Length of the additional data in bytes
@param adata Additional data to authenticate
@param nbytes Length of the data in bytes
@param in Input plaintext or ciphertext
@param out Output ciphertext or plaintext
@param tag_nbytes Length of the tag in bytes
@param tag Authentication tag
@result 0 iff successful.
@discussion Perform GCM encryption or decryption.
@warning The key-IV pair must be unique per encryption. The IV must be nonzero in length.
In stateful protocols, if each packet exposes a guaranteed-unique value, it is recommended to format this as a 12-byte value for
use as the IV.
In stateless protocols, it is recommended to choose a 16-byte value using a cryptographically-secure pseudorandom number
generator (e.g. @p ccrng).
In-place processing is supported.
On encryption, @p tag is purely an output parameter. The generated tag is written to @p tag.
On decryption, @p tag is primarily an input parameter. The caller should provide the authentication tag generated during
encryption. The function will return nonzero if the input tag does not match the generated tag.
@warning To support legacy applications, @p tag is also an output parameter during decryption. The generated tag is written to @p
tag. Legacy callers may choose to compare this to the tag generated during encryption. Do not follow this usage pattern in new
applications.
*/
int ccgcm_one_shot(const struct ccmode_gcm *mode,
size_t key_nbytes,
const void *key,
size_t iv_nbytes,
const void *iv,
size_t adata_nbytes,
const void *adata,
size_t nbytes,
const void *in,
void *out,
size_t tag_nbytes,
void *tag);
/*!
@function ccgcm_one_shot_legacy
@abstract Encrypt or decrypt with GCM.
@param mode Descriptor for the mode
@param key_nbytes Length of the key in bytes
@param key Key for the underlying blockcipher (AES)
@param iv_nbytes Length of the IV in bytes
@param iv Initialization vector
@param adata_nbytes Length of the additional data in bytes
@param adata Additional data to authenticate
@param nbytes Length of the data in bytes
@param in Input plaintext or ciphertext
@param out Output ciphertext or plaintext
@param tag_nbytes Length of the tag in bytes
@param tag Authentication tag
@result 0 iff successful.
@discussion Identical to @p ccgcm_one_shot except that it allows zero-length IVs.
@warning Zero-length IVs nullify the authenticity guarantees of GCM.
@warning Do not use this function in new applications.
*/
int ccgcm_one_shot_legacy(const struct ccmode_gcm *mode,
size_t key_nbytes,
const void *key,
size_t iv_nbytes,
const void *iv,
size_t adata_nbytes,
const void *adata,
size_t nbytes,
const void *in,
void *out,
size_t tag_nbytes,
void *tag);
/* CCM */
#define ccccm_ctx_decl(_size_, _name_) cc_ctx_decl(ccccm_ctx, _size_, _name_)
#define ccccm_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
/* Declare a ccm nonce named _name_. Pass the mode->nonce_ctx_size for _size_. */
#define ccccm_nonce_decl(_size_, _name_) cc_ctx_decl(ccccm_nonce, _size_, _name_)
#define ccccm_nonce_clear(_size_, _name_) cc_clear(_size_, _name_)
CC_INLINE size_t ccccm_context_size(const struct ccmode_ccm *mode)
{
return mode->size;
}
CC_INLINE size_t ccccm_block_size(const struct ccmode_ccm *mode)
{
return mode->block_size;
}
CC_INLINE int ccccm_init(const struct ccmode_ccm *mode, ccccm_ctx *ctx, size_t key_len, const void *key)
{
return mode->init(mode, ctx, key_len, key);
}
CC_INLINE int ccccm_set_iv(const struct ccmode_ccm *mode,
ccccm_ctx *ctx,
ccccm_nonce *nonce_ctx,
size_t nonce_len,
const void *nonce,
size_t mac_size,
size_t auth_len,
size_t data_len)
{
return mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, auth_len, data_len);
}
CC_INLINE int ccccm_cbcmac(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in)
{
return mode->cbcmac(ctx, nonce_ctx, nbytes, in);
}
CC_INLINE int
ccccm_update(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in, void *out)
{
return mode->ccm(ctx, nonce_ctx, nbytes, in, out);
}
CC_INLINE int ccccm_finalize(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, void *mac)
{
return mode->finalize(ctx, nonce_ctx, mac);
}
CC_INLINE int ccccm_reset(const struct ccmode_ccm *mode, ccccm_ctx *ctx, ccccm_nonce *nonce_ctx)
{
return mode->reset(ctx, nonce_ctx);
}
CC_INLINE int ccccm_one_shot(const struct ccmode_ccm *mode,
size_t key_len,
const void *key,
size_t nonce_len,
const void *nonce,
size_t nbytes,
const void *in,
void *out,
size_t adata_len,
const void *adata,
size_t mac_size,
void *mac)
{
int rc;
ccccm_ctx_decl(mode->size, ctx);
ccccm_nonce_decl(mode->nonce_size, nonce_ctx);
rc = mode->init(mode, ctx, key_len, key);
if (rc == 0) {
rc = mode->set_iv(ctx, nonce_ctx, nonce_len, nonce, mac_size, adata_len, nbytes);
}
if (rc == 0) {
rc = mode->cbcmac(ctx, nonce_ctx, adata_len, adata);
}
if (rc == 0) {
rc = mode->ccm(ctx, nonce_ctx, nbytes, in, out);
}
if (rc == 0) {
rc = mode->finalize(ctx, nonce_ctx, mac);
}
ccccm_ctx_clear(mode->size, ctx);
ccccm_nonce_clear(mode->nonce_size, nonce_ctx);
return rc;
}
/* OMAC mode. */
/* Declare a omac key named _name_. Pass the size field of a struct ccmode_omac
for _size_. */
#define ccomac_ctx_decl(_size_, _name_) cc_ctx_decl(ccomac_ctx, _size_, _name_)
#define ccomac_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
CC_INLINE size_t ccomac_context_size(const struct ccmode_omac *mode)
{
return mode->size;
}
CC_INLINE size_t ccomac_block_size(const struct ccmode_omac *mode)
{
return mode->block_size;
}
CC_INLINE int ccomac_init(const struct ccmode_omac *mode, ccomac_ctx *ctx, size_t tweak_len, size_t key_len, const void *key)
{
return mode->init(mode, ctx, tweak_len, key_len, key);
}
CC_INLINE int
ccomac_update(const struct ccmode_omac *mode, ccomac_ctx *ctx, size_t nblocks, const void *tweak, const void *in, void *out)
{
return mode->omac(ctx, nblocks, tweak, in, out);
}
CC_INLINE int ccomac_one_shot(const struct ccmode_omac *mode,
size_t tweak_len,
size_t key_len,
const void *key,
const void *tweak,
size_t nblocks,
const void *in,
void *out)
{
int rc;
ccomac_ctx_decl(mode->size, ctx);
rc = mode->init(mode, ctx, tweak_len, key_len, key);
if (rc == 0) {
rc = mode->omac(ctx, nblocks, tweak, in, out);
}
ccomac_ctx_clear(mode->size, ctx);
return rc;
}
#endif /* _CORECRYPTO_CCMODE_H_ */

View File

@ -0,0 +1,231 @@
/* Copyright (c) (2010,2011,2012,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCMODE_IMPL_H_
#define _CORECRYPTO_CCMODE_IMPL_H_
#include <corecrypto/cc.h>
/* ECB mode. */
cc_aligned_struct(16) ccecb_ctx;
/* Actual symmetric algorithm implementation should provide you one of these. */
struct ccmode_ecb {
size_t size; /* first argument to ccecb_ctx_decl(). */
size_t block_size;
int (*CC_SPTR(ccmode_ecb, init))(const struct ccmode_ecb *ecb, ccecb_ctx *ctx, size_t key_nbytes, const void *key);
int (*CC_SPTR(ccmode_ecb, ecb))(const ccecb_ctx *ctx, size_t nblocks, const void *in, void *out);
void (*CC_SPTR(ccmode_ecb, roundkey))(const ccecb_ctx *ctx, unsigned r, void *key);
};
/*!
* @brief corecrypto symmetrical encryption and decryption modes
*
* corecrypto supports 6 stateless en(de)cryption modes and 2 stateful authenticated en(de)cryption modes
* stateless modes CBC, CFB, CFB8, CTR, OFB, XTS: They provide 3 interface functions that do not return errors codes
* 1- ccmod_xxx_init()
* 2- ccmod_xxx_decrypt()
* 3- ccmod_xxx_encrypt()
*
* stateful modes CCM and GCM: They provide 7 interface functions that return error codes if a function is called out of state
* 1- ccmod_xxx_init()
* 2- ccmod_xxx_setiv()
* 3- ccmod_xxx_aad()
* 4- ccmod_xxx_decrypt()
* 5- ccmod_xxx_encrypt()
* 6- ccmod_xxx_finalize()
* 7- ccmod_xxx_reset()
*
* the correct call sequences are:
*
* calls to 1, 2 and 6 arerequired
* 2 and 3 can be called as mant times as needed
* calls to 3, 4, 5 can be skipped
*
* 1, 2*n, 3*n, 4|5, 6
* 1, 2*n, , 4|5, 6
* 1, 2*n, , , 6
* 1, 2*n, 3*n, , 6
*/
// 1- CBC mode, stateless
cc_aligned_struct(16) cccbc_ctx;
cc_aligned_struct(16) cccbc_iv;
struct ccmode_cbc {
size_t size; /* first argument to cccbc_ctx_decl(). */
size_t block_size;
int (*CC_SPTR(ccmode_cbc, init))(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, size_t key_len, const void *key);
/* cbc encrypt or decrypt nblocks from in to out, iv will be used and updated. */
int (*CC_SPTR(ccmode_cbc, cbc))(const cccbc_ctx *ctx, cccbc_iv *iv, size_t nblocks, const void *in, void *out);
const void *custom;
};
// 2- CFB mode, stateless
cc_aligned_struct(16) cccfb_ctx;
struct ccmode_cfb {
size_t size; /* first argument to cccfb_ctx_decl(). */
size_t block_size;
int (*CC_SPTR(ccmode_cfb,
init))(const struct ccmode_cfb *cfb, cccfb_ctx *ctx, size_t key_len, const void *key, const void *iv);
int (*CC_SPTR(ccmode_cfb, cfb))(cccfb_ctx *ctx, size_t nbytes, const void *in, void *out);
const void *custom;
};
// 3- CFB8 mode, stateless
cc_aligned_struct(16) cccfb8_ctx;
struct ccmode_cfb8 {
size_t size; /* first argument to cccfb8_ctx_decl(). */
size_t block_size;
int (*CC_SPTR(ccmode_cfb8,
init))(const struct ccmode_cfb8 *cfb8, cccfb8_ctx *ctx, size_t key_len, const void *key, const void *iv);
int (*CC_SPTR(ccmode_cfb8, cfb8))(cccfb8_ctx *ctx, size_t nbytes, const void *in, void *out);
const void *custom;
};
// 4- CTR mode, stateless
cc_aligned_struct(16) ccctr_ctx;
struct ccmode_ctr {
size_t size; /* first argument to ccctr_ctx_decl(). */
size_t block_size; /* for historical reasons, this is set to 1 */
size_t ecb_block_size; /* the actual block size of the underlying cipher */
int (*CC_SPTR(ccmode_ctr,
init))(const struct ccmode_ctr *mode, ccctr_ctx *ctx, size_t key_len, const void *key, const void *iv);
int (*CC_SPTR(ccmode_ctr, setctr))(const struct ccmode_ctr *mode, ccctr_ctx *ctx, const void *ctr);
int (*CC_SPTR(ccmode_ctr, ctr))(ccctr_ctx *ctx, size_t nbytes, const void *in, void *out);
const void *custom;
};
// 5- OFB mode, stateless
cc_aligned_struct(16) ccofb_ctx;
struct ccmode_ofb {
size_t size; /* first argument to ccofb_ctx_decl(). */
size_t block_size;
int (*CC_SPTR(ccmode_ofb,
init))(const struct ccmode_ofb *ofb, ccofb_ctx *ctx, size_t key_len, const void *key, const void *iv);
int (*CC_SPTR(ccmode_ofb, ofb))(ccofb_ctx *ctx, size_t nbytes, const void *in, void *out);
const void *custom;
};
// 6- XTS mode, stateless
cc_aligned_struct(16) ccxts_ctx;
cc_aligned_struct(16) ccxts_tweak;
struct ccmode_xts {
size_t size; /* first argument to ccxts_ctx_decl(). Size of the ctx data structure */
size_t tweak_size; /* first argument to ccxts_tweak_decl(). Size of the tweak structure, not the expected tweak size */
size_t block_size;
/* Create a xts key from a xts mode object.
key must point to at least 'size' bytes of free storage.
tweak_key must point to at least 'tweak_size' bytes of free storage.
key and tweak_key must differ.
Returns nonzero on failure.
*/
int (*CC_SPTR(ccmode_xts, init))(const struct ccmode_xts *xts,
ccxts_ctx *ctx,
size_t key_nbytes,
const void *data_key,
const void *tweak_key);
void (*CC_SPTR(ccmode_xts, key_sched))(const struct ccmode_xts *xts,
ccxts_ctx *ctx,
size_t key_nbytes,
const void *data_key,
const void *tweak_key);
/* Set the tweak (sector number), the block within the sector zero. */
int (*CC_SPTR(ccmode_xts, set_tweak))(const ccxts_ctx *ctx, ccxts_tweak *tweak, const void *iv);
/* Encrypt blocks for a sector, clients must call set_tweak before calling
this function. Return a pointer to the tweak buffer */
void *(*CC_SPTR(ccmode_xts, xts))(const ccxts_ctx *ctx, ccxts_tweak *tweak, size_t nblocks, const void *in, void *out);
const void *custom;
const void *custom1;
};
// 7- GCM mode, statful
cc_aligned_struct(16) ccgcm_ctx;
#define CCMODE_GCM_DECRYPTOR 78647
#define CCMODE_GCM_ENCRYPTOR 4073947
struct ccmode_gcm {
size_t size; /* first argument to ccgcm_ctx_decl(). */
int encdec; // is it encrypt or decrypt object
size_t block_size;
int (*CC_SPTR(ccmode_gcm, init))(const struct ccmode_gcm *gcm, ccgcm_ctx *ctx, size_t key_nbytes, const void *key);
int (*CC_SPTR(ccmode_gcm, set_iv))(ccgcm_ctx *ctx, size_t iv_nbytes, const void *iv);
int (*CC_SPTR(ccmode_gcm, gmac))(ccgcm_ctx *ctx, size_t nbytes, const void *in); // could just be gcm with NULL out
int (*CC_SPTR(ccmode_gcm, gcm))(ccgcm_ctx *ctx, size_t nbytes, const void *in, void *out);
int (*CC_SPTR(ccmode_gcm, finalize))(ccgcm_ctx *key, size_t tag_nbytes, void *tag);
int (*CC_SPTR(ccmode_gcm, reset))(ccgcm_ctx *ctx);
const void *custom;
};
// 8- CCM mode, stateful
cc_aligned_struct(16) ccccm_ctx;
cc_aligned_struct(16) ccccm_nonce;
struct ccmode_ccm {
size_t size; /* first argument to ccccm_ctx_decl(). */
size_t nonce_size; /* first argument to ccccm_nonce_decl(). */
size_t block_size;
int (*CC_SPTR(ccmode_ccm, init))(const struct ccmode_ccm *ccm, ccccm_ctx *ctx, size_t key_len, const void *key);
int (*CC_SPTR(ccmode_ccm, set_iv))(ccccm_ctx *ctx,
ccccm_nonce *nonce_ctx,
size_t nonce_len,
const void *nonce,
size_t mac_size,
size_t auth_len,
size_t data_len);
int (*CC_SPTR(ccmode_ccm, cbcmac))(ccccm_ctx *ctx,
ccccm_nonce *nonce_ctx,
size_t nbytes,
const void *in); // could just be ccm with NULL out
int (*CC_SPTR(ccmode_ccm, ccm))(ccccm_ctx *ctx, ccccm_nonce *nonce_ctx, size_t nbytes, const void *in, void *out);
int (*CC_SPTR(ccmode_ccm, finalize))(ccccm_ctx *key, ccccm_nonce *nonce_ctx, void *mac);
int (*CC_SPTR(ccmode_ccm, reset))(ccccm_ctx *key, ccccm_nonce *nonce_ctx);
const void *custom;
};
/* We need to expose this (currently)to keep CommonCrypto happy. */
struct _ccmode_ccm_nonce {
unsigned char A_i[16]; /* crypto block iv */
unsigned char B_i[16]; /* mac block iv */
unsigned char MAC[16]; /* crypted mac */
unsigned char buf[16]; /* crypt buffer */
uint32_t mode; /* mode: IV -> AD -> DATA */
uint32_t buflen; /* length of data in buf */
uint32_t b_i_len; /* length of cbcmac data in B_i */
size_t nonce_size;
size_t mac_size;
};
/* OMAC mode. */
cc_aligned_struct(16) ccomac_ctx;
struct ccmode_omac {
size_t size; /* first argument to ccomac_ctx_decl(). */
size_t block_size;
int (*CC_SPTR(ccmode_omac,
init))(const struct ccmode_omac *omac, ccomac_ctx *ctx, size_t tweak_len, size_t key_len, const void *key);
int (*CC_SPTR(ccmode_omac, omac))(ccomac_ctx *ctx, size_t nblocks, const void *tweak, const void *in, void *out);
const void *custom;
};
#endif /* _CORECRYPTO_CCMODE_IMPL_H_ */

View File

@ -0,0 +1,268 @@
/* Copyright (c) (2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCMODE_SIV_H_
#define _CORECRYPTO_CCMODE_SIV_H_
#include <corecrypto/cc.h>
#include <corecrypto/ccmode.h>
#include <corecrypto/ccmode_impl.h>
#include <corecrypto/cccmac.h>
/* This provide an implementation of SIV
as specified in https://tools.ietf.org/html/rfc5297
also in http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/siv/siv.pdf
Counter Mode where IV is based on CMAC
*/
cc_aligned_struct(16) ccsiv_ctx;
struct ccmode_siv {
size_t size; /* first argument to ccsiv_ctx_decl(). */
size_t block_size;
int (*CC_SPTR(ccmode_siv, init))(const struct ccmode_siv *siv, ccsiv_ctx *ctx,
size_t key_len, const uint8_t *key);
int (*CC_SPTR(ccmode_siv, set_nonce))(ccsiv_ctx *ctx, size_t nbytes, const uint8_t *in); // could just be ccm with NULL out
int (*CC_SPTR(ccmode_siv, auth))(ccsiv_ctx *ctx, size_t nbytes, const uint8_t *in); // could just be ccm with NULL out
int (*CC_SPTR(ccmode_siv, crypt))(ccsiv_ctx *ctx, size_t nbytes, const uint8_t *in, uint8_t *out);
int (*CC_SPTR(ccmode_siv, reset))(ccsiv_ctx *ctx);
const struct ccmode_cbc *cbc;
const struct ccmode_ctr *ctr;
};
#define ccsiv_ctx_decl(_size_, _name_) cc_ctx_decl(ccsiv_ctx, _size_, _name_)
#define ccsiv_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
// Functions
CC_INLINE size_t ccsiv_context_size(const struct ccmode_siv *mode)
{
return mode->size;
}
/*!
@function ccsiv_block_size
@abstract Return the block_size = block_length = tag_length used in the mode.
@param mode ccsiv mode descriptor
@discussion Used to return the current block size of the SIV mode. Note that the tag in this mode is an output of the underlying blockcipher and therefore the tag length corresponds to the block size.
*/
CC_INLINE size_t ccsiv_block_size(const struct ccmode_siv *mode)
{
return mode->block_size;
}
/*!
@function ccsiv_ciphertext_size
@abstract Return size of Ciphertext (which is the ciphertext and corresponding tag) given the mode and plaintext length
@param mode ccsiv mode descriptor
@param plaintext_size Size of the plaintext
@discussion returns the length of the aead ciphertext that the context will generate which includes both the encrypted plaintext and tag.
*/
CC_INLINE size_t ccsiv_ciphertext_size(const struct ccmode_siv *mode,
size_t plaintext_size)
{
return plaintext_size + mode->cbc->block_size;
}
/*!
@function ccsiv_plaintext_size
@abstract Return size of plaintext given a ciphertext length and mode.
@param mode ccsiv mode descriptor
@param ciphertext_size Size of the ciphertext
@discussion returns the length of the plaintext which results from the decryption of a ciphertext of the corresponding size (here ciphertext size includes the tag).
*/
CC_INLINE size_t ccsiv_plaintext_size(const struct ccmode_siv *mode,
size_t ciphertext_size)
{
if (ciphertext_size<mode->cbc->block_size) {
return 0; // error
}
return ciphertext_size - mode->cbc->block_size;
}
/*!
@function ccsiv_init
@abstract Initialize a context for ccsiv with an associated mode, and given key.
@param mode Descriptor for the mode
@param ctx Alocated context to be intialized
@param key_byte_len Length of the key: Supported key sizes are 32, 48, 64 bytes.
@param key key for siv. All bits of this key should be random. (See discussion)
@discussion In order to compute SIV_Enc_k(a1,...,am, n, x) where ai is the ith piece of associated data, n is a nonce and x is a plaintext, we use the following sequence of calls :
@code
ccsiv_init(...)
ccsiv_aad(...) (may be called zero or more times)
ccsiv_set_nonce(...)
ccsiv_crypt(...)
@endcode
To reuse the context for additional encryptions, follow this sequence:
@code
ccsiv_reset(...)
ccsiv_aad(...) (may be called zero or more times)
ccsiv_set_nonce(...)
ccsiv_crypt(...)
@endcode
Importantly, all the bits in the key need to be random. Duplicating a smaller key to achieve a longer key length will result in an insecure implementation.
*/
CC_INLINE int ccsiv_init(const struct ccmode_siv *mode, ccsiv_ctx *ctx,
size_t key_byte_len, const uint8_t *key)
{
return mode->init(mode, ctx, key_byte_len, key);
}
/*!
@function ccsiv_set_nonce
@abstract Add the nonce to the siv's computation of the the tag. Changes the internal state of the context
so that after the call only a crypt or reset call is permitted.
@param mode Descriptor for the mode
@param ctx Intialized ctx
@param nbytes Length of the current nonce data being added
@param in Nonce data to be authenticated.
@discussion The nonce is a special form of authenticated data. If provided (a call to ccsiv_set_nonce is optional) it allows
randomization of the ciphertext (preventing deterministic encryption). While the length of the nonce is not limmited, the
amount of entropy that can be provided is limited by the number of bits in the block of the associated block-cipher.
*/
CC_INLINE int ccsiv_set_nonce(const struct ccmode_siv *mode, ccsiv_ctx *ctx,
size_t nbytes, const uint8_t *in)
{
return mode->set_nonce(ctx, nbytes, in);
}
/*!
@function ccsiv_aad
@abstract Add the next piece of associated data to the SIV's computation of the tag.
@param mode Descriptor for the mode
@param ctx Intialized ctx
@param nbytes Length of the current associated data being added
@param in Associated data to be authenticated.
@discussion Adds the associated data given by in to the computation of the tag in the associated data. Note this call is optional and no associated data needs to be provided. Multiple pieces of associated data can be provided by multiple calls to this function. Note the associated data in this case is simply computed as the concatenation of all of the associated data inputs.
*/
CC_INLINE int ccsiv_aad(const struct ccmode_siv *mode, ccsiv_ctx *ctx,
size_t nbytes, const uint8_t *in)
{
return mode->auth(ctx, nbytes, in);
}
/*!
@function ccsiv_crypt
@abstract Depdening on mode, 1) Encrypts a plaintext , or 2) Decrypts a ciphertext
@param mode Descriptor for the mode
@param ctx Intialized ctx
@param nbytes Case 1) Length of the current plaintext
Case 2) Length of the current ciphertext (block length + plaintext length).
@param in Case 1) Plaintext
Case 2) Ciphertext
@param out Case 1) Tag+ciphertext (buffer should be already allocated and of length block_length+plaintext_length.)
Case 2) Plaintext (buffer should be already allocated and of length ciphertext_length - block_length length
@discussion Depending on whether mode has been setup to encrypt or decrypt, this function
1) Encrypts the plaintext given as input in, and provides the ciphertext (which is a concatenation of the cbc-tag
followed by the encrypted plaintext) as output out. 2) Decrypts plaintext using the input ciphertext at in (which again is the cbc-tag, followed by encrypted plaintext), and then verifies that the computed tag and provided tags match.
This function is only called once. If one wishes to compute another (en)/(de)cryption, one resets the state with
ccsiv_reset, and then begins the process again. There is no way to stream large plaintext/ciphertext inputs into the
function.
In the case of a decryption, if there is a failure in verifying the computed tag against the provided tag (embedded int he ciphertext), then a decryption/verification
failure is returned, and any internally computed plaintexts and tags are zeroed out.
Lastly the contexts internal state is reset, so that a new decryption/encryption can be commenced.
Decryption can be done in place in memory by setting in=out. Encryption cannot be done in place. However, if one is trying to minimize memory usage one can set out = in - block_length, which results in the ciphertext being encrypted inplace, and the IV being prepended before the ciphertext.
*/
CC_INLINE int ccsiv_crypt(const struct ccmode_siv *mode, ccsiv_ctx *ctx,
size_t nbytes, const uint8_t *in, uint8_t *out)
{
return mode->crypt(ctx, nbytes, in, out);
}
/*!
@function ccsiv_reset
@abstract Resets the state of the ccsiv_ctx ctx, maintaing the key, but preparing the
ctx to preform a new Associated Data Authenticated (En)/(De)cryption.
@param mode Descriptor for the mode
@param ctx Intialized ctx
*/
CC_INLINE int ccsiv_reset(const struct ccmode_siv *mode, ccsiv_ctx *ctx)
{
return mode->reset(ctx);
}
/*!
@function ccsiv_one_shot
@abstract A simplified but more constrained way of performing a AES SIV (en)/(de)cryption. It is limited because only
one piece of associated data may be provided.
@param mode Descriptor for the mode
@param key_len Length of the key: Supported key sizes are 32, 48, 64 bytes
@param key key for siv
@param nonce_nbytes Length of the current nonce data being added
@param nonce Nonce data to be authenticated.
@param adata_nbytes Length of the associated data.
@param adata Associated data to be authenticated.
@param in_nbytes Length of either the plaintext (for encryption) or ciphertext (for decryption), in the latter case the length includes the length of the tag.
@param in Plaintext or ciphertext. Note that the ciphertext includes a tag of length tag_length prepended to it.
@param out Buffer to hold ciphertext/plaintext. (Note Ciphertext is of size plaintext_length + block_length and plaintext is of ciphertext_length - block_length, as the tag has the length of one block.
Must be the case that out<= in - block length || out>= in + plaintext_length
@discussion Decryption can be done in place in memory by setting in=out. Encryption cannot be done in place. However, is one is trying to minimize memory usage
one can set out = in - block_length, which results in the ciphertext being encrypted inplace, and the IV being prepended before the ciphertext.
Suppose the block length is 16 bytes long (AES) and plaintext of length 20, then we could set in = 16, out = 0 let the bytes of the plaintext be denoted as P_1...P_20
then memory is depicted as:
| 0 = ? | 1 = ? | ... | 15 = ? | 16 = P_1 | ... | 35 = P_20 |
| | | | |
V V V V V
|IV_1 | IV_2 | ... | IV_16 | C_1 | ... | C_20 |
Note that the ciphrtext itself is encrypted in place, but the IV prefixes the ciphertext.
*/
CC_INLINE int ccsiv_one_shot(const struct ccmode_siv *mode,
size_t key_len, const uint8_t *key,
unsigned nonce_nbytes, const uint8_t* nonce,
unsigned adata_nbytes, const uint8_t* adata,
size_t in_nbytes, const uint8_t *in, uint8_t *out)
{
int rc;
ccsiv_ctx_decl(mode->size, ctx);
rc=mode->init(mode, ctx, key_len, key);
if (rc) {return rc;}
rc=mode->set_nonce(ctx, nonce_nbytes, nonce);
if (rc) {return rc;}
rc=mode->auth(ctx, adata_nbytes, adata);
if (rc) {return rc;}
rc=mode->crypt(ctx, in_nbytes, in, out);
if (rc) {return rc;}
ccsiv_ctx_clear(mode->size, ctx);
return rc;
}
#endif /* _CORECRYPTO_CCMODE_H_ */

View File

@ -0,0 +1,213 @@
/* Copyright (c) (2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
// Created by Apple on 12/10/18.
//
#ifndef ccmode_siv_hmac_h
#define ccmode_siv_hmac_h
#include <corecrypto/cc.h>
#include <corecrypto/ccmode.h>
#include <corecrypto/ccmode_impl.h>
#include <corecrypto/ccdigest.h>
#include <corecrypto/cchmac.h>
#include <corecrypto/ccsha2.h>
/* This provides an implementation of SIV using AES CTR mode with HMAC as the MAC,
allowing for a tagging mechanism with collision resistant tags. This is a modification of the
standard specified in https://tools.ietf.org/html/rfc5297
also in http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/siv/siv.pdf
Counter Mode where IV is based on HMAC.
*/
cc_aligned_struct(16) ccsiv_hmac_ctx;
struct ccmode_siv_hmac {
size_t size; /* first argument to ccsiv_hmac_ctx_decl(). */
size_t block_size;
int (*CC_SPTR(ccmode_siv_hmac, init))(const struct ccmode_siv_hmac *sivhmac,
ccsiv_hmac_ctx *ctx,
size_t key_len,
const uint8_t *key,
const size_t tag_size);
int (*CC_SPTR(ccmode_siv_hmac, set_nonce))(ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in);
int (*CC_SPTR(ccmode_siv_hmac, auth))(ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in);
int (*CC_SPTR(ccmode_siv_hmac, crypt))(ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in, uint8_t *out);
int (*CC_SPTR(ccmode_siv_hmac, reset))(ccsiv_hmac_ctx *ctx);
const struct ccdigest_info *hmac_digest; // Digest to be used in HMAC;
const struct ccmode_ctr *ctr;
};
#define ccsiv_hmac_ctx_decl(_size_, _name_) cc_ctx_decl(ccsiv_hmac_ctx, _size_, _name_)
#define ccsiv_hmac_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
/*!
@function ccsiv_hmac_context_size
@abstract Return size of context
@param mode Descriptor for the mode
*/
CC_INLINE size_t ccsiv_hmac_context_size(const struct ccmode_siv_hmac *mode)
{
return mode->size;
}
/*!
@function ccsiv_hmac_block_size
@abstract Return size of context
@param mode Descriptor for the mode
*/
CC_INLINE size_t ccsiv_hmac_block_size(const struct ccmode_siv_hmac *mode)
{
return mode->block_size;
}
/*!
@function ccsiv_hmac_ciphertext_size
@abstract Return size of Ciphertext (which is the ciphertext and corresponding tag) given the mode and plaintext length
@param ctx Current siv_hmac context that has been previously initialized
@param plaintext_size Size of the plaintext
@discussion returns the length of the aead ciphertext that the context will generate which includes both the encrypted plaintext
and tag.
*/
size_t ccsiv_hmac_ciphertext_size(ccsiv_hmac_ctx *ctx, size_t plaintext_size);
/*!
@function ccsiv_hmac_plaintext_size
@abstract Return size of plaintext given a ciphertext length and mode.
@param ctx Current siv_hmac context that has been previously initialized
@param ciphertext_size Size of the ciphertext (which includes the tag)
@discussion returns the length of the plaintext which results from the decryption of a ciphertext of the corresponding size (here ciphertext size includes the tag).
*/
size_t ccsiv_hmac_plaintext_size(ccsiv_hmac_ctx *ctx, size_t ciphertext_size);
/*!
@function ccsiv_hmac_init
@abstract Initialize a context for siv_hmac with an associated mode, given key and specifying output tag size.
@param mode Descriptor for the mode
@param ctx Alocated context to be intialized
@param key_byte_len Length of the key: Supported key sizes are 32, 48, 64 bytes
@param key key for siv_hmac
@param tag_size The length of the output tag requested. Must be at least 20 bytes, and can be as larged as the
associated digest's output
@discussion In order to compute HMAC_SIV_Enc_k(a1,...,am, n, x) where ai is the ith piece of associated data, n is a nonce and x
is a plaintext, we first initialize the context with this call, and then use it to call ccsiv_hmac_aad for each ai, followed by
ccsiv_hmac_set_nonce for nonce n, and finally a call to ccsiv_hmac_crypt for the plaintext x. Note the order of the calls to aad,
nonce and then crypt is critical. If a second encryption is needed then a call to ccsiv_hmac_reset can be used to reset state,
and begin again.
*/
int ccsiv_hmac_init(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx, size_t key_byte_len, const uint8_t *key, size_t tag_size);
/*!
@function ccsiv_hmac_aad
@abstract Add the next piece of associated data to the hmac_siv's computation of the tag. Note this call is optional and no
associated data needs to be provided. Multiple pieces of associated data can be provided by multiple calls to this
function. Each input is regarded as a seperate piece of associated data, and the mac is NOT simply computed on the
concatenation of all of the associated data inputs. Therefore on decryption the same inputs must be prodivded and in
the same order.
@param mode Descriptor for the mode
@param ctx Intialized ctx
@param nbytes Length of the current associated data being added
@param in Associated data to be authenticated.
@discussion Adds the associated data given by in to the computation of the tag in the associated data.
*/
int ccsiv_hmac_aad(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in);
/*!
@function ccsiv_hmac_nonce
@abstract Add the nonce to the hmac_siv's computation of the the tag. Changes the internal state of the context
so that after the call only a crypt or reset call is permitted.
@param mode Descriptor for the mode
@param ctx Intialized ctx
@param nbytes Length of the current nonce data being added
@param in Nonce data to be authenticated.
@discussion The nonce is a special form of authenticated data. If provided ( a call to hmac_nonce is optional) it allows
randomization of the of ciphertext (preventing deterministic encryption). While the length of the nonce is not limimited, the
amount of entropy that can be provided is limited by the number of bits in the block of the associated block-cipher in mode.
*/
int ccsiv_hmac_set_nonce(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in);
/*!
@function ccsiv_hmac_crypt
@abstract Depending on whether mode has been setup to encrypt or decrypt, this function
1) Encrypts the plaintext given as input in, and provides the ciphertext (which is a concatenation of the tag
followed by the encrypted plaintext) as output out. 2) Decrypts plaintext using the input ciphertext at in (which again is the
tag, followed by encrypted plaintext), and then verifies that the computer tag and provided tags match.
@param mode Descriptor for the mode
@param ctx Intialized ctx
@param nbytes Case 1) Length of the current plaintext
Case 2) Length of the current ciphertext (tag length + plaintext length)
@param in Case 1) Plaintext
Case 2) Ciphertext
@discussion This function is only called once. If one wishes to compute another (en)/(de)cryption, one resets the state with
ccsiv_hmac_reset, and then begins the process again. There is no way to stream large plaintext/ciphertext inputs into the
function.
@param out Case1) Tag+ Ciphertext (buffer should be already allocated and of length tag + plaintext length)
Case 2) Plaintext (buffer should be already allocated and of length ciphertext - tag length
In the case of a decryption, if there is a failure in verifying the computed tag against the provided tag (embedded int he ciphertext), then a decryption/verification
failure is returned, and any internally computed plaintexts and tags are zeroed out.
Lastly the contexts internal state is reset, so that a new decryption/encryption can be commenced.
*/
int ccsiv_hmac_crypt(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx, size_t nbytes, const uint8_t *in, uint8_t *out);
/*!
@function ccsiv_hmac_reset
@abstract Resets the state of the siv_hamc ctx, maintaing the key, but preparing the
ctx to preform a new Associated Data Authenticated (En)/(De)cryption.
@param mode Descriptor for the mode
@param ctx Intialized ctx
*/
int ccsiv_hmac_reset(const struct ccmode_siv_hmac *mode, ccsiv_hmac_ctx *ctx);
/*!
@function ccsiv_hmac_one_shot
@abstract A simplified but more constrained way of performing an AEAD SIV HMAC (en)/(de)cryption. It is limited because only
one piece of associated data may be provided.
@param mode Descriptor for the mode
@param key_len Length of the key: Supported key sizes are 32, 48, 64 bytes
@param key key for siv_hmac
@param tag_length The length of the tag to produce or accept as input. Must be at least 20
bytes, and can be as large as the hmac's digest's output
@param nonce_nbytes Length of the current nonce data being added
@param nonce Nonce data to be authenticated.
@param adata_nbytes Length of the associated data.
@param adata Associated data to be authenticated.
@param in_nbytes Length of either the plaintext (for encryption) or ciphertext (for decryption)
@param in plaintext or ciphertext. Note that the ciphertext includes a tag of length tag_length prepended to it.
@param out Buffer to hold ciphertext/plaintext. (Note Ciphertext is of size plaintext length + tag_length and plaintext is of length ciphertext - tag_length.)
*/
// One shot AEAD with only one input for adata, and a nonce.
int ccsiv_hmac_one_shot(const struct ccmode_siv_hmac *mode,
size_t key_len,
const uint8_t *key,
size_t tag_length,
unsigned nonce_nbytes,
const uint8_t *nonce,
unsigned adata_nbytes,
const uint8_t *adata,
size_t in_nbytes,
const uint8_t *in,
uint8_t *out);
#endif /* ccmode_siv_hmac_h */

View File

@ -0,0 +1,635 @@
/* Copyright (c) (2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCN_H_
#define _CORECRYPTO_CCN_H_
#include <corecrypto/cc.h>
#include <stdint.h>
#include <stdarg.h>
typedef uint8_t cc_byte;
typedef size_t cc_size;
#if CCN_UNIT_SIZE == 8
typedef uint64_t cc_unit; // 64 bit unit
typedef int64_t cc_int;
#define CCN_LOG2_BITS_PER_UNIT 6 // 2^6 = 64 bits
#define CC_UNIT_C(x) UINT64_C(x)
#if CCN_UINT128_SUPPORT_FOR_64BIT_ARCH
typedef unsigned cc_dunit __attribute__((mode(TI))); // 128 bit double width unit
typedef signed cc_dint __attribute__((mode(TI)));
#else
typedef struct cc_dunit {
uint64_t l; //do not change the order of the variables. cc_dunit must be little endian
uint64_t h;
} cc_dunit;
typedef struct cc_dint {
uint64_t l;
uint64_t h;
} cc_dint;
#endif
#elif CCN_UNIT_SIZE == 4
typedef uint32_t cc_unit; // 32 bit unit
typedef uint64_t cc_dunit; // 64 bit double width unit
typedef int64_t cc_dint;
typedef int32_t cc_int;
#define CCN_LOG2_BITS_PER_UNIT 5 // 2^5 = 32 bits
#define CC_UNIT_C(x) UINT32_C(x)
#elif CCN_UNIT_SIZE == 2
typedef uint16_t cc_unit; // 16 bit unit
typedef uint32_t cc_dunit; // 32 bit double width unit
#define CCN_LOG2_BITS_PER_UNIT 4 // 2^4 = 16 bits
#define CC_UNIT_C(x) UINT16_C(x)
#elif CCN_UNIT_SIZE == 1
typedef uint8_t cc_unit; // 8 bit unit
typedef uint16_t cc_dunit; // 16 bit double width unit
#define CCN_LOG2_BITS_PER_UNIT 3 // 2^3 = 8 bits
#define CC_UNIT_C(x) UINT8_C(x)
#else
#error invalid CCN_UNIT_SIZE
#endif
#define CCN_UNIT_BITS (sizeof(cc_unit) * 8)
#define CCN_UNIT_MASK ((cc_unit)~0)
#define CCN_UNIT_LOWER_HALF_MASK ((CCN_UNIT_MASK) >> (CCN_UNIT_BITS/2))
#define CCN_UNIT_UPPER_HALF_MASK (~CCN_UNIT_LOWER_HALF_MASK)
#define CCN_UNIT_HALF_BITS (CCN_UNIT_BITS / 2)
typedef struct {
cc_unit *start; // First cc_unit of the workspace
cc_unit *end; // address and beyond NOT TO BE TOUCHED
} cc_ws,*cc_ws_t;
/* Conversions between n sizeof and bits */
/* Returns the sizeof a ccn vector of length _n_ units. */
#define ccn_sizeof_n(_n_) (sizeof(cc_unit) * (_n_))
/* Returns the count (n) of a ccn vector that can represent _bits_. */
#define ccn_nof(_bits_) (((_bits_) + CCN_UNIT_BITS - 1) >> CCN_LOG2_BITS_PER_UNIT)
/* Returns the sizeof a ccn vector that can represent _bits_. */
#define ccn_sizeof(_bits_) (ccn_sizeof_n(ccn_nof(_bits_)))
/* Returns the count (n) of a ccn vector that can represent _size_ bytes. */
#define ccn_nof_size(_size_) (((_size_) + CCN_UNIT_SIZE - 1) / CCN_UNIT_SIZE)
#define ccn_nof_sizeof(_expr_) ccn_nof_size(sizeof (_expr_))
/* Return the max number of bits a ccn vector of _n_ units can hold. */
#define ccn_bitsof_n(_n_) ((_n_) * CCN_UNIT_BITS)
/* Return the max number of bits a ccn vector of _size_ bytes can hold. */
#define ccn_bitsof_size(_size_) ((_size_) * 8)
/* Return the size of a ccn of size bytes in bytes. */
#define ccn_sizeof_size(_size_) ccn_sizeof_n(ccn_nof_size(_size_))
/* Returns the value of bit _k_ of _ccn_, both are only evaluated once. */
#define ccn_bit(_ccn_, _k_) ({size_t __k = (size_t)(_k_); \
1 & ((_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] >> (__k & (CCN_UNIT_BITS - 1)));})
/* Set the value of bit _k_ of _ccn_ to the value _v_ */
#define ccn_set_bit(_ccn_, _k_, _v_) ({size_t __k = (size_t)(_k_); \
if (_v_) \
(_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] |= CC_UNIT_C(1) << (__k & (CCN_UNIT_BITS - 1)); \
else \
(_ccn_)[ __k >> CCN_LOG2_BITS_PER_UNIT] &= ~(CC_UNIT_C(1) << (__k & (CCN_UNIT_BITS - 1))); \
})
/* Macros for making ccn constants. You must use list of CCN64_C() instances
separated by commas, with an optional smaller sized CCN32_C, CCN16_C, or
CCN8_C() instance at the end of the list, when making macros to declare
larger sized constants. */
#define CCN8_C(a0) CC_UNIT_C(0x##a0)
#if CCN_UNIT_SIZE >= 2
#define CCN16_C(a1,a0) CC_UNIT_C(0x##a1##a0)
#define ccn16_v(a0) (a0)
#elif CCN_UNIT_SIZE == 1
#define CCN16_C(a1,a0) CCN8_C(a0),CCN8_C(a1)
#define ccn16_v(a0) (a0 & UINT8_C(0xff)),(a0 >> 8)
#endif
#if CCN_UNIT_SIZE >= 4
#define CCN32_C(a3,a2,a1,a0) CC_UNIT_C(0x##a3##a2##a1##a0)
#define ccn32_v(a0) (a0)
#else
#define CCN32_C(a3,a2,a1,a0) CCN16_C(a1,a0),CCN16_C(a3,a2)
#define ccn32_v(a0) ccn16_v(a0 & UINT16_C(0xffff)),ccn16_v(a0 >> 16)
#endif
#if CCN_UNIT_SIZE == 8
#define CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0) CC_UNIT_C(0x##a7##a6##a5##a4##a3##a2##a1##a0)
#define CCN40_C(a4,a3,a2,a1,a0) CC_UNIT_C(0x##a4##a3##a2##a1##a0)
#define ccn64_v(a0) (a0)
//#define ccn64_32(a1,a0) ((a1 << 32) | a0)
//#define ccn_uint64(a,i) (a[i])
#else
#define CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0) CCN32_C(a3,a2,a1,a0),CCN32_C(a7,a6,a5,a4)
#define CCN40_C(a4,a3,a2,a1,a0) CCN32_C(a3,a2,a1,a0),CCN8_C(a4)
#define ccn64_v(a0) ccn32_v((uint64_t)a0 & UINT32_C(0xffffffff)),ccn32_v((uint64_t)a0 >> 32)
//#define ccn64_32(a1,a0) ccn32_v(a0),ccn32_v(a1)
//#define ccn_uint64(a,i) ((uint64_t)ccn_uint32(a, i << 1 + 1) << 32 | (uint64_t)ccn_uint32(a, i << 1))
#endif
/* Macro's for reading uint32_t and uint64_t from ccns, the index is in 32 or
64 bit units respectively. */
#if CCN_UNIT_SIZE == 8
/* #define ccn_uint16(a,i) ((i & 3) == 3 ? ((uint16_t)(a[i >> 2] >> 48)) : \
(i & 3) == 2 ? ((uint16_t)(a[i >> 2] >> 32) & UINT16_C(0xffff)) : \
(i & 3) == 1 ? ((uint16_t)(a[i >> 2] >> 16) & UINT16_C(0xffff)) : \
((uint16_t)(a[i >> 1] & UINT16_C(0xffff))))
*/
//#define ccn_uint32(a,i) (i & 1 ? ((uint32_t)(a[i >> 1] >> 32)) : ((uint32_t)(a[i >> 1] & UINT32_C(0xffffffff))))
#elif CCN_UNIT_SIZE == 4
//#define ccn16_v(a0) (a0)
//#define ccn32_v(a0) (a0)
//#define ccn_uint16(a,i) (i & 1 ? ((uint16_t)(a[i >> 1] >> 16)) : ((uint16_t)(a[i >> 1] & UINT16_C(0xffff))))
//#define ccn_uint32(a,i) (a[i])
#elif CCN_UNIT_SIZE == 2
//#define ccn16_v(a0) (a0)
//#define ccn32_v(a0,a1) (a1,a0)
//#define ccn_uint16(a,i) (a[i])
//#define ccn_uint32(a,i) (((uint32_t)a[i << 1 + 1]) << 16 | (uint32_t)a[i << 1]))
#elif CCN_UNIT_SIZE == 1
//#define ccn16_v(a0) (a0 & UINT8_C(0xff)),(a0 >> 8)
//#define ccn_uint16(a,i) ((uint16_t)((a[i << 1 + 1] << 8) | a[i << 1]))
//#define ccn_uint32(a,i) ((uint32_t)ccn_uint16(a, i << 1 + 1) << 16 | (uint32_t)ccn_uint16(a, i << 1))
#endif
/* Macro's for reading uint32_t and uint64_t from ccns, the index is in 32 or
64 bit units respectively. */
#if CCN_UNIT_SIZE == 8
#define ccn64_32(a1,a0) (((const cc_unit)a1) << 32 | ((const cc_unit)a0))
#define ccn32_32(a0) a0
#if __LITTLE_ENDIAN__
#define ccn32_32_parse(p,i) (((const uint32_t *)p)[i])
#else
#define ccn32_32_parse(p,i) (((const uint32_t *)p)[i^1])
#endif
#define ccn32_32_null 0
#define ccn64_64(a0) a0
#define ccn64_64_parse(p,i) p[i]
#define ccn64_64_null 0
#elif CCN_UNIT_SIZE == 4
#define ccn32_32(a0) a0
#define ccn32_32_parse(p,i) p[i]
#define ccn32_32_null 0
#define ccn64_32(a1,a0) ccn32_32(a0),ccn32_32(a1)
#define ccn64_64(a1,a0) a0,a1
#define ccn64_64_parse(p,i) p[1+(i<<1)],p[i<<1]
#define ccn64_64_null 0,0
#elif CCN_UNIT_SIZE == 2
#define ccn32_32(a1,a0) a0,a1
#define ccn32_32_parse(p,i) p[1+(i<<1)],p[i<<1]
#define ccn32_32_null 0,0
#define ccn64_32(a3,a2,a1,a0) ccn32_32(a1,a0),ccn32_32(a3,a2)
#define ccn64_64(a3,a2,a1,a0) a0,a1,a2,a3
#define ccn64_64_parse(p,i) p[3+(i<<2)],p[2+(i<<2)],p[1+(i<<2)],p[i<<2]
#define ccn64_64_null 0,0,0,0
#elif CCN_UNIT_SIZE == 1
#define ccn32_32(a3,a2,a1,a0) a0,a1,a2,a3
#define ccn32_32_parse(p,i) p[3+(i<<2)],p[2+(i<<2)],p[1+(i<<2)],p[i<<2]
#define ccn32_32_null 0,0,0,0
#define ccn64_32(a7,a6,a5,a4,a3,a2,a1,a0) ccn32_32(a3,a2,a1,a0),ccn32_32(a7,a6,a5,a4)
#define ccn64_64(a7,a6,a5,a4,a3,a2,a1,a0) a0,a1,a2,a3,a4,a5,a6,a7
#define ccn64_64_parse(p,i) p[7+(i<<3)],p[6+(i<<3)],p[5+(i<<3)],p[4+(i<<3)],p[3+(i<<3)],p[2+(i<<3)],p[1+(i<<3)],p[i<<3]
#define ccn64_64_null 0,0,0,0,0,0,0,0
#endif
/* Macros to construct fixed size ccn arrays from 64 or 32 bit quantities. */
#define ccn192_64(a2,a1,a0) ccn64_64(a0),ccn64_64(a1),ccn64_64(a2)
#define ccn192_32(a5,a4,a3,a2,a1,a0) ccn64_32(a1,a0),ccn64_32(a3,a2),ccn64_32(a5,a4)
#define ccn224_32(a6,a5,a4,a3,a2,a1,a0) ccn64_32(a1,a0),ccn64_32(a3,a2),ccn64_32(a5,a4),ccn32_32(a6)
#define ccn256_32(a7,a6,a5,a4,a3,a2,a1,a0) ccn64_32(a1,a0),ccn64_32(a3,a2),ccn64_32(a5,a4),ccn64_32(a7,a6)
#define ccn384_32(a11,a10,a9,a8,a7,a6,a5,a4,a3,a2,a1,a0) ccn64_32(a1,a0),ccn64_32(a3,a2),ccn64_32(a5,a4),ccn64_32(a7,a6),ccn64_32(a9,a8),ccn64_32(a11,a10)
#define CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \
CCN64_C(a7,a6,a5,a4,a3,a2,a1,a0),\
CCN64_C(b7,b6,b5,b4,b3,b2,b1,b0),\
CCN64_C(c7,c6,c5,c4,c3,c2,c1,c0)
#define CCN200_C(d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \
CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\
CCN8_C(d0)
#define CCN224_C(d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \
CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\
CCN32_C(d3,d2,d1,d0)
#define CCN232_C(d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \
CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\
CCN40_C(d4,d3,d2,d1,d0)
#define CCN256_C(d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \
CCN192_C(c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\
CCN64_C(d7,d6,d5,d4,d3,d2,d1,d0)
#define CCN384_C(f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0,d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \
CCN256_C(d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\
CCN64_C(e7,e6,e5,e4,e3,e2,e1,e0),\
CCN64_C(f7,f6,f5,f4,f3,f2,f1,f0)
#define CCN528_C(i1,i0,h7,h6,h5,h4,h3,h2,h1,h0,g7,g6,g5,g4,g3,g2,g1,g0,f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0,d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0) \
CCN256_C(d7,d6,d5,d4,d3,d2,d1,d0,c7,c6,c5,c4,c3,c2,c1,c0,b7,b6,b5,b4,b3,b2,b1,b0,a7,a6,a5,a4,a3,a2,a1,a0),\
CCN256_C(h7,h6,h5,h4,h3,h2,h1,h0,g7,g6,g5,g4,g3,g2,g1,g0,f7,f6,f5,f4,f3,f2,f1,f0,e7,e6,e5,e4,e3,e2,e1,e0),\
CCN16_C(i1,i0)
#define CCN192_N ccn_nof(192)
#define CCN224_N ccn_nof(224)
#define CCN256_N ccn_nof(256)
#define CCN384_N ccn_nof(384)
#define CCN512_N ccn_nof(512)
#define CCN521_N ccn_nof(521)
/* Return the number of used units after stripping leading 0 units. */
CC_PURE CC_NONNULL((2))
cc_size ccn_n(cc_size n, const cc_unit *s) __asm__("_ccn_n");
/* s >> k -> r return bits shifted out of least significant word in the higest order bits of
the retuned value. For example if CCN_UNIT_SIZE == 1, then (0b1101 1110)>>4 returns (0b1110 0000)
and sets r==(0b0000 1101).
{ N bit, scalar -> N bit } N = n * sizeof(cc_unit) * 8
the _multi version doesn't return the shifted bits, but does support multiple
word shifts. */
CC_NONNULL((2, 3))
cc_unit ccn_shift_right(cc_size n, cc_unit *r, const cc_unit *s, size_t k) __asm__("_ccn_shift_right");
/* s == 0 -> return 0 | s > 0 -> return index (starting at 1) of most
* significant bit that is 1.
* { N bit } N = n * sizeof(cc_unit) * 8
*
* Runs in constant time, independent of the value of `s`.
*/
CC_NONNULL((2))
size_t ccn_bitlen(cc_size n, const cc_unit *s);
/* s == 0 -> return true | s != 0 -> return false
{ N bit } N = n * sizeof(cc_unit) * 8 */
#define ccn_is_zero(_n_, _s_) (!ccn_n(_n_, _s_))
/* s == 1 -> return true | s != 1 -> return false
{ N bit } N = n * sizeof(cc_unit) * 8 */
#define ccn_is_one(_n_, _s_) (ccn_n(_n_, _s_) == 1 && _s_[0] == 1)
#define ccn_is_zero_or_one(_n_, _s_) (((_n_)==0) || ((ccn_n(_n_, _s_) <= 1) && (_s_[0] <= 1)))
/* s < t -> return - 1 | s == t -> return 0 | s > t -> return 1
{ N bit, N bit -> int } N = n * sizeof(cc_unit) * 8 */
CC_PURE CC_NONNULL((2, 3))
int ccn_cmp(cc_size n, const cc_unit *s, const cc_unit *t) __asm__("_ccn_cmp");
/*! @function ccn_cmpn
@abstract Compares the values of two big ints of different lengths.
@discussion The execution time does not depend on the values of either s or t.
The function does not hide ns, nt, or whether ns > nt.
@param ns Length of s
@param s First integer
@param nt Length of t
@param t Second integer
@return 1 if s > t, -1 if s < t, 0 otherwise.
*/
CC_NONNULL_ALL
int ccn_cmpn(cc_size ns, const cc_unit *s, cc_size nt, const cc_unit *t);
/* s - t -> r return 1 iff t > s
{ N bit, N bit -> N bit } N = n * sizeof(cc_unit) * 8 */
CC_NONNULL((2, 3, 4))
cc_unit ccn_sub(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t) __asm__("_ccn_sub");
/* s - v -> r return 1 iff v > s return 0 otherwise.
{ N bit, sizeof(cc_unit) * 8 bit -> N bit } N = n * sizeof(cc_unit) * 8 */
CC_NONNULL((2, 3))
cc_unit ccn_sub1(cc_size n, cc_unit *r, const cc_unit *s, cc_unit v);
/* s - t -> r return 1 iff t > s
{ N bit, NT bit -> N bit NT <= N} N = n * sizeof(cc_unit) * 8 */
CC_INLINE
CC_NONNULL((2, 3, 5))
cc_unit ccn_subn(cc_size n, cc_unit *r, const cc_unit *s,
cc_size nt, const cc_unit *t) {
assert(n >= nt);
return ccn_sub1(n - nt, r + nt, s + nt, ccn_sub(nt, r, s, t));
}
/* s + t -> r return carry if result doesn't fit in n bits.
{ N bit, N bit -> N bit } N = n * sizeof(cc_unit) * 8 */
CC_NONNULL((2, 3, 4))
cc_unit ccn_add(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t) __asm__("_ccn_add");
/* s + v -> r return carry if result doesn't fit in n bits.
{ N bit, sizeof(cc_unit) * 8 bit -> N bit } N = n * sizeof(cc_unit) * 8 */
CC_NONNULL((2, 3))
cc_unit ccn_add1(cc_size n, cc_unit *r, const cc_unit *s, cc_unit v);
/* s + t -> r return carry if result doesn't fit in n bits
{ N bit, NT bit -> N bit NT <= N} N = n * sizeof(cc_unit) * 8 */
CC_INLINE
CC_NONNULL((2, 3, 5))
cc_unit ccn_addn(cc_size n, cc_unit *r, const cc_unit *s,
cc_size nt, const cc_unit *t) {
assert(n >= nt);
return ccn_add1(n - nt, r + nt, s + nt, ccn_add(nt, r, s, t));
}
/* s * t -> r_2n r_2n must not overlap with s nor t
{ n bit, n bit -> 2 * n bit } n = count * sizeof(cc_unit) * 8
{ N bit, N bit -> 2N bit } N = ccn_bitsof(n) */
CC_NONNULL((2, 3, 4))
void ccn_mul(cc_size n, cc_unit *r_2n, const cc_unit *s, const cc_unit *t) __asm__("_ccn_mul");
/* s[0..n) * v -> r[0..n)+return value
{ N bit, sizeof(cc_unit) * 8 bit -> N + sizeof(cc_unit) * 8 bit } N = n * sizeof(cc_unit) * 8 */
CC_NONNULL((2, 3))
cc_unit ccn_mul1(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit v);
/* s[0..n) * v + r[0..n) -> r[0..n)+return value
{ N bit, sizeof(cc_unit) * 8 bit -> N + sizeof(cc_unit) * 8 bit } N = n * sizeof(cc_unit) * 8 */
CC_NONNULL((2, 3))
cc_unit ccn_addmul1(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit v);
/*!
@function ccn_read_uint
@abstract Copy big endian integer and represent it in cc_units
@param n Input allocated size of the cc_unit output array r
@param r Ouput cc_unit array for unsigned integer
@param data_nbytes Input byte size of data
@param data Input unsigned integer represented in big endian
@result r is initialized with the big unsigned number
@return 0 if no error, !=0 if the big number cannot be represented in the allocated cc_unit array.
@discussion The execution pattern of this function depends on both n and data_nbytes but not on data values except the handling
of the error case.
*/
CC_NONNULL((2, 4))
int ccn_read_uint(cc_size n, cc_unit *r, size_t data_nbytes, const uint8_t *data);
/* r = (data, len) treated as a big endian byte array, return -1 if data
doesn't fit in r, return 0 otherwise.
ccn_read_uint strips leading zeroes and doesn't care about sign. */
#define ccn_read_int(n, r, data_size, data) ccn_read_uint(n, r, data_size, data)
/*!
@function ccn_write_uint_size
@abstract Compute the minimum size required to store an big integer
@param n Input size of the cc_unit array representing the input
@param s Input cc_unit array
@result Return value is the exact byte size of the big integer
@discussion
The execution flow is independent on the value of the big integer.
However, the use of the returned value may leak the position of the most significant byte
*/
CC_PURE CC_NONNULL((2)) size_t ccn_write_uint_size(cc_size n, const cc_unit *s);
/*!
@function ccn_write_uint
@abstract Serialize the big integer into a big endian byte buffer
@param n Input size of the cc_unit array representing the input
@param s Input cc_unit array
@param out_size Size of the output buffer
@param out Output byte array of size at least out_size
@discussion This function writes exactly
MIN(out_size,ccn_write_uint_size(n,s)) bytes truncating to keep the
most significant bytes when out_size<ccn_write_uint_size(n,s). The
execution flow of function is based on the position of the most
significant byte as well as input sizes.
*/
CC_NONNULL((2, 4))
void ccn_write_uint(cc_size n, const cc_unit *s, size_t out_size, void *out);
/*!
@function ccn_write_uint_padded_ct
@abstract Serialize the big integer into a big endian byte buffer
@param n Input size of the cc_unit array representing the input
@param s Input cc_unit array
@param out_size Size of the output buffer
@param out Output byte array of size at least out_size
@return number of leading zero bytes in case of success, a negative error value in case of failure
@result This function writes exactly out_size byte, padding with zeroes when necessary.
This function DOES NOT support truncation and returns an error if out_size < ccn_write_uint_size
@discussion The execution flow of function is independent on the value of the big integer
However, the processing of the return value by the caller may expose the position of
the most significant byte
*/
CC_NONNULL((2, 4))
int ccn_write_uint_padded_ct(cc_size n, const cc_unit *s, size_t out_size, uint8_t *out);
/*!
@function ccn_write_uint_padded
@abstract Serialize the big integer into a big endian byte buffer
Not recommended, for most cases ccn_write_uint_padded_ct is more appropriate
Sensitive big integers are exposed since the processing expose the position of the MS byte
@param n Input size of the cc_unit array representing the input
@param s Input cc_unit array
@param out_size Size of the output buffer
@param out Output byte array of size at least out_size
@return number of leading zero bytes
@result This function writes exactly out_size byte, padding with zeroes when necessary.
This function DOES support truncation when out_size<ccn_write_uint_size()
@discussion The execution flow of this function DEPENDS on the position of the most significant byte in
case truncation is required.
*/
CC_INLINE CC_NONNULL((2, 4)) size_t ccn_write_uint_padded(cc_size n, const cc_unit *s, size_t out_size, uint8_t *out)
{
size_t offset = 0;
// Try first the non-truncation case
int offset_int = ccn_write_uint_padded_ct(n, s, out_size, out);
if (offset_int >= 0) {
// It worked
offset = (size_t)offset_int;
} else {
// Truncation case, execution depends on the position of the MSByte
ccn_write_uint(n, s, out_size, out);
}
return offset;
}
/* Return actual size in bytes needed to serialize s as int
(adding leading zero if high bit is set). */
CC_PURE CC_NONNULL((2))
size_t ccn_write_int_size(cc_size n, const cc_unit *s);
/* Serialize s, to out.
First byte of byte stream is the m.s. byte of s,
regardless of the size of cc_unit.
No assumption is made about the alignment of out.
The out_size argument should be the value returned from ccn_write_int_size,
and is also the exact number of bytes this function will write to out.
If out_size if less than the value returned by ccn_write_int_size, only the
first out_size non-zero most significant octets of s will be written. */
CC_NONNULL((2, 4))
void ccn_write_int(cc_size n, const cc_unit *s, size_t out_size, void *out);
/* s -> r
{ n bit -> n bit } */
CC_NONNULL((2, 3))
void ccn_set(cc_size n, cc_unit *r, const cc_unit *s);
CC_INLINE CC_NONNULL((2))
void ccn_zero(cc_size n, cc_unit *r) {
cc_clear(ccn_sizeof_n(n),r);
}
CC_INLINE CC_NONNULL((2))
void ccn_clear(cc_size n, cc_unit *r) {
cc_clear(ccn_sizeof_n(n),r);
}
CC_NONNULL((2))
void ccn_zero_multi(cc_size n, cc_unit *r, ...);
CC_INLINE CC_NONNULL((2))
void ccn_seti(cc_size n, cc_unit *r, cc_unit v) {
assert(n > 0);
r[0] = v;
ccn_zero(n - 1, r + 1);
}
CC_INLINE CC_NONNULL((2, 4))
void ccn_setn(cc_size n, cc_unit *r, const cc_size s_size, const cc_unit *s) {
assert(n > 0);
assert(s_size > 0);
assert(s_size <= n);
ccn_set(s_size, r, s);
ccn_zero(n - s_size, r + s_size);
}
#define CC_SWAP_HOST_BIG_64(x) \
((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \
(((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \
(((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \
(((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \
(((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \
(((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \
(((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \
(((uint64_t)(x) & 0x00000000000000ffULL) << 56)))
#define CC_SWAP_HOST_BIG_32(x) \
((((x) & 0xff000000) >> 24) | \
(((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x000000ff) << 24))
#define CC_SWAP_HOST_BIG_16(x) \
((((x) & 0xff00) >> 8) | \
(((x) & 0x00ff) << 8))
/* This should probably move if we move ccn_swap out of line. */
#if CCN_UNIT_SIZE == 8
#define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_64(x)
#elif CCN_UNIT_SIZE == 4
#define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_32(x)
#elif CCN_UNIT_SIZE == 2
#define CC_UNIT_TO_BIG(x) CC_SWAP_HOST_BIG_16(x)
#elif CCN_UNIT_SIZE == 1
#define CC_UNIT_TO_BIG(x) (x)
#else
#error unsupported CCN_UNIT_SIZE
#endif
/* Swap units in r in place from cc_unit vector byte order to big endian byte order (or back). */
CC_INLINE CC_NONNULL((2))
void ccn_swap(cc_size n, cc_unit *r) {
cc_unit *e;
for (e = r + n - 1; r < e; ++r, --e) {
cc_unit t = CC_UNIT_TO_BIG(*r);
*r = CC_UNIT_TO_BIG(*e);
*e = t;
}
if (n & 1)
*r = CC_UNIT_TO_BIG(*r);
}
CC_INLINE CC_NONNULL((2, 3, 4))
void ccn_xor(cc_size n, cc_unit *r, const cc_unit *s, const cc_unit *t) {
while (n--) {
r[n] = s[n] ^ t[n];
}
}
/* Debugging */
CC_NONNULL((2))
void ccn_print(cc_size n, const cc_unit *s);
CC_NONNULL((3))
void ccn_lprint(cc_size n, const char *label, const cc_unit *s);
/* Forward declaration so we don't depend on ccrng.h. */
struct ccrng_state;
#if 0
CC_INLINE CC_NONNULL((2, 3))
int ccn_random(cc_size n, cc_unit *r, struct ccrng_state *rng) {
return (RNG)->generate((RNG), ccn_sizeof_n(n), (unsigned char *)r);
}
#else
#define ccn_random(_n_,_r_,_ccrng_ctx_) \
ccrng_generate(_ccrng_ctx_, ccn_sizeof_n(_n_), (unsigned char *)_r_)
#endif
/* Make a ccn of size ccn_nof(nbits) units with up to nbits sized random value. */
CC_NONNULL((2, 3))
int ccn_random_bits(cc_size nbits, cc_unit *r, struct ccrng_state *rng);
CC_NONNULL((6, 8))
int ccn_div_euclid(cc_size nq, cc_unit *q, cc_size nr, cc_unit *r, cc_size na, const cc_unit *a, cc_size nd, const cc_unit *d);
#define ccn_div(nq, q, na, a, nd, d) ccn_div_euclid(nq, q, 0, NULL, na, a, nd, d)
#define ccn_mod(nr, r, na, a, nd, d) ccn_div_euclid(0 , NULL, nr, r, na, a, nd, d)
#endif /* _CORECRYPTO_CCN_H_ */

View File

@ -0,0 +1,74 @@
/* Copyright (c) (2010,2011,2012,2014,2015,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCPAD_H_
#define _CORECRYPTO_CCPAD_H_
#include <corecrypto/ccmode.h>
// CTS1,2,3 are defined in Addendum to 800-38A,
// "Cipher Modes of Operation: Three Variants of Ciphertext Stealing for CBC Mode"
// CTS3 is also known as "CTS" in RFC3962
/* Contract is nbytes is at least 1 block + 1 byte. Also in is nbytes long out is nbytes long. */
size_t ccpad_cts1_decrypt(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, cccbc_iv *iv,
size_t nbytes, const void *in, void *out);
/* Contract is nbytes is at least 1 block + 1 byte. Also in is nbytes long out is nbytes long. */
size_t ccpad_cts1_encrypt(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, cccbc_iv *iv,
size_t nbytes, const void *in, void *out);
/* Contract is nbytes is at least 1 block + 1 byte. Also in is nbytes long out is nbytes long. */
size_t ccpad_cts2_decrypt(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, cccbc_iv *iv,
size_t nbytes, const void *in, void *out);
/* Contract is nbytes is at least 1 block + 1 byte. Also in is nbytes long out is nbytes long. */
size_t ccpad_cts2_encrypt(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, cccbc_iv *iv,
size_t nbytes, const void *in, void *out);
/* Contract is nbytes is at least 1 block + 1 byte. Also in is nbytes long out is nbytes long. */
size_t ccpad_cts3_decrypt(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, cccbc_iv *iv,
size_t nbytes, const void *in, void *out);
/* Contract is nbytes is at least 1 block + 1 byte. Also in is nbytes long out is nbytes long. */
size_t ccpad_cts3_encrypt(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, cccbc_iv *iv,
size_t nbytes, const void *in, void *out);
/* Contract is nbytes is non zero and a multiple of block_size. Furthermore in is nbytes long and out is nbytes long. Returns number of bytes written to out (technically we always write nbytes to out but the returned value is the number of bytes decrypted after removal of padding.
To be safe we remove the entire offending block if the pkcs7 padding checks failed. However we purposely don't report the failure to decode the padding since any use of this error leads to potential security exploits. So currently there is no way to distinguish between a full block of padding and bad padding.
*/
size_t ccpad_pkcs7_decrypt(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, cccbc_iv *iv,
size_t nbytes, const void *in, void *out);
/* Contract is in is nbytes long. Writes (nbytes / block_size) + 1 times block_size to out. In other words, out must be nbytes rounded down to the closest multiple of block_size plus block_size bytes. */
size_t ccpad_pkcs7_encrypt(const struct ccmode_cbc *cbc, cccbc_ctx *ctx, cccbc_iv *iv,
size_t nbytes, const void *in, void *out);
/* Contract is 'don't break CommonCrypto functionality that allows PKCS7 padding with ECB mode'. This is basically the same routines above, without an IV, because calling
crypt with an IV makes ecb cry (and crash) */
size_t ccpad_pkcs7_ecb_decrypt(const struct ccmode_ecb *ecb, ccecb_ctx *ecb_key,
size_t nbytes, const void *in, void *out);
size_t ccpad_pkcs7_ecb_encrypt(const struct ccmode_ecb *ecb, ccecb_ctx *ctx,
size_t nbytes, const void *in, void *out);
/* Function common to ccpad_pkcs7_ecb_decrypt and ccpad_pkcs7_decrypt */
size_t ccpad_pkcs7_decode(const size_t block_size, const uint8_t* last_block);
/* Contract is nbytes is at least 1 block + 1 byte. Also in is nbytes long out is nbytes long. */
size_t ccpad_xts_decrypt(const struct ccmode_xts *xts, ccxts_ctx *ctx, ccxts_tweak *tweak,
size_t nbytes, const void *in, void *out);
/* Contract is nbytes is at least 1 block + 1 byte. Also in is nbytes long out is nbytes long. */
void ccpad_xts_encrypt(const struct ccmode_xts *xts, ccxts_ctx *ctx, ccxts_tweak *tweak,
size_t nbytes, const void *in, void *out);
#endif /* _CORECRYPTO_CCPAD_H_ */

View File

@ -0,0 +1,74 @@
/* Copyright (c) (2010,2011,2012,2013,2014,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCRNG_H_
#define _CORECRYPTO_CCRNG_H_
#include <corecrypto/cc.h>
#define CCRNG_STATE_COMMON \
int (*CC_SPTR(ccrng_state, generate))(struct ccrng_state *rng, size_t outlen, void *out);
/*!
@type struct ccrng_state
@abstract Default state structure. Do not instantiate. ccrng() returns a reference to this structure
*/
struct ccrng_state {
CCRNG_STATE_COMMON
};
/*!
@function ccrng
@abstract Initializes an AES-CTR mode cryptographic random number generator and returns the statically-allocated rng object.
Getting a pointer to a ccrng has never been simpler!
Call this function, get an rng object and then pass the object to ccrng_generate() to generate randoms.
ccrng() may be called more than once. It returns pointer to the same object on all calls.
@result a cryptographically secure random number generator or NULL if fails
@discussion
- It is significantly faster than using the system /dev/random
- FIPS Compliant: NIST SP800-90A + FIPS 140-2
- Seeded from the system entropy.
- Provides at least 128bit security if the system provide 2bit of entropy / byte.
- Entropy accumulation
- Backtracing resistance
- Prediction break with frequent (asynchronous) reseed
*/
struct ccrng_state *ccrng(int *error);
/*!
@function ccrng_generate
@abstract Generate `outlen` bytes of output, stored in `out`, using ccrng_state `rng`.
@param rng `struct ccrng_state` representing the state of the RNG.
@param outlen Amount of random bytes to generate.
@param out Pointer to memory where random bytes are stored, of size at least `outlen`.
@result 0 on success and nonzero on failure.
*/
#define ccrng_generate(rng, outlen, out) \
((rng)->generate((struct ccrng_state *)(rng), (outlen), (out)))
/*!
@function ccrng_uniform
@abstract Generate a random value in @p [0, bound).
@param rng The state of the RNG.
@param bound The exclusive upper bound on the output.
@param rand A pointer to a single @p uint64_t to store the result.
@result Returns zero iff the operation is successful.
*/
int ccrng_uniform(struct ccrng_state *rng, uint64_t bound, uint64_t *rand);
#endif /* _CORECRYPTO_CCRNG_H_ */

View File

@ -0,0 +1,908 @@
/* Copyright (c) (2010,2011,2012,2014,2015,2016,2017,2018,2019,2020) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCRSA_H_
#define _CORECRYPTO_CCRSA_H_
#include <corecrypto/cc.h>
#include <corecrypto/ccdigest.h>
#include <corecrypto/ccrng.h>
#include <corecrypto/cczp.h>
#include <corecrypto/cc_fault_canary.h>
#include <stdbool.h>
// Apple does not generate keys of greater than 4096 bits
// This limit is relaxed to accommodate potential third-party consumers
#define CCRSA_KEYGEN_MAX_NBITS 8192
struct ccrsa_full_ctx {
__CCZP_ELEMENTS_DEFINITIONS(pb_)
} CC_ALIGNED(CCN_UNIT_SIZE);
struct ccrsa_pub_ctx {
__CCZP_ELEMENTS_DEFINITIONS(pb_)
} CC_ALIGNED(CCN_UNIT_SIZE);
struct ccrsa_priv_ctx {
__CCZP_ELEMENTS_DEFINITIONS(pv_)
} CC_ALIGNED(CCN_UNIT_SIZE);
typedef struct ccrsa_full_ctx* ccrsa_full_ctx_t;
typedef struct ccrsa_pub_ctx* ccrsa_pub_ctx_t;
typedef struct ccrsa_priv_ctx* ccrsa_priv_ctx_t;
/*
public key cczp d=e^-1 mod lambda(m) priv key cczp priv key cczq dp, dq, qinv
| | | | |
| | | | |
+-------+------+-------+------++------++-------+------+---------++-------+------+---------++-------+-------+---------+
| zm_hd | m[n] |mr[n+1]| e[n] || d[n] || zp_hd |p[n/2]|pr[n/2+1]|| zq_hd |q[n/2]|qr[n/2+1]||dp[n/2]|dq[n/2]|qinv[n/2]|
+-------+------+-------+------++------++-------+------+---------++-------+------+---------++-------+-------+---------+
*/
/* Return the size of an ccec_full_ctx where each ccn is _size_ bytes. Get _size_ through ccn_sizeof(nbits) */
/* Return the size of an ccec_full_ctx where each ccn is _size_ bytes. */
#define ccrsa_pub_ctx_size(_size_) (sizeof(struct cczp) + CCN_UNIT_SIZE + 3 * (_size_))
#define ccrsa_priv_ctx_size(_size_) ((sizeof(struct cczp) + CCN_UNIT_SIZE) * 2 + 7 * ccn_sizeof(ccn_bitsof_size(_size_)/2 + 1))
#define ccrsa_full_ctx_size(_size_) (ccrsa_pub_ctx_size(_size_) + _size_ + ccrsa_priv_ctx_size(_size_))
/* Declare a fully scheduled rsa key. Size is the size in bytes each ccn in
the key. For example to declare (on the stack or in a struct) a 1021 bit
rsa public key named foo use ccrsa_pub_ctx_decl(ccn_sizeof(1021), foo).
*/
#define ccrsa_full_ctx_decl(_size_, _name_) cc_ctx_decl(struct ccrsa_full_ctx, ccrsa_full_ctx_size(_size_), _name_)
#define ccrsa_full_ctx_clear(_size_, _name_) cc_clear(ccrsa_full_ctx_size(_size_), _name_)
#define ccrsa_pub_ctx_decl(_size_, _name_) cc_ctx_decl(struct ccrsa_pub_ctx, ccrsa_pub_ctx_size(_size_), _name_)
#define ccrsa_pub_ctx_clear(_size_, _name_) cc_clear(ccrsa_pub_ctx_size(_size_), _name_)
// accessors to ccrsa full and public key fields. */
// The offsets are computed using pb_ccn. If any object other than ccrsa_full_ctx_t
// or ccrsa_pub_ctx_t is passed to the macros, compiler error is generated.
#define ccrsa_ctx_zm(_ctx_) ((cczp_t)(_ctx_))
#define ccrsa_ctx_n(_ctx_) (ccrsa_ctx_zm(_ctx_)->n)
#define ccrsa_ctx_m(_ctx_) ((_ctx_)->pb_ccn)
#define ccrsa_ctx_e(_ctx_) (ccrsa_ctx_m(_ctx_) + 2 * ccrsa_ctx_n(_ctx_) + 1)
#define ccrsa_ctx_d(_ctx_) (ccrsa_ctx_m(_ctx_) + 3 * ccrsa_ctx_n(_ctx_) + 1)
// accessors to ccrsa private key fields
// The offsets are computed using pv_ccn. If any object other than ccrsa_priv_ctx_t
// is passed to the macros, compiler error is generated.
#define ccrsa_ctx_private_zp(FK) ((cczp_t)ccrsa_get_private_ctx_ptr(FK))
#define ccrsa_ctx_private_zq(FK) ((cczp_t)((ccrsa_get_private_ctx_ptr(FK))->pv_ccn + 2 * ccrsa_ctx_private_zp(FK)->n + 1))
#define ccrsa_ctx_private_dp(FK) ((ccrsa_get_private_ctx_ptr(FK))->pv_ccn + 4 * ccrsa_ctx_private_zp(FK)->n + 2 + ccn_nof_size(sizeof(struct cczp)))
#define ccrsa_ctx_private_dq(FK) ((ccrsa_get_private_ctx_ptr(FK))->pv_ccn + 5 * ccrsa_ctx_private_zp(FK)->n + 2 + ccn_nof_size(sizeof(struct cczp)))
#define ccrsa_ctx_private_qinv(FK) ((ccrsa_get_private_ctx_ptr(FK))->pv_ccn + 6 * ccrsa_ctx_private_zp(FK)->n + 2 + ccn_nof_size(sizeof(struct cczp)))
/* rvalue accessors to ccec_key fields. */
CC_INLINE
ccrsa_priv_ctx_t ccrsa_get_private_ctx_ptr(ccrsa_full_ctx_t fk) {
ccrsa_priv_ctx_t priv = (ccrsa_priv_ctx_t)(ccrsa_ctx_d(fk)+ccrsa_ctx_n(fk));
return priv;
}
/*!
@function ccrsa_ctx_public
@abstract gets the public key from full key
@param fk RSA full key
@result Returns RSA public ker
*/
CC_INLINE
ccrsa_pub_ctx_t ccrsa_ctx_public(ccrsa_full_ctx_t fk) {
return (ccrsa_pub_ctx_t) fk;
}
/*!
@function ccrsa_pubkeylength
@abstract Compute the actual bit length of the RSA key (bit length of the modulus)
@param pubk An initialized RSA public key
@result bit length of the RSA key
*/
CC_NONNULL_ALL
size_t ccrsa_pubkeylength(ccrsa_pub_ctx_t pubk);
/* PKCS1 pad_markers */
#define CCRSA_PKCS1_PAD_SIGN 1
#define CCRSA_PKCS1_PAD_ENCRYPT 2
/*!
@function ccrsa_init_pub
@abstract Initialize an RSA public key structure based on modulus and exponent. Values are copied into the structure.
@param pubk allocated public key structure (see requirements below)
@param modulus cc_unit array of the modulus
@param exponent cc_unit array of the exponent
@result CCERR_OK if no error
@discussion ccrsa_ctx_n(pubk) must have been initialized based on the modulus size, typically using ccn_nof_size(mod_nbytes).
The public key structure pubk is typically allocated with ccrsa_pub_ctx_decl(ccn_sizeof_size(mod_nbytes), pubk);
*/
CC_NONNULL_ALL
int ccrsa_init_pub(ccrsa_pub_ctx_t pubk, const cc_unit *modulus,
const cc_unit *exponent);
/*! @function ccrsa_make_priv
@abstract Initializes an RSA public and private key given the public
exponent e and prime factors p and q.
@param full_ctx Initialized context with ccrsa_ctx_n(full_ctx) set to 2*ccn_nof_size(p_nbytes)
@param e_nbytes Number of bytes of public exponent e.
@param e_bytes Public exponent e in Big Endian.
@param p_nbytes Number of bytes of prime factor p.
@param p_bytes Prime factor p in Big Endian.
@param q_nbytes Number of bytes of prime factor q.
@param q_bytes Prime factor q in Big Endian.
@return 0 iff successful.
@discussion ccrsa_ctx_n(full_ctx) must already be set to 2*ccn_nof_size(p_mbytes), with the expectation that p_nbytes>q_nbytes.
e is the public exponent, and e_nbytes<= 2*p_nbytes.
The output is a fully formed RSA context with N=pq, d=e^{-1} mod lambda(N), and appropriate inverses of different associated values precomputed
to speed computation.
*/
int ccrsa_make_priv(ccrsa_full_ctx_t full_ctx,
size_t e_nbytes, const uint8_t *e_bytes,
size_t p_nbytes, const uint8_t *p_bytes,
size_t q_nbytes, const uint8_t *q_bytes);
/*! @function ccrsa_recover_priv
@abstract Initializes an RSA public and private key given the modulus m,
the public exponent e and the private exponent d.
@discussion Follows the algorithm described by
NIST SP 800-56B, Appendix C, "Prime Factory Recovery".
@param full_ctx Initialized context with ccrsa_ctx_n(full_ctx) set to ccn_nof_size(m_nbytes)
@param m_nbytes Number of bytes of modulus m.
@param m_bytes Modulus m in Big Endian.
@param e_nbytes Number of bytes of public exponent e.
@param e_bytes Public exponent e in Big Endian.
@param d_nbytes Number of bytes of private exponent d.
@param d_bytes Private exponent d in Big Endian.
@param rng RNG instance.
@return 0 iff successful.
*/
int ccrsa_recover_priv(ccrsa_full_ctx_t full_ctx,
size_t m_nbytes, const uint8_t *m_bytes,
size_t e_nbytes, const uint8_t *e_bytes,
size_t d_nbytes, const uint8_t *d_bytes,
struct ccrng_state *rng);
/*!
@function ccrsa_make_pub
@abstract Initialize public key based on modulus and public exponent as big endian byte arrays;
@param pubk allocated public key structure (see requirements below)
@param exp_nbytes Number of bytes in big endian exponent.
@param exp Pointer to big endian exponent e (may have leading 0's).
@param mod_nbytes Number of bytes in big endian modulus.
@param mod Pointer to big endian to rsa modulus N.
@result 0 iff successful.
@discussion ccrsa_ctx_n(pubk) must have been initialized based on the modulus size, typically using ccn_nof_size(mod_nbytes).
The public key structure pubk is typically allocated with ccrsa_pub_ctx_decl(ccn_sizeof_size(mod_nbytes), pubk);
*/
CC_NONNULL((1, 3, 5))
int ccrsa_make_pub(ccrsa_pub_ctx_t pubk,
size_t exp_nbytes, const uint8_t *exp,
size_t mod_nbytes, const uint8_t *mod);
/*!
@function ccrsa_pub_crypt
@abstract Perform an RSA public key operation: (in)^e mod m
@param key initialized public key defining e and m
@param out result of the operation, at least ccrsa_key_n(key) cc_units must have been allocated
@param in base of the exponentiation, of size ccrsa_key_n(key)
@result CCERR_OK if no error
@discussion Input to this function must not be secrets as the execution flow may expose their values
Clients can use ccn_read_uint() to convert bytes to cc_units to use for this API.
*/
CC_NONNULL((1, 2, 3))
int ccrsa_pub_crypt(ccrsa_pub_ctx_t key, cc_unit *out, const cc_unit *in);
/*!
@function ccrsa_generate_key
@abstract Generate a nbit RSA key pair.
@param nbits Bit size requested for the key
@param fk Allocated context where the generated key will be stored
@param e_nbytes Byte size of the input public exponent
@param e_bytes Input public exponent in big endian. Recommend value is {0x01, 0x00, 0x01}
@param rng Random Number generator used.
@result CCERR_OK if no error
@discussion
fk should be allocated using ccrsa_full_ctx_decl(ccn_sizeof(nbits), fk).
The unsigned big endian byte array exponent e of length e_size is used as the exponent. It's an error to call this function with an exponent larger than nbits
*/
CC_NONNULL_ALL
int ccrsa_generate_key(size_t nbits, ccrsa_full_ctx_t fk,
size_t e_nbytes, const void *e_bytes, struct ccrng_state *rng) CC_WARN_RESULT;
/*!
@function ccrsa_generate_fips186_key
@abstract Generate a nbit RSA key pair in conformance with FIPS186-4 standard.
@param nbits Bit size requested for the key
@param fk Allocated context where the generated key will be stored
@param e_nbytes Byte size of the input public exponent
@param e_bytes Input public exponent in big endian. Recommend value is {0x01, 0x00, 0x01}
@param rng Random Number generator used for p and q
@param rng_mr Random Number generator only used for the primality check
@result CCERR_OK if no error
@discussion
fk should be allocated using ccrsa_full_ctx_decl(ccn_sizeof(nbits), fk).
rng and rng_mr shoud be set to the same value. The distinction is only relevant for testing
*/
CC_NONNULL_ALL int
ccrsa_generate_fips186_key(size_t nbits, ccrsa_full_ctx_t fk,
size_t e_nbytes, const void *e_bytes,
struct ccrng_state *rng, struct ccrng_state *rng_mr) CC_WARN_RESULT;
/* Construct RSA key from fix input in conformance with FIPS186-4 standard */
/*!
@function ccrsa_make_fips186_key
@abstract Initialize an RSA full key from explicit inputs necessary for validating conformance to FIPS186-4
@param nbits size in bits of the key to construct
@param e_n Size in cc_unit of the public exponent
@param e Public exponent represented in cc_units
@param xp1_nbytes Size in byte of the first seed for the construction of p
@param xp1 First seed for the construction of p
@param xp2_nbytes Size in byte of the second seed for the construction of p
@param xp2 Second seed for the construction of p
@param xp_nbytes Size in byte of the large seed for the construction of p
@param xp large seed for the construction of p
@param xq1_nbytes Size in byte of the first seed for the construction of q
@param xq1 First seed for the construction of q
@param xq2_nbytes Size in byte of the second seed for the construction of q
@param xq2 Second seed for the construction of q
@param xq_nbytes Size in byte of the large seed for the construction of q
@param xq large seed for the construction of q
@param fk Allocated context where the output constructed key is stored
@param np Pointer to the size in cc_unit of the buffer for the output prime factor p. Updated with actual size.
@param r_p Copy of the output prime factor p
@param nq Pointer to the size in cc_unit of the buffer for the output prime factor q. Updated with actual size.
@param r_q Copy of the output prime factor q
@param nm Pointer to the size in cc_unit of the buffer for the output modulus m=p*q. Updated with actual size.
@param r_m Copy of the output modulus m=p*q
@param nd Pointer to the size in cc_unit of the buffer for the output private exponent d. Updated with actual size.
@param r_d Copy of the output private exponent d
@result 0 iff successful.
@discussion
fk should be allocated using ccrsa_full_ctx_decl(ccn_sizeof(nbits), fk).
*/
CC_NONNULL((3, 5, 7, 9, 11, 13, 15, 16))
int
ccrsa_make_fips186_key(size_t nbits,
const cc_size e_n, const cc_unit *e,
const cc_size xp1_nbytes, const cc_unit *xp1, const cc_size xp2_nbytes, const cc_unit *xp2,
const cc_size xp_nbytes, const cc_unit *xp,
const cc_size xq1_nbytes, const cc_unit *xq1, const cc_size xq2_nbytes, const cc_unit *xq2,
const cc_size xq_nbytes, const cc_unit *xq,
ccrsa_full_ctx_t fk,
cc_size *np, cc_unit *r_p,
cc_size *nq, cc_unit *r_q,
cc_size *nm, cc_unit *r_m,
cc_size *nd, cc_unit *r_d);
/*
Signing and Verification algorithms
*/
/*!
@function ccrsa_sign_pss
@brief ccrsa_sign_pss() generates RSASSA-PSS signature in PKCS1-V2 format given an input digest
@param key The RSA key
@param hashAlgorithm The hash algorithm used to generate mHash from the original message. It is also used inside the PSS encoding function.
@param MgfHashAlgorithm The hash algorithm for thr mask generation function
@param rng Random number geberator to generate salt in PSS encoding
@param salt_nbytes Intended length of the salt
@param digest_nbytes Length of message hash . Must be equal to hashAlgorithm->output_size
@param digest The input that needs to be signed. This is the hash of message M with length of hLen
@param sig_nbytes The length of generated signature in bytes, which equals the size of the RSA modulus.
@param sig The signature output
@return 0:ok, non-zero:error
@discussion
note that in RSASSA-PSS, salt length is part of the signature as specified in ASN1
RSASSA-PSS-params ::= SEQUENCE {
hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
saltLength [2] INTEGER DEFAULT 20,
trailerField [3] TrailerField DEFAULT trailerFieldBC
If nlen = 1024 bits (i.e., 128 bytes), and the output length of the approved hash function output block is 512 bits (i.e., 64 bytes), then the length (in bytes) of the salt (sLen) shall satisfy 0 sLen hLen 2,
Otherwise, the length (in bytes) of the salt (sLen) shall satisfy 0 sLen hLen, where hLen is the length of the hash function output block (in bytes).
*/
CC_NONNULL((1, 2, 3, 5, 7, 8, 9))
int ccrsa_sign_pss(ccrsa_full_ctx_t key,
const struct ccdigest_info* hashAlgorithm, const struct ccdigest_info* MgfHashAlgorithm,
size_t salt_nbytes, struct ccrng_state *rng,
size_t digest_nbytes, const uint8_t *digest,
size_t *sig_nbytes, uint8_t *sig);
/*!
@function ccrsa_sign_pss_msg
@brief ccrsa_sign_pss_msg() generates a RSASSA-PSS signature in PKCS1-V2 format given an input message
@param key The RSA key
@param hashAlgorithm The hash algorithm used to generate mHash from the input message. It is also used inside the PSS encoding function.
@param MgfHashAlgorithm The hash algorithm for thr mask generation function
@param rng Random number generator to generate salt in PSS encoding
@param salt_nbytes Intended length of the salt
@param msg_nbytes Length of message.
@param msg The input that needs to be signed. This will be hashed using `hashAlgorithm`
@param sig_nbytes The length of generated signature in bytes, which equals the size of the RSA modulus.
@param sig The signature output
@return 0:ok, non-zero:error
@discussion
note that in RSASSA-PSS, salt length is part of the signature as specified in ASN1
RSASSA-PSS-params ::= SEQUENCE {
hashAlgorithm [0] HashAlgorithm DEFAULT sha1,
maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
saltLength [2] INTEGER DEFAULT 20,
trailerField [3] TrailerField DEFAULT trailerFieldBC
If nlen = 1024 bits (i.e., 128 bytes), and the output length of the approved hash function output block is 512 bits (i.e., 64 bytes), then the length (in bytes) of the salt (sLen) shall satisfy 0 sLen hLen 2,
Otherwise, the length (in bytes) of the salt (sLen) shall satisfy 0 sLen hLen, where hLen is the length of the hash function output block (in bytes).
*/
CC_NONNULL((1, 2, 3, 5, 7, 8, 9))
int ccrsa_sign_pss_msg(ccrsa_full_ctx_t key,
const struct ccdigest_info* hashAlgorithm, const struct ccdigest_info* MgfHashAlgorithm,
size_t salt_nbytes, struct ccrng_state *rng,
size_t msg_nbytes, const uint8_t *msg,
size_t *sig_nbytes, uint8_t *sig);
/*!
@function ccrsa_verify_pss
@brief ccrsa_verify_pss() verifies RSASSA-PSS signature in PKCS1-V2 format
@param key The RSA public key
@param hashAlgorithm The hash algorithm used to generate mHash from the original message. It is also used inside the PSS encoding function.
@param MgfHashAlgorithm The hash algorithm for the mask generation function
@param digest_nbytes Length of message hash . Must be equal to hashAlgorithm->output_size
@param digest The signed message hash
@param sig_nbytes The length of generated signature in bytes, which equals the size of the RSA modulus.
@param sig The signature to verify
@param salt_nbytes Length of the salt as used during signature generation. Mismatch would result in the signature being considered invalid
@param valid Input boolean used to indicate a valid signature.
@result 0 && valid == True indicates a valid signature. If return != 0 or valid == False, the signature is invalid.
*/
CC_NONNULL((2, 3, 5, 7, 9))
int ccrsa_verify_pss(ccrsa_pub_ctx_t key,
const struct ccdigest_info* hashAlgorithm,
const struct ccdigest_info* MgfHashAlgorithm,
size_t digest_nbytes, const uint8_t *digest,
size_t sig_nbytes, const uint8_t *sig,
size_t salt_nbytes, bool *valid)
cc_deprecate_with_replacement("ccrsa_verify_pss_digest", 13.0, 10.15, 13.0, 6.0, 4.0);
/*!
@function ccrsa_verify_pss_digest
@brief ccrsa_verify_pss_digest() verifies RSASSA-PSS signature in PKCS1-V2 format, given the digest
@param key The RSA public key
@param di The hash algorithm used to generate the hash of the message.
@param mgfdi The hash algorithm for the mask generation function
@param digest_nbytes Length of digest. Must be equal to di->output_size
@param digest The signed message hash
@param sig_nbytes The length of generated signature in bytes, which equals the size of the RSA modulus.
@param sig The signature to verify
@param salt_nbytes Length of the salt as used during signature generation.
@param fault_canary_out OPTIONAL cc_fault_canary_t (see discussion)
@result CCERR_SIGNATURE_VALID on signature success.
CCERR_SIGNATURE_INVALID on signature failure.
other on some other signature verification issue.
@discussion If the fault_canary_out argument is not NULL, the value `CCRSA_PSS_FAULT_CANARY` will be placed into fault_canary_out
if the salted input hash is equal to the decoded hash (which strongly implies the signature is valid). Callers can then securely compare this output buffer against CCRSA_PSS_FAULT_CANARY, using CC_FAULT_CANARY_EQUAL, as an additional check of signature validity: if the two canary values are equal, the signature is valid otherwise it is not. If the signature is valid and the canary values are NOT equal this may indicate a potentially injected computational fault.
*/
CC_NONNULL((1, 2, 3, 5, 7))
int ccrsa_verify_pss_digest(ccrsa_pub_ctx_t key,
const struct ccdigest_info* di,
const struct ccdigest_info* mgfdi,
size_t digest_nbytes, const uint8_t *digest,
size_t sig_nbytes, const uint8_t *sig,
size_t salt_nbytes, cc_fault_canary_t fault_canary_out);
/*!
@function ccrsa_verify_pss_msg
@brief ccrsa_verify_pss_msg() verifies RSASSA-PSS signature in PKCS1-V2 format, given the message
@param key The RSA public key
@param di The hash algorithm used to generate the hash of the message.
@param mgfdi The hash algorithm for the mask generation function
@param msg_nbytes Length of message
@param msg The signed message
@param sig_nbytes The length of generated signature in bytes, which equals the size of the RSA modulus.
@param sig The signature to verify
@param salt_nbytes Length of the salt as used during signature generation.
@param fault_canary_out OPTIONAL cc_fault_canary_t (see discussion)
@result CCERR_SIGNATURE_VALID on signature success.
CCERR_SIGNATURE_INVALID on signature failure.
other on some other signature verification issue.
@discussion If the fault_canary_out argument is not NULL, the value `CCRSA_PSS_FAULT_CANARY` will be placed into fault_canary_out
if the salted input hash is equal to the decoded hash (which strongly implies the signature is valid). Callers can then securely compare this output buffer against CCRSA_PSS_FAULT_CANARY, using CC_FAULT_CANARY_EQUAL, as an additional check of signature validity: if the two canary values are equal, the signature is valid otherwise it is not. If the signature is valid and the canary values are NOT equal this may indicate a potentially injected computational fault.
*/
CC_NONNULL((1, 2, 3, 5, 7))
int ccrsa_verify_pss_msg(ccrsa_pub_ctx_t key,
const struct ccdigest_info* di,
const struct ccdigest_info* mgfdi,
size_t msg_nbytes, const uint8_t *msg,
size_t sig_nbytes, const uint8_t *sig,
size_t salt_nbytes, cc_fault_canary_t fault_canary_out);
/*!
@function ccrsa_sign_pkcs1v15
@abstract RSA signature with PKCS#1 v1.5 format per PKCS#1 v2.2
@param key Full key
@param oid OID describing the type of digest passed in
@param digest_len Byte length of the digest
@param digest Byte array of digest_len bytes containing the digest
@param sig_len Pointer to the number of bytes allocated for sig.
Output the exact size of the signature.
@param sig Pointer to the allocated buffer of size *sig_len
for the output signature
@result CCERR_OK iff successful.
@discussion Null OID is a special case, required to support RFC 4346 where the padding
is based on SHA1+MD5. In general it is not recommended to use a NULL OID,
except when strictly required for interoperability
*/
CC_NONNULL((1, 4, 5, 6))
int ccrsa_sign_pkcs1v15(ccrsa_full_ctx_t key, const uint8_t *oid,
size_t digest_len, const uint8_t *digest,
size_t *sig_len, uint8_t *sig);
/*!
@function ccrsa_sign_pkcs1v15_msg
@abstract RSA signature with PKCS#1 v1.5 format per PKCS#1 v2.2
@param key Full key
@param di Digest context
@param msg_len Byte length of the message to sign
@param msg Byte array of msg_len bytes containing the message. Will be hashed with di.
@param sig_len Pointer to the number of bytes allocated for sig.
Output the exact size of the signature.
@param sig Pointer to the allocated buffer of size *sig_len
for the output signature
@result CCERR_OK iff successful.
@discussion Null OID is not supported by this API.
*/
CC_NONNULL((1, 2, 4, 5, 6))
int ccrsa_sign_pkcs1v15_msg(ccrsa_full_ctx_t key, const struct ccdigest_info* di,
size_t msg_len, const uint8_t *msg,
size_t *sig_len, uint8_t *sig);
/*!
@function ccrsa_verify_pkcs1v15
@abstract RSA signature with PKCS#1 v1.5 format per PKCS#1 v2.2
@param key Public key
@param oid OID describing the type of digest passed in
@param digest_len Byte length of the digest
@param digest Byte array of digest_len bytes containing the digest
@param sig_len Number of bytes of the signature sig.
@param sig Pointer to the signature buffer of sig_len
@param valid Output boolean, true if the signature is valid.
@result A return value of 0 and valid = True indicates a valid signature.
A non-zero return value or valid = False indicates an invalid signature.
@discussion Null OID is a special case, required to support RFC 4346
where the padding is based on SHA1+MD5. In general it is not
recommended to use a NULL OID, except when strictly required for
interoperability.
*/
CC_NONNULL((1, 4, 6, 7))
int ccrsa_verify_pkcs1v15(ccrsa_pub_ctx_t key, const uint8_t *oid,
size_t digest_len, const uint8_t *digest,
size_t sig_len, const uint8_t *sig,
bool *valid);
/*!
@function ccrsa_verify_pkcs1v15_digest
@abstract RSA signature with PKCS#1 v1.5 format per PKCS#1 v2.2, given a digest
@param key Public key
@param oid OID describing the type of digest passed in
@param digest_len Byte length of the digest
@param digest Byte array of digest_len bytes containing the digest
@param sig_len Number of bytes of the signature sig.
@param sig Pointer to the signature buffer of sig_len
@param fault_canary_out OPTIONAL cc_fault_canary_t
@result CCERR_VALID_SIGNATURE if a valid signature.
CCERR_INVALID_SIGNATURE if an invalid signature.
Other if the verification procedure failed.
@discussion If the fault_canary_out argument is not NULL, the value `CCRSA_PKCS1_FAULT_CANARY` will be placed into fault_canary_out
if the input hash is equal to the decoded hash (which strongly implies the signature is valid). Callers can then securely compare this output buffer against CCRSA_PKCS1_FAULT_CANARY, using CC_FAULT_CANARY_EQUAL, as an additional check of signature validity: if the two canary values are equal, the signature is valid otherwise it is not. If the signature is valid and the canary values are NOT equal this may indicate a potentially injected computational fault.
*/
CC_NONNULL((1, 4, 6))
int ccrsa_verify_pkcs1v15_digest(ccrsa_pub_ctx_t key, const uint8_t *oid,
size_t digest_len, const uint8_t *digest,
size_t sig_len, const uint8_t *sig,
cc_fault_canary_t fault_canary_out);
/*!
@function ccrsa_verify_pkcs1v15_msg
@abstract RSA signature with PKCS#1 v1.5 format per PKCS#1 v2.2
@param key Public key
@param di Hash function
@param msg_len Byte length of the digest
@param msg Byte array of digest_len bytes containing the digest
@param sig_len Number of bytes of the signature sig.
@param sig Pointer to the signature buffer of sig_len
@param fault_canary_out OPTIONAL cc_fault_canary_t
@result CCERR_VALID_SIGNATURE if a valid signature.
CCERR_INVALID_SIGNATURE if an invalid signature.
Other if the verification procedure failed.
@discussion Null OID is not supported by this API.
If the fault_canary_out argument is not NULL, the value `CCRSA_PKCS1_FAULT_CANARY` will
be placed into fault_canary_out if the input hash is equal to the decoded hash (which strongly
implies the signature is valid). Callers can then securely compare this output buffer against CCRSA_PKCS1_FAULT_CANARY, using CC_FAULT_CANARY_EQUAL, as an additional check of signature validity: if the two canary values are equal, the signature is valid otherwise it is not. If the signature is valid and the canary values are NOT equal this may indicate a potentially injected computational fault.
*/
CC_NONNULL((1, 2, 4, 6))
int ccrsa_verify_pkcs1v15_msg(ccrsa_pub_ctx_t key, const struct ccdigest_info* di,
size_t msg_len, const uint8_t *msg,
size_t sig_len, const uint8_t *sig,
cc_fault_canary_t fault_canary_out);
/*!
@function ccder_encode_rsa_pub_size
@abstract Calculate size of public key export format data package.
@param key Public key
@result Returns size required for encoding.
*/
CC_NONNULL((1))
size_t ccder_encode_rsa_pub_size(const ccrsa_pub_ctx_t key);
/*!
@function ccrsa_export_priv_pkcs1
@abstract Export a public key.
@param key Public key
@param der Beginning of output DER buffer
@param der_end End of output DER buffer
*/
CC_NONNULL((1, 2, 3))
uint8_t *ccder_encode_rsa_pub(const ccrsa_pub_ctx_t key, uint8_t *der, uint8_t *der_end);
/*!
@function ccder_encode_rsa_priv_size
@abstract Calculate size of full key exported in PKCS#1 format.
@param key Full key
@result Returns size required for encoding.
*/
CC_NONNULL((1))
size_t ccder_encode_rsa_priv_size(const ccrsa_full_ctx_t key);
/*!
@function ccder_encode_rsa_priv
@abstract Export a full key in PKCS#1 format.
@param key Full key
@param der Beginning of output DER buffer
@param der_end End of output DER buffer
*/
CC_NONNULL((1, 2, 3))
uint8_t *ccder_encode_rsa_priv(const ccrsa_full_ctx_t key, const uint8_t *der, uint8_t *der_end);
/*!
@function ccder_decode_rsa_pub_n
@abstract Calculate "n" for a public key imported from a data package.
PKCS #1 format
@param der Beginning of input DER buffer
@param der_end End of input DER buffer
@result the "n" of the RSA key that would result from the import. This can be used
to declare the key itself.
*/
CC_NONNULL((1, 2))
cc_size ccder_decode_rsa_pub_n(const uint8_t *der, const uint8_t *der_end);
/*!
@function ccder_decode_rsa_pub
@abstract Import a public RSA key from a package in public key format.
PKCS #1 format
@param key Public key (n must be set)
@param der Beginning of input DER buffer
@param der_end End of input DER buffer
@result Key is initialized using the data in the public key message.
*/
CC_NONNULL((1, 2, 3))
const uint8_t *ccder_decode_rsa_pub(const ccrsa_pub_ctx_t key, const uint8_t *der, const uint8_t *der_end);
/*!
@function ccder_decode_rsa_pub_x509_n
@abstract Calculate "n" for a public key imported from a data package in x509 format
@param der Beginning of input DER buffer
@param der_end End of input DER buffer
@result the "n" of the RSA key that would result from the import. This can be used
to declare the key itself.
*/
CC_NONNULL((1, 2))
cc_size ccder_decode_rsa_pub_x509_n(const uint8_t *der, const uint8_t *der_end);
/*!
@function ccder_decode_rsa_pub_x509
@abstract Import a public RSA key from a package in x509 format.
@param key Public key (n must be set)
@param der Beginning of input DER buffer
@param der_end End of input DER buffer
@result Key is initialized using the data in the public key message.
*/
CC_NONNULL((1, 2, 3))
const uint8_t *ccder_decode_rsa_pub_x509(const ccrsa_pub_ctx_t key, const uint8_t *der, const uint8_t *der_end);
/*!
@function ccder_decode_rsa_priv_n
@abstract Calculate "n" for a private key imported from a data package.
@param der Beginning of input DER buffer
@param der_end End of input DER buffer
@result the "n" of the RSA key that would result from the import. This can be used
to declare the key itself.
*/
CC_NONNULL((1, 2))
cc_size ccder_decode_rsa_priv_n(const uint8_t *der, const uint8_t *der_end);
/*!
@function ccder_decode_rsa_priv
@abstract Import a private RSA key from a package in PKCS#1 format.
@param key Full key (n must be set)
@param der Beginning of input DER buffer
@param der_end End of input DER buffer
@result Key is initialized using the data in the public key message.
*/
CC_NONNULL((1, 2, 3))
const uint8_t *ccder_decode_rsa_priv(const ccrsa_full_ctx_t key, const uint8_t *der, const uint8_t *der_end);
/*!
@function ccrsa_export_pub_size
@abstract Calculate size of public key exported data package.
@param key Public key
@result Returns size required for encoding.
*/
CC_INLINE CC_NONNULL((1))
size_t ccrsa_export_pub_size(const ccrsa_pub_ctx_t key) {
return ccder_encode_rsa_pub_size(key);
}
/*!
@function ccrsa_export_pub
@abstract Export a public key in public key format.
@param key Public key
@param out_len Allocated size
@param out Output buffer
*/
CC_NONNULL((1, 3))
int ccrsa_export_pub(const ccrsa_pub_ctx_t key, size_t out_len, uint8_t *out);
/*!
@function ccrsa_import_pub_n
@abstract Calculate "n" for a public key imported from a data package.
@param inlen Length of public key package data
@param der pointer to public key package data
@result the "n" of the RSA key that would result from the import. This can be used
to declare the key itself.
*/
CC_INLINE CC_NONNULL((2))
cc_size ccrsa_import_pub_n(size_t inlen, const uint8_t *der) {
cc_size size = ccder_decode_rsa_pub_x509_n(der, der + inlen);
if(size == 0) {
size = ccder_decode_rsa_pub_n(der, der + inlen);
}
return size;
}
/*!
@function ccrsa_import_pub
@abstract Import a public RSA key from a package in public key format.
@param key Public key (n must be set)
@param inlen Length of public key package data
@param der pointer to public key package data
@result Key is initialized using the data in the public key message.
*/
CC_NONNULL((1, 3))
int ccrsa_import_pub(ccrsa_pub_ctx_t key, size_t inlen, const uint8_t *der);
/*!
@function ccrsa_export_priv_size
@abstract Calculate size of full key exported in PKCS#1 format.
@param key Full key
@result Returns size required for encoding.
*/
CC_INLINE CC_NONNULL((1))
size_t ccrsa_export_priv_size(const ccrsa_full_ctx_t key) {
return ccder_encode_rsa_priv_size(key);
}
/*!
@function ccrsa_export_priv
@abstract Export a full key in PKCS#1 format.
@param key Full key
@param out_len Allocated size
@param out Output buffer
*/
CC_INLINE CC_NONNULL((1, 3))
int ccrsa_export_priv(const ccrsa_full_ctx_t key, size_t out_len, uint8_t *out) {
return (ccder_encode_rsa_priv(key, out, out+out_len) != out);
}
/*!
@function ccrsa_import_priv_n
@abstract Calculate size of full key exported in PKCS#1 format.
@param inlen Length of PKCS#1 package data
@param der pointer to PKCS#1 package data
@result the "n" of the RSA key that would result from the import. This can be used
to declare the key itself.
*/
CC_INLINE CC_NONNULL((2))
cc_size ccrsa_import_priv_n(size_t inlen, const uint8_t *der) {
return ccder_decode_rsa_priv_n(der, der + inlen);
}
/*!
@function ccrsa_import_priv
@abstract Import a full RSA key from a package in PKCS#1 format.
@param key Full key (n must be set)
@param inlen Length of PKCS#1 package data
@param der pointer to PKCS#1 package data
@result Key is initialized using the data in the PKCS#1 message.
*/
CC_INLINE CC_NONNULL((1, 3))
int ccrsa_import_priv(ccrsa_full_ctx_t key, size_t inlen, const uint8_t *der) {
return (ccder_decode_rsa_priv(key, der, der+inlen) == NULL);
}
/*!
@function ccrsa_get_pubkey_components
@abstract Copy each component of the public key to the given buffers
@param pubkey Public key
@param modulus Buffer to the output buffer for the modulus
@param modulusLength Pointer to the byte size allocated for the modulus, updated with actual output size
@param exponent Buffer to the output buffer for the exponent
@param exponentLength Pointer to the byte size allocated for the exponent, updated with actual output size
@return 0 is success, not 0 in case of error
@discussion if either allocated buffer length is insufficient, the function returns an error
*/
CC_NONNULL((1, 2))
int ccrsa_get_pubkey_components(const ccrsa_pub_ctx_t pubkey, uint8_t *modulus, size_t *modulusLength, uint8_t *exponent, size_t *exponentLength);
/*!
@function ccrsa_get_fullkey_components
@abstract Copy each component of the public key to the given buffers
@param key Full key
@param modulus Buffer to the output buffer for the modulus
@param modulusLength Pointer to the byte size allocated for the modulus, updated with actual output size
@param exponent Buffer to the output buffer for the exponent
@param exponentLength Pointer to the byte size allocated for the exponent, updated with actual output size
@param p Buffer to the output buffer for the first prime factor of the modulus
@param pLength Pointer to the byte size allocated for the prime factor, updated with actual output size
@param q Buffer to the output buffer for the second prime factor of the modulus
@param qLength Pointer to the byte size allocated for the prime factor, updated with actual output size
@return 0 is success, not 0 in case of error
@discussion if either allocated buffer length is insufficient, the function returns an error
*/
CC_NONNULL((1, 2))
int ccrsa_get_fullkey_components(const ccrsa_full_ctx_t key, uint8_t *modulus, size_t *modulusLength, uint8_t *exponent, size_t *exponentLength,
uint8_t *p, size_t *pLength, uint8_t *q, size_t *qLength);
/*!
@function ccrsa_dump_public_key
@abstract Print a rsa public key in the console (printf)
@param key Public key
*/
void ccrsa_dump_public_key(ccrsa_pub_ctx_t key);
/*!
@function ccrsa_dump_full_key
@abstract Print a rsa private key in the console (printf)
@param key Public key
*/
void ccrsa_dump_full_key(ccrsa_full_ctx_t key);
#endif /* _CORECRYPTO_CCRSA_H_ */

View File

@ -0,0 +1,40 @@
/* Copyright (c) (2010,2011,2012,2014,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCSHA1_H_
#define _CORECRYPTO_CCSHA1_H_
#include <corecrypto/ccdigest.h>
#include <corecrypto/cc_config.h>
#define CCSHA1_BLOCK_SIZE 64
#define CCSHA1_OUTPUT_SIZE 20
#define CCSHA1_STATE_SIZE 20
/* sha1 selector */
const struct ccdigest_info *ccsha1_di(void);
/* Implementations */
extern const struct ccdigest_info ccsha1_ltc_di;
extern const struct ccdigest_info ccsha1_eay_di;
#if CCSHA1_VNG_INTEL
extern const struct ccdigest_info ccsha1_vng_intel_SupplementalSSE3_di;
#endif
#if CCSHA1_VNG_ARM
extern const struct ccdigest_info ccsha1_vng_arm_di;
#endif
#define ccoid_sha1 ((unsigned char *)"\x06\x05\x2b\x0e\x03\x02\x1a")
#define ccoid_sha1_len 7
#endif /* _CORECRYPTO_CCSHA1_H_ */

View File

@ -0,0 +1,81 @@
/* Copyright (c) (2010,2011,2012,2014,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCSHA2_H_
#define _CORECRYPTO_CCSHA2_H_
#include <corecrypto/ccdigest.h>
/* sha2 selectors */
const struct ccdigest_info *ccsha224_di(void);
const struct ccdigest_info *ccsha256_di(void);
const struct ccdigest_info *ccsha384_di(void);
const struct ccdigest_info *ccsha512_di(void);
const struct ccdigest_info *ccsha512_256_di(void); // SHA512/256 (cf FIPS 180-4 https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf)
#define ccoid_sha224 ((unsigned char *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04")
#define ccoid_sha224_len 11
#define ccoid_sha256 ((unsigned char *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01")
#define ccoid_sha256_len 11
#define ccoid_sha384 ((unsigned char *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02")
#define ccoid_sha384_len 11
#define ccoid_sha512 ((unsigned char *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03")
#define ccoid_sha512_len 11
#define ccoid_sha512_256 ((unsigned char *)"\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06")
#define ccoid_sha512_256_len 11
/* SHA256 */
#define CCSHA256_BLOCK_SIZE 64
#define CCSHA256_OUTPUT_SIZE 32
#define CCSHA256_STATE_SIZE 32
extern const struct ccdigest_info ccsha256_ltc_di;
#if CCSHA2_VNG_INTEL
extern const struct ccdigest_info ccsha224_vng_intel_SupplementalSSE3_di;
extern const struct ccdigest_info ccsha256_vng_intel_SupplementalSSE3_di;
#endif
#if CCSHA2_VNG_ARM
extern const struct ccdigest_info ccsha224_vng_arm_di;
extern const struct ccdigest_info ccsha256_vng_arm_di;
#if CC_ACCELERATECRYPTO && defined(__arm64__) && CCSHA2_VNG_ARM
extern const struct ccdigest_info ccsha256_vng_arm64neon_di;
#endif // CC_ACCELERATECRYPTO
extern const struct ccdigest_info ccsha384_vng_arm_di;
extern const struct ccdigest_info ccsha512_vng_arm_di;
extern const struct ccdigest_info ccsha512_256_vng_arm_di;
#endif
/* SHA224 */
#define CCSHA224_OUTPUT_SIZE 28
extern const struct ccdigest_info ccsha224_ltc_di;
/* SHA512 */
#define CCSHA512_BLOCK_SIZE 128
#define CCSHA512_OUTPUT_SIZE 64
#define CCSHA512_STATE_SIZE 64
extern const struct ccdigest_info ccsha512_ltc_di;
/* SHA512/256 */
// FIPS 180-4
// https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
#define CCSHA512_256_BLOCK_SIZE 128
#define CCSHA512_256_OUTPUT_SIZE 32
#define CCSHA512_256_STATE_SIZE 64
extern const struct ccdigest_info ccsha512_256_ltc_di;
/* SHA384 */
#define CCSHA384_OUTPUT_SIZE 48
extern const struct ccdigest_info ccsha384_ltc_di;
#endif /* _CORECRYPTO_CCSHA2_H_ */

View File

@ -0,0 +1,137 @@
/* Copyright (c) (2010,2011,2012,2013,2014,2015,2016,2017,2018,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_CCZP_H_
#define _CORECRYPTO_CCZP_H_
#include <corecrypto/ccn.h>
#include <corecrypto/ccrng.h>
/*
Don't use cczp_hd struct directly, except in static tables such as eliptic curve parameter
definitions.
Declare cczp objects using cczp_decl_n(). It allocates cc_unit arrays of the length returned by
cczp_nof_n().
*/
struct cczp;
typedef struct cczp *cczp_t;
typedef const struct cczp *cczp_const_t;
struct cczp_funcs;
typedef const struct cczp_funcs *cczp_funcs_t;
// keep cczp_hd and cczp structures consistent
// cczp_hd is typecasted to cczp to read EC curve params
// make sure n is the first element see ccrsa_ctx_n macro
#define __CCZP_HEADER_ELEMENTS_DEFINITIONS(pre) \
cc_size pre##n; \
cc_unit pre##bitlen; \
cczp_funcs_t pre##funcs;
#define __CCZP_ELEMENTS_DEFINITIONS(pre) \
__CCZP_HEADER_ELEMENTS_DEFINITIONS(pre) \
cc_unit pre##ccn[];
// cczp_hd must be defined separetly without variable length array ccn[], because it is used in
// sructures such as ccdh_gp_decl_n
struct cczp_hd {
__CCZP_HEADER_ELEMENTS_DEFINITIONS()
} CC_ALIGNED(CCN_UNIT_SIZE);
struct cczp {
__CCZP_ELEMENTS_DEFINITIONS()
} CC_ALIGNED(CCN_UNIT_SIZE);
/* Return the size of an cczp where each ccn is _size_ bytes. */
#define cczp_size(_size_) (sizeof(struct cczp) + ccn_sizeof_n(1) + 2 * (_size_))
/* Return number of units that a struct cczp needs to be in units for a prime
size of N units. This is large enough for all operations. */
#define cczp_nof_n(_n_) (ccn_nof_size(sizeof(struct cczp)) + 1 + 2 * (_n_))
/* Return number of units that a struct cczp needs to be in units for a prime
size of _n_ units. */
#define cczp_decl_n(_n_, _name_) cc_ctx_decl(struct cczp, ccn_sizeof_n(cczp_nof_n(_n_)), _name_)
#define cczp_clear_n(_n_, _name_) cc_clear(ccn_sizeof_n(cczp_nof_n(_n_)), _name_)
#define CCZP_N(ZP) ((ZP)->n)
#define CCZP_PRIME(ZP) ((ZP)->ccn)
#define CCZP_BITLEN(ZP) ((ZP)->bitlen)
#define CCZP_RECIP(ZP) ((ZP)->ccn + CCZP_N(ZP))
CC_NONNULL((1)) CC_INLINE cc_size cczp_n(cczp_const_t zp)
{
return zp->n;
}
CC_NONNULL((1)) CC_INLINE const cc_unit *cczp_prime(cczp_const_t zp)
{
return zp->ccn;
}
CC_NONNULL((1)) CC_INLINE size_t cczp_bitlen(cczp_const_t zp)
{
cc_assert(ccn_bitlen(cczp_n(zp), cczp_prime(zp)) == CCZP_BITLEN(zp));
return (size_t)CCZP_BITLEN(zp);
}
/* Return a pointer to the Reciprocal or Montgomery constant of zp, which is
allocated cczp_n(zp) + 1 units long. */
CC_NONNULL((1)) CC_INLINE const cc_unit *cczp_recip(cczp_const_t zp)
{
return zp->ccn + zp->n;
}
/* Ensure both cczp_mod_prime(zp) and cczp_recip(zp) are valid. cczp_n and
cczp_prime must have been previously initialized. The reciprocal will
be computed and set. */
CC_NONNULL((1))
int cczp_init(cczp_t zp);
/*! @function cczp_init_with_recip
@abstract Initializes a cczp struct with a given reciprocal.
@param zp Pointer to a cczp struct.
@param recip Reciprocal for zp's prime.
*/
CC_NONNULL((1, 2))
void cczp_init_with_recip(cczp_t zp, const cc_unit *recip);
/* Compute r = m ^ e mod cczp_prime(zp), using Montgomery ladder.
- writes cczp_n(zp) units to r
- reads cczp_n(zp) units units from m and e
- if r and m are not identical they must not overlap.
- r and e must not overlap nor be identical.
- before calling this function either cczp_init(zp) must have been called
or both CCZP_MOD_PRIME((cc_unit *)zp) and CCZP_RECIP((cc_unit *)zp) must
be initialized some other way.
*/
CC_NONNULL((1, 2, 3, 4))
int cczp_power(cczp_const_t zp, cc_unit *r, const cc_unit *m, const cc_unit *e);
/*!
@brief cczp_inv(zp, r, x) computes r = x^-1 (mod p) , where p=cczp_prime(zp).
@discussion It is a general function and works for any p. It validates the inputs. r and x can
overlap. It writes n =cczp_n(zp) units to r, and read n units units from x and p. The output r is
overwriten only if the inverse is correctly computed. This function is not constant time in
absolute sense, but it does not have data dependent 'if' statements in the code.
@param zp The input zp. cczp_n(zp) and cczp_prime(zp) need to be valid. cczp_init(zp) need not to
be called before invoking cczp_inv().
@param x input big integer
@param r output big integer
@return 0 if inverse exists and correctly computed.
*/
CC_NONNULL((1, 2, 3))
int cczp_inv(cczp_const_t zp, cc_unit *r, const cc_unit *x);
#endif /* _CORECRYPTO_CCZP_H_ */

View File

@ -0,0 +1,46 @@
/* Copyright (c) (2017,2019) Apple Inc. All rights reserved.
*
* corecrypto is licensed under Apple Inc.s Internal Use License Agreement (which
* is contained in the License.txt file distributed with corecrypto) and only to
* people who accept that license. IMPORTANT: Any license rights granted to you by
* Apple Inc. (if any) are limited to internal use within your organization only on
* devices and computers you own or control, for the sole purpose of verifying the
* security characteristics and correct functioning of the Apple Software. You may
* not, directly or indirectly, redistribute the Apple Software or any portions thereof.
*/
#ifndef _CORECRYPTO_FIPSPOST_TRACE_H_
#define _CORECRYPTO_FIPSPOST_TRACE_H_
#if CC_FIPSPOST_TRACE
/*
* Use this string to separate out tests.
*/
#define FIPSPOST_TRACE_TEST_STR "?"
int fipspost_trace_is_active(void);
void fipspost_trace_call(const char *fname);
/* Only trace when VERBOSE is set to avoid impacting normal boots. */
#define FIPSPOST_TRACE_EVENT do { \
if (fipspost_trace_is_active()) { \
fipspost_trace_call(__FUNCTION__); \
} \
} while (0);
#define FIPSPOST_TRACE_MESSAGE(MSG) do { \
if (fipspost_trace_is_active()) { \
fipspost_trace_call(MSG); \
} \
} while (0);
#else
/* Not building a CC_FIPSPOST_TRACE-enabled, no TRACE operations. */
#define FIPSPOST_TRACE_EVENT
#define FIPSPOST_TRACE_MESSAGE(X)
#endif
#endif

View File

@ -0,0 +1,215 @@
//
// CoreTrust.h
// CoreTrust
//
// Copyright © 2017-2020 Apple Inc. All rights reserved.
//
#ifndef _CORETRUST_EVALUATE_H_
#define _CORETRUST_EVALUATE_H_
#include <stdint.h>
#include <stdbool.h>
__BEGIN_DECLS
typedef struct x509_octet_string {
const uint8_t *data;
size_t length;
} CTAsn1Item;
int CTParseCertificateSet(const uint8_t *der, const uint8_t *der_end, // Input: binary representation of concatenated DER-encoded certs
CTAsn1Item *certStorage, size_t certStorageLen, // Output: An array of certStorageLen CTAsn1Items that will be populated with the
// CTAsn1Item for each parsed cert (in the same order as input)
size_t *numParsedCerts); // Output: number of successfully parsed certs
int CTEvaluateSavageCerts(const uint8_t *certsData, size_t certsLen,
const uint8_t *rootKeyData, size_t rootKeyLen,
const uint8_t **leafKeyData, size_t *leafKeyLen,
bool *isProdCert);
int CTEvaluateSavageCertsWithUID(const uint8_t *certsData, size_t certsLen,
const uint8_t *rootKeyData, size_t rootKeyLen,
const uint8_t **leafKeyData, size_t *leafKeyLen, // Output: points to the leaf key data in the input certsData
uint8_t *UIDData, size_t UIDLen, // Output: a pre-allocated buffer of UIDLen
bool *isProdCert);
int CTEvaluateYonkersCerts(const uint8_t *certsData, size_t certsLen,
const uint8_t *rootKeyData, size_t rootKeyLen,
const uint8_t **leafKeyData, size_t *leafKeyLen, // Output: points to the leaf key data in the input certsData
uint8_t *UIDData, size_t UIDLen, // Output: a pre-allocated buffer of UIDLen
bool *isProdCert);
int CTEvaluateAcrt(const uint8_t *certsData, size_t certsLen, // Input: binary representation of at most 3 concatenated certs
// with leaf first (root may be omitted)
const uint8_t **leafKeyData, size_t *leafKeyLen); // Output: points to the leaf key data in the input certsData
int CTEvaluateUcrt(const uint8_t *certsData, size_t certsLen, // Input: binary representation of exactly 3 concatenated
// DER-encoded certs, with leaf first
const uint8_t **leafKeyData, size_t *leafKeyLen); // Output: points to the leaf key data in the input certsData)
int CTEvaluateUcrtTestRoot(const uint8_t *certsData, size_t certsLen, // Input: binary representation of exactly 3 concatenated
// DER-encoded certs, with leaf first
const uint8_t *rootKeyData, size_t rootKeyLen, // Input: Root public key, if not specified production root will be used
const uint8_t **leafKeyData, size_t *leafKeyLen); // Output: points to the leaf key data in the input certsData)
int CTEvaluateBAASystem(const uint8_t *certsData, size_t certsLen, // Input: binary representation of exactly 3 concatenated
// DER-encoded certs, with leaf first
const uint8_t **leafKeyData, size_t *leafKeyLen); // Output: points to the leaf key data in the input certsData
typedef struct baa_identity {
uint32_t chipId;
uint64_t ecid;
bool productionStatus;
bool securityMode;
uint8_t securityDomain;
CTAsn1Item img4;
} CTBAAIdentity;
int CTEvaluateBAASystemWithId(const uint8_t *certsData, size_t certsLen, // Input: binary representation of exactly 3 concatenated
// DER-encoded certs, with leaf first
const uint8_t **leafKeyData, size_t *leafKeyLen, // Output: points to the leaf key data in the input certsData
CTBAAIdentity *identity); // Output from identity field in leaf certificate
int CTEvaluateBAASystemTestRoot(const uint8_t *certsData, size_t certsLen, // Input: binary representation of exactly 3 concatenated
// DER-encoded certs, with leaf first
const uint8_t *rootKeyData, size_t rootKeyLen, // Input: Root public key, if not specified production root will be used
const uint8_t **leafKeyData, size_t *leafKeyLen,// Output: points to the leaf key data in the input certsData
CTBAAIdentity *identity); // Output from identity field in leaf certificate
int CTEvaluateBAAUser(const uint8_t *certsData, size_t certsLen, // Input: binary representation of exactly 3 concatenated
// DER-encoded certs, with leaf first
const uint8_t **leafKeyData, size_t *leafKeyLen, // Output: points to the leaf key data in the input certsData
CTBAAIdentity *identity); // Output from identity field in leaf certificate
int CTEvaluateBAAUserTestRoot(const uint8_t *certsData, size_t certsLen, // Input: binary representation of exactly 3 concatenated
// DER-encoded certs, with leaf first
const uint8_t *rootKeyData, size_t rootKeyLen, // Input: Root public key, if not specified production root will be used
const uint8_t **leafKeyData, size_t *leafKeyLen, // Output: points to the leaf key data in the input certsData
CTBAAIdentity *identity); // Output from identity field in leaf certificate
int CTEvaluateSatori(const uint8_t *certsData, size_t certsLen, // Input: binary (DER) representation of 3 concatenated certs
// with leaf first
bool allowTestRoot, // Input: whether to allow the Test Apple Roots
const uint8_t **leafKeyData, size_t *leafKeyLen); // Output: points to the leaf key data in the input certsData
int CTEvaluatePragueSignatureCMS(const uint8_t *cmsData, size_t cmsLen, // Input: CMS signature blob
const uint8_t *detachedData, size_t detachedDataLen, // Input: data signed by CMS blob
bool allowTestRoot, // Input: permit use of test hierarchy
const uint8_t **leafKeyData, size_t *leafKeyLen); // Output: points to leaf key data in input cmsData
int CTEvaluateKDLSignatureCMS(const uint8_t *cmsData, size_t cmsLen, // Input: CMS signature blob
const uint8_t *detachedData, size_t detachedDataLen, // Input: data signed by CMS blob
bool allowTestRoot, // Input: permit use of test hierarchy
const uint8_t **leafKeyData, size_t *leafKeyLen); // Output: points to leaf key data in input cmsData
typedef uint64_t CoreTrustPolicyFlags;
enum {
CORETRUST_POLICY_BASIC = 0,
CORETRUST_POLICY_SAVAGE_DEV = 1 << 0,
CORETRUST_POLICY_SAVAGE_PROD = 1 << 1,
CORETRUST_POLICY_MFI_AUTHV3 = 1 << 2,
CORETRUST_POLICY_MAC_PLATFORM = 1 << 3,
CORETRUST_POLICY_MAC_DEVELOPER = 1 << 4,
CORETRUST_POLICY_DEVELOPER_ID = 1 << 5,
CORETRUST_POLICY_MAC_APP_STORE = 1 << 6,
CORETRUST_POLICY_IPHONE_DEVELOPER = 1 << 7,
CORETRUST_POLICY_IPHONE_APP_PROD = 1 << 8,
CORETRUST_POLICY_IPHONE_APP_DEV = 1 << 9,
CORETRUST_POLICY_IPHONE_VPN_PROD = 1 << 10,
CORETRUST_POLICY_IPHONE_VPN_DEV = 1 << 11,
CORETRUST_POLICY_TVOS_APP_PROD = 1 << 12,
CORETRUST_POLICY_TVOS_APP_DEV = 1 << 13,
CORETRUST_POLICY_TEST_FLIGHT_PROD = 1 << 14,
CORETRUST_POLICY_TEST_FLIGHT_DEV = 1 << 15,
CORETRUST_POLICY_IPHONE_DISTRIBUTION = 1 << 16,
CORETRUST_POLICY_MAC_SUBMISSION = 1 << 17,
CORETRUST_POLICY_YONKERS_DEV = 1 << 18,
CORETRUST_POLICY_YONKERS_PROD = 1 << 19,
CORETRUST_POLICY_MAC_PLATFORM_G2 = 1 << 20,
CORETRUST_POLICY_ACRT = 1 << 21,
CORETRUST_POLICY_SATORI = 1 << 22,
CORETRUST_POLICY_BAA = 1 << 23,
CORETRUST_POLICY_UCRT = 1 << 24,
CORETRUST_POLICY_PRAGUE = 1 << 25,
CORETRUST_POLICY_KDL = 1 << 26,
CORETRUST_POLICY_MFI_AUTHV2 = 1 << 27,
CORETRUST_POLICY_MFI_SW_AUTH_PROD = 1 << 28,
CORETRUST_POLICY_MFI_SW_AUTH_DEV = 1 << 29,
CORETRUST_POLICY_COMPONENT = 1 << 30,
CORETRUST_POLICY_IMG4 = 1ULL << 31,
CORETRUST_POLICY_SERVER_AUTH = 1ULL << 32,
CORETRUST_POLICY_SERVER_AUTH_STRING = 1ULL << 33,
};
typedef uint32_t CoreTrustDigestType;
enum {
CORETRUST_DIGEST_TYPE_SHA1 = 1,
CORETRUST_DIGEST_TYPE_SHA224 = 2,
CORETRUST_DIGEST_TYPE_SHA256 = 4,
CORETRUST_DIGEST_TYPE_SHA384 = 8,
CORETRUST_DIGEST_TYPE_SHA512 = 16
};
int CTEvaluateAMFICodeSignatureCMS(const uint8_t *cmsData, size_t cmsLen, // Input: CMS blob
const uint8_t *detachedData, size_t detachedDataLen, // Input: data signed by CMS blob
bool allow_test_hierarchy, // Input: permit use of test hierarchy
const uint8_t **leafCert, size_t *leafCertLen, // Output: signing certificate
CoreTrustPolicyFlags *policyFlags, // Output: policy met by signing certificate
CoreTrustDigestType *cmsDigestType, // Output: digest used to sign the CMS blob
CoreTrustDigestType *hashAgilityDigestType, // Output: highest stregth digest type
// from hash agility attribute
const uint8_t **digestData, size_t *digestLen); // Output: pointer to hash agility value
// in CMS blob (with digest type above)
/* Returns non-zero if there's a standards-based problem with the CMS or certificates.
* Policy matching of the certificates is only reflected in the policyFlags output. Namely, if the only problem is that
* the certificates don't match a policy, the returned integer will be 0 (success) and the policyFlags will be 0 (no matching policies).
* Some notes about hash agility outputs:
* - hashAgilityDigestType is only non-zero for HashAgilityV2
* - If hashAgilityDigestType is non-zero, digestData/Len provides the digest value
* - If hashAgilityDigestType is zero, digestData/Len provides the content of the HashAgilityV1 attribute (if present)
* - If neither HashAgilityV1 nor HashAgilityV2 attributes are found, these outputs will all be NULL.
*/
int CTParseAccessoryCerts(const uint8_t *certsData, size_t certsLen, // Input: CMS or binary representation of DER-encoded certs
const uint8_t **leafCertData, size_t *leafCertLen, // Output: points to leaf cert data in input certsData
const uint8_t **subCACertData, size_t *subCACertLen, // Output: points to subCA cert data (1st of 2) in input certsData, if present. Is set to NULL if only one cert present in input.
CoreTrustPolicyFlags *flags); // Output: policy flags set by this leaf
int CTEvaluateAccessoryCert(const uint8_t *leafCertData, size_t leafCertLen, // Input: binary representation of DER-encoded leaf cert
const uint8_t *subCACertData, size_t subCACertLen, // Input: (optional) binary representation of DER-encoded subCA cert
const uint8_t *anchorCertData, size_t anchorCertLen, // Input: binary representation of DER-encoded anchor cert
CoreTrustPolicyFlags policy, // Input: policy to use when evaluating chain
const uint8_t **leafKeyData, size_t *leafKeyLen, // Output: points to the leaf key data in the input leafCertData
const uint8_t **extensionValueData, size_t *extensionValueLen); // Output: points to the extension value in the input leafCertData
/* Which extension value is returned is based on which policy the cert was verified against:
* - For MFI AuthV3, this is the value of the extension with OID 1.2.840.113635.100.6.36
* - For SW Auth, this is the value of the extension with OID 1.2.840.113635.100.6.59.1 (GeneralCapabilities extension)
* - For Component certs, this si the value of the extension with OID 1.2.840.113635.100.11.1 (Component Type)
*
* The following CoreTrustPolicyFlags are accepted:
* - CORETRUST_POLICY_BASIC
* - CORETRUST_POLICY_MFI_AUTHV2
* - CORETRUST_POLICY_MFI_AUTHV3
* - CORETRUST_POLICY_MFI_SW_AUTH_DEV
* - CORETRUST_POLICY_MFI_SW_AUTH_PROD
* - CORETRUST_POLICY_COMPONENT
*/
int CTEvaluateAppleSSL(const uint8_t *certsData, size_t certsLen, // Input: binary representation of up to 3 concatenated
// DER-encoded certificates, with leaf first
const uint8_t *hostnameData, size_t hostnameLen, // Input: The hostname of the TLS server being connected to
uint64_t leafMarker, // Input: The last decimal of the marker OID for this project
// (e.g. 32 for 1.2.840.113635.100.6.27.32
bool allowTestRoots); // Input: permit use of test hierarchy
int CTEvaluateAppleSSLWithOptionalTemporalCheck(const uint8_t *certsData, size_t certsLen,
const uint8_t *hostnameData, size_t hostnameLen,
uint64_t leafMarker,
bool allowTestRoots,
bool checkTemporalValidity);
__END_DECLS
#endif /* _CORETRUST_EVALUATE_H_ */

163
EXTERNAL_HEADERS/img4/api.h Normal file
View File

@ -0,0 +1,163 @@
/*!
* @header
* API definitions.
*/
#ifndef __IMG4_API_H
#define __IMG4_API_H
#ifndef __IMG4_INDIRECT
#error "Please #include <img4/firmware.h> instead of this file directly"
#endif // __IMG4_INDIRECT
#include <stdint.h>
#include <stdbool.h>
#include <os/base.h>
#ifndef KERNEL
#include <os/availability.h>
#include <unistd.h>
#endif
#if !XNU_KERNEL_PRIVATE
#include <TargetConditionals.h>
#endif
/*!
* @const IMG4_API_VERSION
* The API version of the library. This version will be changed in accordance
* with new API introductions so that callers may submit code to the build that
* adopts those new APIs before the APIs land by using the following pattern:
*
* #if IMG4_API_VERSION >= 20180424
* img4_new_api();
* #endif
*
* In this example, the library maintainer and API adopter agree on an API
* version of 20180424 ahead of time for the introduction of
* img4_new_api(). When a libdarwin with that API version is submitted, the
* project is rebuilt, and the new API becomes active.
*
* Breaking API changes will be both covered under this mechanism as well as
* individual preprocessor macros in this header that declare new behavior as
* required.
*/
#define IMG4_API_VERSION (20200724u)
#if IMG4_TAPI || (!defined(KERNEL) && !IMG4_PROJECT_BUILD)
#define IMG4_API_AVAILABLE_20180112 \
API_AVAILABLE( \
macos(10.15), \
ios(12.0), \
tvos(12.0), \
watchos(5.0))
#define IMG4_API_AVAILABLE_20180112_DEPRECATED \
API_DEPRECATED_WITH_REPLACEMENT( \
"img4_firmware_t", \
macos(10.15, 11.0), \
ios(12.0, 14.0), \
tvos(12.0, 14.0), \
watchos(5.0, 7.0))
#define IMG4_API_AVAILABLE_20181004 \
API_DEPRECATED_WITH_REPLACEMENT( \
"img4_firmware_t", \
macos(10.15, 11.0), \
ios(12.2, 14.0), \
tvos(12.2, 14.0), \
watchos(5.2, 7.0))
// This API version introduced the nonce manager which was not deprecated when
// the new API was introduced.
#define IMG4_API_AVAILABLE_20181106 \
API_AVAILABLE( \
macos(10.15), \
ios(12.2), \
tvos(12.2), \
watchos(5.2))
#define IMG4_API_AVAILABLE_20181106_DEPRECATED \
API_DEPRECATED_WITH_REPLACEMENT( \
"img4_firmware_t", \
macos(10.15, 11.0), \
ios(12.2, 14.0), \
tvos(12.2, 14.0), \
watchos(5.2, 7.0))
#define IMG4_API_AVAILABLE_20190125 \
API_DEPRECATED_WITH_REPLACEMENT( \
"img4_firmware_t", \
macos(10.15, 11.0), \
ios(13.0, 14.0), \
tvos(13.0, 14.0), \
watchos(6.0, 7.0))
#define IMG4_API_AVAILABLE_20191001 \
API_DEPRECATED_WITH_REPLACEMENT( \
"img4_firmware_t", \
macos(10.15.2, 11.0), \
ios(13.3, 14.0), \
tvos(13.3, 14.0), \
watchos(6.1.1, 7.0))
#define IMG4_API_AVAILABLE_20191108 \
API_DEPRECATED_WITH_REPLACEMENT( \
"img4_firmware_t", \
macos(11.0, 11.0), \
ios(14.0, 14.0), \
tvos(14.0, 14.0), \
watchos(7.0, 7.0))
#define IMG4_API_AVAILABLE_20200221 \
API_DEPRECATED_WITH_REPLACEMENT( \
"img4_firmware_t", \
macos(11.0, 11.0), \
ios(14.0, 14.0), \
tvos(14.0, 14.0), \
watchos(7.0, 7.0))
#define IMG4_API_AVAILABLE_20200310 \
API_DEPRECATED_WITH_REPLACEMENT( \
"img4_firmware_t", \
macos(11.0, 11.0), \
ios(14.0, 14.0), \
tvos(14.0, 14.0), \
watchos(7.0, 7.0))
#define IMG4_API_AVAILABLE_20200508 \
API_AVAILABLE( \
macos(11.0), \
ios(14.0), \
tvos(14.0), \
watchos(7.0), \
bridgeos(5.0))
#define IMG4_API_AVAILABLE_20200608 \
API_AVAILABLE( \
macos(11.0), \
ios(14.0), \
tvos(14.0), \
watchos(7.0), \
bridgeos(5.0))
#define IMG4_API_AVAILABLE_20200724 \
API_AVAILABLE( \
macos(11.0), \
ios(14.0), \
tvos(14.0), \
watchos(7.0), \
bridgeos(5.0))
#else
#define IMG4_API_AVAILABLE_20180112
#define IMG4_API_AVAILABLE_20180112_DEPRECATED
#define IMG4_API_AVAILABLE_20181004
#define IMG4_API_AVAILABLE_20181106
#define IMG4_API_AVAILABLE_20181106_DEPRECATED
#define IMG4_API_AVAILABLE_20190125
#define IMG4_API_AVAILABLE_20191001
#define IMG4_API_AVAILABLE_20191108
#define IMG4_API_AVAILABLE_20200221
#define IMG4_API_AVAILABLE_20200310
#define IMG4_API_AVAILABLE_20200508
#define IMG4_API_AVAILABLE_20200608
#define IMG4_API_AVAILABLE_20200724
#endif
/*!
* @typedef img4_struct_version_t
* A type describing the version of a structure in the library.
*/
IMG4_API_AVAILABLE_20180112
typedef uint16_t img4_struct_version_t;
#endif // __IMG4_API_H

View File

@ -0,0 +1,490 @@
/*!
* @header
* Supported chip environments.
*/
#ifndef __IMG4_CHIP_H
#define __IMG4_CHIP_H
#ifndef __IMG4_INDIRECT
#error "Please #include <img4/firmware.h> instead of this file directly"
#endif // __IMG4_INDIRECT
#if IMG4_TAPI
#include "tapi.h"
#endif
OS_ASSUME_NONNULL_BEGIN
/*!
* @typedef img4_chip_t
* An opaque type describing a destination chip environment for the firmware
* image.
*/
IMG4_API_AVAILABLE_20200508
typedef struct _img4_chip img4_chip_t;
/*!
* @typedef img4_chip_select_array_t
* A type representing a list of chips from which the implementation may select.
*/
IMG4_API_AVAILABLE_20200724
typedef const img4_chip_t *_Nullable const *img4_chip_select_array_t;
/*!
* @const IMG4_CHIP_INSTANCE_STRUCT_VERSION
* The version of the {@link img4_chip_instance_t} supported by the
* implementation.
*/
#define IMG4_CHIP_INSTANCE_STRUCT_VERSION (1u)
/*!
* @typedef img4_chip_instance_omit_t
* A bitfield describing omitted identifiers from a chip instance.
*
* @const IMG4_CHIP_INSTANCE_OMIT_CEPO
* The chip instance has no epoch.
*
* @const IMG4_CHIP_INSTANCE_OMIT_BORD
* The chip instance has no board identifier.
*
* @const IMG4_CHIP_INSTANCE_OMIT_CHIP
* The chip instance has no chip identifier.
*
* @const IMG4_CHIP_INSTANCE_OMIT_SDOM
* The chip instance has no security domain.
*
* @const IMG4_CHIP_INSTANCE_OMIT_ECID
* The chip instance has no unique chip identifier.
*
* @const IMG4_CHIP_INSTANCE_OMIT_CPRO
* The chip instance has no certificate production status.
*
* @const IMG4_CHIP_INSTANCE_OMIT_CSEC
* The chip instance has no certificate security mode.
*
* @const IMG4_CHIP_INSTANCE_OMIT_EPRO
* The chip instance has no effective production status.
*
* @const IMG4_CHIP_INSTANCE_OMIT_ESEC
* The chip instance has no effective security mode.
*
* @const IMG4_CHIP_INSTANCE_OMIT_IUOU
* The chip instance has no internal-use-only-unit property.
*
* @const IMG4_CHIP_INSTANCE_OMIT_RSCH
* The chip instance has no research fusing state.
*
* @const IMG4_CHIP_INSTANCE_OMIT_EUOU
* The chip instance has no engineering-use-only-unit property.
*/
OS_CLOSED_OPTIONS(img4_chip_instance_omit, uint64_t,
IMG4_CHIP_INSTANCE_OMIT_CEPO = (1 << 0),
IMG4_CHIP_INSTANCE_OMIT_BORD = (1 << 1),
IMG4_CHIP_INSTANCE_OMIT_CHIP = (1 << 2),
IMG4_CHIP_INSTANCE_OMIT_SDOM = (1 << 3),
IMG4_CHIP_INSTANCE_OMIT_ECID = (1 << 4),
IMG4_CHIP_INSTANCE_OMIT_CPRO = (1 << 5),
IMG4_CHIP_INSTANCE_OMIT_CSEC = (1 << 6),
IMG4_CHIP_INSTANCE_OMIT_EPRO = (1 << 7),
IMG4_CHIP_INSTANCE_OMIT_ESEC = (1 << 8),
IMG4_CHIP_INSTANCE_OMIT_IUOU = (1 << 9),
IMG4_CHIP_INSTANCE_OMIT_RSCH = (1 << 10),
IMG4_CHIP_INSTANCE_OMIT_EUOU = (1 << 11),
);
/*!
* @typedef img4_chip_instance_t
* An structure describing an instance of a chip.
*
* @field chid_version
* The version of the structure. Initialize to
* {@link IMG4_CHIP_INSTANCE_STRUCT_VERSION}.
*
* @field chid_chip_family
* The chip family of which this is an instance.
*
* @field chid_omit
* The identifiers which are absent from the chip instance.
*
* @field chid_cepo
* The certificate epoch of the chip instance.
*
* @field chid_bord
* The board identifier of the chip instance.
*
* @field chid_chip
* The chip identifier of the chip instance.
*
* @field chid_sdom
* The security domain of the chip instance.
*
* @field chid_ecid
* The unique chip identifier of the chip instance.
*
* @field chid_cpro
* The certificate production status of the chip instance.
*
* @field chid_csec
* The certificate security mode of the chip instance.
*
* @field chid_epro
* The effective production status of the chip instance.
*
* @field chid_esec
* The effective security mode of the chip instance.
*
* @field chid_iuou
* The internal use-only unit status of the chip instance.
*
* @field chid_rsch
* The research mode of the chip instance.
*
* @field chid_euou
* The engineering use-only unit status of the chip instance.
*
* Added in version 1 of the structure.
*/
IMG4_API_AVAILABLE_20200508
typedef struct _img4_chip_instance {
img4_struct_version_t chid_version;
const img4_chip_t *chid_chip_family;
img4_chip_instance_omit_t chid_omit;
uint32_t chid_cepo;
uint32_t chid_bord;
uint32_t chid_chip;
uint32_t chid_sdom;
uint64_t chid_ecid;
bool chid_cpro;
bool chid_csec;
bool chid_epro;
bool chid_esec;
bool chid_iuou;
bool chid_rsch;
bool chid_euou;
} img4_chip_instance_t;
/*!
* @const IMG4_CHIP_AP_SHA1
* The Application Processor on an Apple ARM SoC with an embedded sha1
* certifcate chain.
*
* This chip environment represents one unique instance of such a chip.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT
const img4_chip_t _img4_chip_ap_sha1;
#define IMG4_CHIP_AP_SHA1 (&_img4_chip_ap_sha1)
#else
#define IMG4_CHIP_AP_SHA1 (img4if->i4if_v7.chip_ap_sha1)
#endif
/*!
* @const IMG4_CHIP_AP_SHA2_384
* The Application Processor on an Apple ARM SoC with an embedded sha2-384
* certifcate chain.
*
* This chip environment represents one unique instance of such a chip.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT
const img4_chip_t _img4_chip_ap_sha2_384;
#define IMG4_CHIP_AP_SHA2_384 (&_img4_chip_ap_sha2_384)
#else
#define IMG4_CHIP_AP_SHA2_384 (img4if->i4if_v7.chip_ap_sha2_384)
#endif
/*!
* @const IMG4_CHIP_AP_HYBRID
* An Intel x86 processor whose chain of trust is rooted in an
* {@link IMG4_CHIP_AP_SHA2_384} environment. Firmwares executed on this chip
* are authenticated against the characteristics of the corresponding AP chip
* environment.
*
* This chip environment represents one unique instance of such a chip pair.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT
const img4_chip_t _img4_chip_ap_hybrid;
#define IMG4_CHIP_AP_HYBRID (&_img4_chip_ap_hybrid)
#else
#define IMG4_CHIP_AP_HYBRID (img4if->i4if_v7.chip_ap_hybrid)
#endif
/*!
* @const IMG4_CHIP_AP_REDUCED
* An Application Processor on an Apple ARM SoC operating in a reduced security
* configuration.
*
* This chip cannot be uniquely identified.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT
const img4_chip_t _img4_chip_ap_reduced;
#define IMG4_CHIP_AP_REDUCED (&_img4_chip_ap_reduced)
#else
#define IMG4_CHIP_AP_REDUCED (img4if->i4if_v7.chip_ap_reduced)
#endif
/*!
* @const IMG4_CHIP_AP_PERMISSIVE
* An Application Processor on an Apple ARM SoC operating with no secure boot
* enforcement.
*
* This chip cannot be uniquely identified.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT
const img4_chip_t _img4_chip_ap_permissive;
#define IMG4_CHIP_AP_PERMISSIVE (&_img4_chip_ap_permissive)
#else
#define IMG4_CHIP_AP_PERMISSIVE (img4if->i4if_v8.chip_ap_permissive)
#endif
/*!
* @const IMG4_CHIP_AP_HYBRID_MEDIUM
* An Intel x86 processor whose chain of trust is rooted in an
* {@link IMG4_CHIP_AP_SHA2_384} environment and is operating in a "medium
* security" mode due to a user-approved security degradation.
*
* This chip cannot be uniquely identified.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT
const img4_chip_t _img4_chip_ap_hybrid_medium;
#define IMG4_CHIP_AP_HYBRID_MEDIUM (&_img4_chip_ap_hybrid_medium)
#else
#define IMG4_CHIP_AP_HYBRID_MEDIUM (img4if->i4if_v8.chip_ap_hybrid_medium)
#endif
/*!
* @const IMG4_CHIP_AP_HYBRID_RELAXED
* An Intel x86 processor whose chain of trust is rooted in an
* {@link IMG4_CHIP_AP_SHA2_384} environment and is operating with no secure
* boot enforcement due to a user-approved security degradation.
*
* This chip cannot be uniquely identified.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT
const img4_chip_t _img4_chip_ap_hybrid_relaxed;
#define IMG4_CHIP_AP_HYBRID_RELAXED (&_img4_chip_ap_hybrid_relaxed)
#else
#define IMG4_CHIP_AP_HYBRID_RELAXED (img4if->i4if_v8.chip_ap_hybrid_relaxed)
#endif
/*!
* @const IMG4_CHIP_AP_SOFTWARE_FF00
* A software-defined chip environment whose firmwares are executed on any
* Application Processor on an Apple ARM SoC. The firmwares are loadable trust
* caches shipped with OTA update brains.
*
* This chip cannot be uniquely identified.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT
const img4_chip_t _img4_chip_ap_software_ff00;
#define IMG4_CHIP_AP_SOFTWARE_FF00 (&_img4_chip_ap_software_ff00)
#else
#define IMG4_CHIP_AP_SOFTWARE_FF00 (img4if->i4if_v7.chip_ap_software_ff00)
#endif
/*!
* @const IMG4_CHIP_AP_SOFTWARE_FF01
* A software-defined chip environment whose firmwares are executed on any
* Application Processor on an Apple ARM SoC. The firmwares are loadable trust
* caches which are shipped in the Install Assistant and loaded by an
* unprivileged trampoline.
*
* This chip cannot be uniquely identified.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT
const img4_chip_t _img4_chip_ap_software_ff01;
#define IMG4_CHIP_AP_SOFTWARE_FF01 (&_img4_chip_ap_software_ff01)
#else
#define IMG4_CHIP_AP_SOFTWARE_FF01 (img4if->i4if_v7.chip_ap_software_ff01)
#endif
/*!
* @const IMG4_CHIP_X86
* An Intel x86 processor which cannot be uniquely identified.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT
const img4_chip_t _img4_chip_x86;
#define IMG4_CHIP_X86 (&_img4_chip_x86)
#else
#define IMG4_CHIP_X86 (img4if->i4if_v7.chip_x86)
#endif
/*!
* @const IMG4_CHIP_X86_SOFTWARE_8012
* A software-defined chip environment describing a virtualized x86 processor.
* Since the virtual machine is at the mercy of the VM, support for any sort of
* chip identity may not be available. Therefore this environment is returned
* from {@link img4_chip_select_personalized_ap} and
* {@link img4_chip_select_effective_ap} when it is called on a virtual machine
* so that the appropriate chip environment is present entirely in software.
*
* This environment provides an equivalent software identity to that of
* the {@link IMG4_CHIP_X86} chip environment on non-Gibraltar Macs.
*
* @discussion
* Do not use this environment directly.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT
const img4_chip_t _img4_chip_x86_software_8012;
#define IMG4_CHIP_X86_SOFTWARE_8012 (&_img4_chip_x86_software_8012)
#else
#define IMG4_CHIP_X86_SOFTWARE_8012 (img4if->i4if_v7.chip_x86_software_8012)
#endif
/*!
* @function img4_chip_init_from_buff
* Initializes a buffer as a chip object.
*
* @param buff
* A pointer to the storage to use for the chip object.
*
* @param len
* The size of the buffer.
*
* @discussion
* The caller is expected to pass a buffer that is "big enough". If the provided
* buffer is too small, the implementation will abort the caller.
*
* @example
*
* uint8_t _buff[IMG4_CHIP_SIZE_RECOMMENDED];
* img4_chip_t *chip = NULL;
*
* chip = img4_chip_init_from_buff(_buff, sizeof(_buff));
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_WARN_RESULT OS_NONNULL1
img4_chip_t *
img4_chip_init_from_buff(void *buff, size_t len);
#else
#define img4_chip_init_from_buff (img4if->i4if_v7.chip_init_from_buff)
#endif
/*!
* @function img4_chip_select_personalized_ap
* Returns the chip appropriate for personalized verification against the host
* AP.
*
* @result
* The personalized chip environment for the host which corresponds to its
* silicon identity.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_WARN_RESULT
const img4_chip_t *
img4_chip_select_personalized_ap(void);
#else
#define img4_chip_select_personalized_ap(...) \
(img4if->i4if_v7.chip_select_personalized_ap(__VA_ARGS__))
#endif
/*!
* @function img4_chip_select_effective_ap
* Returns the chip appropriate for verification against the host AP.
*
* @result
* The currently enforced chip environment for the host. This interface is
* generally only useful on the AP.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_WARN_RESULT
const img4_chip_t *
img4_chip_select_effective_ap(void);
#else
#define img4_chip_select_effective_ap(...) \
(img4if->i4if_v7.chip_select_effective_ap(__VA_ARGS__))
#endif
/*!
* @function img4_chip_instantiate
* Returns an instantiation of the given chip using the default runtime where
* necessary.
*
* @param chip
* The chip to instantiate.
*
* @param chip_instance
* Upon successful return, storage to be populated with the instantiated chip.
* Upon failure, the contents of this storage are undefined.
*
* @result
* Upon success, zero is returned. Otherwise, one of the following error codes
* will be returned:
*
* [EXDEV] There was an error querying the runtime's identity oracle
* [ENODATA] The expected property in the runtime's identity oracle was
* of an unexpected type
* [EOVERFLOW] The expected property in the runtime's identity oracle had
* a value that was too large to be represented in the
* expected type
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2
errno_t
img4_chip_instantiate(const img4_chip_t *chip,
img4_chip_instance_t *chip_instance);
#else
#define img4_chip_instantiate(...) \
(img4if->i4if_v7.chip_instantiate(__VA_ARGS__))
#endif
/*!
* @function img4_chip_custom
* Returns a custom chip derived from the given chip instance. The
* {@link chid_chip_family} field of the given instance will be used as a
* template from which to derive the new chip.
*
* @param chip_instance
* The instance of the custom chip.
*
* The memory referenced by this pointer must be static or otherwise guaranteed
* to be valid for the duration of the caller's use of the custom chip.
*
* @param chip
* A pointer to storage for the new custom chip.
*
* The memory referenced by this pointer must be static or otherwise guaranteed
* to be valid for the duration of the caller's use of the custom chip.
*
* This pointer should be obtained as the result of a call to
* {@link img4_chip_init_from_buff}.
*
* @result
* A new custom chip.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_WARN_RESULT OS_NONNULL1
const img4_chip_t *
img4_chip_custom(const img4_chip_instance_t *chip_instance, img4_chip_t *chip);
#else
#define img4_chip_custom(...) (img4if->i4if_v7.chip_custom(__VA_ARGS__))
#endif
OS_ASSUME_NONNULL_END
#endif // __IMG4_CHIP_H

View File

@ -0,0 +1,649 @@
/*!
* @header
* Interfaces for manipulating Image4 firmware objects.
*/
#ifndef __IMG4_FIRMWARE_H
#define __IMG4_FIRMWARE_H
#include <os/base.h>
#include <stdint.h>
#include <stdbool.h>
#include <sys/cdefs.h>
__BEGIN_DECLS;
#if !KERNEL
#include <os/stdio.h>
#endif
#if !_DARWIN_BUILDING_PROJECT_APPLEIMAGE4
#if __has_include(<os/linker_set.h>) && !KERNEL
#include <os/linker_set.h>
#elif XNU_KERNEL_PRIVATE
// There is no linker set header in the KDK, and the one from the SDK is not
// safe for kexts to use.
//
// <rdar://problem/64576673>
#include <sys/linker_set.h>
#else
#define LINKER_SET_ENTRY(...)
#endif
#endif // !_DARWIN_BUILDING_PROJECT_APPLEIMAGE4
/*!
* @discussion
* When used from the pmap layer, this header pulls in the types from libsa,
* which conflict with the BSD sys/types.h header that we need to pull in. But
* we only need it for the errno_t typedef and the vnode_t typedef. So when
* building MACH_KERNEL_PRIVATE, we do two things:
*
* 1. Explicitly pull in <sys/_types/_errno_t.h>, so we get errno_t and
* nothing else (no transitive #include's)
* 2. #define _SYS_TYPES_H_ before #includ'ing <sys/kernel_types.h> so that
* we don't get the transitive #include of <sys/types.h> but we still get
* the definitions we need
*/
#if MACH_KERNEL_PRIVATE
#define _SYS_TYPES_H_ 1
#include <sys/kernel_types.h>
#include <sys/_types/_errno_t.h>
#else
#include <sys/kernel_types.h>
#include <sys/types.h>
#endif
#define __IMG4_INDIRECT 1
#include <img4/api.h>
#if IMG4_TAPI
#include "tapi.h"
#endif
OS_ASSUME_NONNULL_BEGIN
/*!
* @typedef img4_4cc_t
* A type which represents a four-character code (4cc) that identifies the
* firmware. These 4cc's are statically assigned and correspond to long-form tag
* names -- e.g. the 4cc 'krnl' corresponds to the "KernelCache" tag.
*/
IMG4_API_AVAILABLE_20200508
typedef uint32_t img4_4cc_t;
/*!
* @typedef img4_buff_t
* A structure describing a buffer. See {@link _img4_buff}.
*/
IMG4_API_AVAILABLE_20200508
typedef struct _img4_buff img4_buff_t;
/*!
* @typedef img4_firmware_t
* An opaque type describing an Image4 firmware object.
*/
IMG4_API_AVAILABLE_20200508
typedef struct _img4_firmware *img4_firmware_t;
/*!
* @typedef img4_image_t
* An opaque type describing an authenticated Image4 firmware image.
*/
IMG4_API_AVAILABLE_20200508
typedef struct _img4_image *img4_image_t;
/*!
* @typedef img4_runtime_t
* A structure describing required primitives in the operating environment's
* runtime. See {@link _img4_runtime}.
*/
IMG4_API_AVAILABLE_20200508
typedef struct _img4_runtime img4_runtime_t;
OS_ASSUME_NONNULL_END
#if !_DARWIN_BUILDING_PROJECT_APPLEIMAGE4 || IMG4_TAPI
#define __IMG4_INDIRECT 1
#include <img4/nonce.h>
#include <img4/object.h>
#include <img4/chip.h>
#include <img4/image.h>
#include <img4/runtime.h>
#endif
OS_ASSUME_NONNULL_BEGIN
/*!
* @typedef img4_firmware_authenticated_execute_t
* A firmware execution function. This function is called when the firmware has
* been successfully authenticated and is ready for execution.
*
* @param fw
* The firmware which has been authenticated.
*
* @param image
* The resulting firmware image that may be executed. The implementation will
* pass NULL if there was a failure.
*
* This object is automatically freed by the implementation upon return.
*
* @param error
* An error code describing the result of the authentication. If authentication
* was successful, the implementation will pass zero. Otherwise, one of the
* following error codes will be provided:
*
* [EILSEQ] The firmware data is not valid Image4 data -- this will not
* be passed for firmwares created with
* {@link IMG4_FIRMWARE_FLAG_BARE}
* [EFTYPE] The attached manifest is not a valid Image4 manifest
* [ENOENT] The attached manifest does not authenticate this type of
* firmware
* [EAUTH] The attached manifest is not authentic (i.e. was not signed
* by an Apple CA)
* [EACCES] The given chip does not satisfy the constraints of the
* attached manifest
* [ESTALE] The manifest has been invalidated and is no longer valid for
* the provided chip
* [ENOEXEC] The firmware has been corrupted, or the given chip does not
* satisfy the constraints of the corresponding object in the
* attached manifest
*
* @param _ctx
* The user-provided context pointer.
*/
IMG4_API_AVAILABLE_20200508
typedef void (*img4_firmware_authenticated_execute_t)(
const img4_firmware_t fw,
img4_image_t _Nullable image,
errno_t error,
void *_ctx
);
/*!
* @define IMG4_FIRMWARE_EXECUTION_CONTEXT_STRUCT_VERSION
* The version of the {@link img4_firmware_execution_context_t} structure
* supported by the implementation.
*/
#define IMG4_FIRMWARE_EXECUTION_CONTEXT_STRUCT_VERSION (0u)
/*!
* @typedef img4_firmware_execution_context_t
* A structure describing the context in which a firmware is to be executed.
*
* @field i4fex_version
* The version of the structure supported by the implementation. Initialize to
* {@link IMG4_FIRMWARE_EXECUTION_CONTEXT_STRUCT_VERSION}.
*
* @field i4fex_execute
* A pointer to the firmware execution function.
*
* @field i4fex_context
* A caller-provided context pointer that will be passed to functions invoked
* from the execution context.
*/
IMG4_API_AVAILABLE_20200508
typedef struct _img4_firmware_execution_context {
img4_struct_version_t i4fex_version;
img4_firmware_authenticated_execute_t i4fex_execute;
void *i4fex_context;
} img4_firmware_execution_context_t;
/*!
* @typedef img4_firmware_flags_t
* A bitfield modifying the behavior of an {@link img4_firmware_t} object.
*
* @const IMG4_FIRMWARE_FLAG_INIT
* No bits set. This value is suitable for initialization purposes.
*
* @const IMG4_FIRMWARE_FLAG_ATTACHED_MANIFEST
* The manifest authenticating the firmware is attached (i.e. the buffer given
* represents a .img4 file).
*
* @const IMG4_FIRMWARE_FLAG_BARE
* The firmware image is not wrapped with an Image4 payload structure. This flag
* is mutually exclusive with {@link IMG4_FIRMWARE_FLAG_ATTACHED_MANIFEST}, and
* if both are present, the implementation's behavior is undefined.
*
* @const IMG4_FIRMWARE_FLAG_SUBSEQUENT_STAGE
* The firmware image extends an existing chain of trust. If set, the
* runtime must provide a {@link i4rt_get_digest} function which returns a
* digest for {@link IMG4_IDENTIFIER_CHMH}.
*
* If set, the firmware may optionally provide a {@link i4rt_get_bool} function
* which returns a value for {@link IMG4_IDENTIFIER_AMNM}.
*
* @const IMG4_FIRMWARE_FLAG_RESPECT_AMNM
* Forces the implementation to respect the manifest's AMNM entitlement if it is
* present, even if the validation is creating a new chain of trust. This is
* technically maybe sort of against the Image4 spec, but it is useful for
* certain internal workflows (cf. v2.3, §2.2.10).
*
* This flag has no effect if {@link IMG4_FIRMWARE_FLAG_SUBSEQUENT_STAGE} is
* also passed.
*/
IMG4_API_AVAILABLE_20200508
OS_CLOSED_OPTIONS(img4_firmware_flags, uint64_t,
IMG4_FIRMWARE_FLAG_INIT,
IMG4_FIRMWARE_FLAG_ATTACHED_MANIFEST = (1 << 0),
IMG4_FIRMWARE_FLAG_BARE = (1 << 1),
IMG4_FIRMWARE_FLAG_SUBSEQUENT_STAGE = (1 << 2),
IMG4_FIRMWARE_FLAG_RESPECT_AMNM = (1 << 3),
);
/*!
* @function img4_firmware_new
* Allocate and initialize a new firmware object.
*
* @param rt
* The runtime in which to initialize the object.
*
* @param _4cc
* The 4cc which distinguishes the firmware.
*
* @param buff
* A buffer containing a valid Image4 payload (usually the contents of either a
* .im4p or .img4 file).
*
* Upon return, the destructor in the buffer is replaced with NULL, and the
* implementation assumes responsibility for deallocating the underlying memory.
*
* @param flags
* Flags modifying the behavior of the object.
*
* @result
* A new firmware object or NULL if there was an allocation failure.
*
* @discussion
* The resulting object assumes ownership of the given buffer.
*
* In the Darwin userspace runtime, NULL will not be returned.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_WARN_RESULT OS_MALLOC OS_NONNULL1 OS_NONNULL2 OS_NONNULL4
img4_firmware_t _Nullable
img4_firmware_new(const img4_runtime_t *rt,
const img4_firmware_execution_context_t *exec,
img4_4cc_t _4cc,
img4_buff_t *buff,
img4_firmware_flags_t flags);
#else
#define img4_firmware_new(...) (img4if->i4if_v7.firmware_new(__VA_ARGS__))
#endif
/*!
* @function img4_firmware_new_from_vnode_4xnu
* Allocate and initialize a new firmware object from a vnode.
*
* @param rt
* The runtime in which to initialize the object. This interface is only
* supported with the Darwin kernel runtime. If any other runtime is provided,
* the implementation's behavior is undefined.
*
* @param _4cc
* The 4cc which distinguishes the firmware.
*
* @param vn
* A vnode representing a valid Image4 payload (usually the contents of either a
* .im4p or .img4 file).
*
* @param flags
* Flags modifying the behavior of the object.
*
* @result
* A new firmware object or NULL if there was an allocation failure.
*
* @discussion
* Verification of a vnode is performed by reading in chunks of data, updating
* an ongoing hash operation with that data, and then discarding it. Therefore,
* firmware objects created in this manner can only guarantee their validity at
* the time the check was performed since the vnode's contents are not kept in
* memory and may be tampered with after validation has been performed.
*
* As such, on successful execution, the image passed to the
* {@link img4_firmware_authenticated_execute_t} function of the execution
* context is NULL.
*
* Firmwares created with this interface cannot be created with the
* {@link IMG4_FIRMWARE_FLAG_ATTACHED_MANIFEST} flag.
*/
#if KERNEL
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_WARN_RESULT OS_MALLOC OS_NONNULL1 OS_NONNULL2 OS_NONNULL4
img4_firmware_t _Nullable
img4_firmware_new_from_vnode_4xnu(const img4_runtime_t *rt,
const img4_firmware_execution_context_t *exec,
img4_4cc_t _4cc,
vnode_t vn,
img4_firmware_flags_t flags);
#else
#define img4_firmware_new_from_vnode_4xnu(...) \
(img4if->i4if_v7.firmware_new_from_vnode_4xnu(__VA_ARGS__))
#endif // !XNU_KERNEL_PRIVATE
#endif // !KERNEL
/*!
* @function img4_firmware_new_from_fd_4MSM
* Allocate and initialize a new firmware object from a file descriptor.
*
* @param rt
* The runtime in which to initialize the object. This interface is only
* supported with the Darwin userspace runtime. If any other runtime is
* provided, the implementation's behavior is undefined.
*
* @param _4cc
* The 4cc which distinguishes the firmware.
*
* @param fd
* A pointer to a file descriptor representing a valid Image4 payload (usually
* the contents of either a .im4p or .img4 file). The object assumes ownership
* of the descriptor, and upon return, the value referenced by the pointer will
* be set to -1.
*
* @param flags
* Flags modifying the behavior of the object.
*
* @result
* A new firmware object. The implementation will not return NULL.
*
* @discussion
* This interface is the userspace equivalent of
* {@link img4_firmware_new_from_vnode_4xnu}, and all the same caveats apply.
*/
#if !KERNEL
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_WARN_RESULT OS_MALLOC OS_NONNULL1 OS_NONNULL2
img4_firmware_t
img4_firmware_new_from_fd_4MSM(const img4_runtime_t *rt,
const img4_firmware_execution_context_t *exec,
img4_4cc_t _4cc,
os_fd_t *fd,
img4_firmware_flags_t flags);
#endif
/*!
* @function img4_firmware_init_from_buff
* Initializes a buffer as a firmware object. This interface is useful for
* runtimes which do not provide for dynamic memory allocation.
*
* @param storage
* A pointer to the storage to use for the firmware object.
*
* @param len
* The size of the buffer.
*
* @discussion
* The caller is expected to pass a buffer that is "big enough". If the provided
* buffer is too small, the implementation will abort the caller.
*
* @example
*
* uint8_t _buff[IMG4_FIRMWARE_SIZE_RECOMMENDED];
* img4_firmware_t fw = NULL;
*
* fw = img4_firmware_init_from_buff(_buff, sizeof(_buff));
* img4_firmware_init(fw, IMG4_RUNTIME_DEFAULT, &exec_context,
* kImg4Tag_krnl, fw_buff, 0);
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_WARN_RESULT OS_NONNULL1
img4_firmware_t
img4_firmware_init_from_buff(void *buff, size_t len);
#else
#define img4_firmware_init_from_buff(...) \
(img4if->i4if_v7.firmware_init_from_buff(__VA_ARGS__))
#endif
/*!
* @function img4_firmware_init
* Initialize a firmware object.
*
* @param fw
* A pointer to the storage for the firmware object. This pointer should refer
* to a region of memory that is sufficient to hold a {@link img4_firmware_t}
* object. This size should be queried with the {@link i4rt_object_size}
* function of the runtime.
*
* @param rt
* The runtime in which to initialize the object.
*
* @param _4cc
* The 4cc which distinguishes the firmware.
*
* @param buff
* A buffer containing a valid Image4 payload (usually the contents of either a
* .im4p or .img4 file).
*
* Upon return, the destructor in the buffer is replaced with NULL, and the
* implementation assumes responsibility for deallocating the underlying memory.
*
* @param flags
* Flags modifying the behavior of the object.
*
* @discussion
* The resulting object assumes ownership of the given buffer. This routine
* should only be used when dynamic memory allocation is not available in the
* runtime. Otherwise, use {@link img4_firmware_new}.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_NONNULL1 OS_NONNULL2 OS_NONNULL3 OS_NONNULL5
void
img4_firmware_init(img4_firmware_t fw,
const img4_runtime_t *rt,
const img4_firmware_execution_context_t *exec,
img4_4cc_t _4cc,
img4_buff_t *buff,
img4_firmware_flags_t flags);
#else
#define img4_firmware_init(...) (img4if->i4if_v7.firmware_init(__VA_ARGS__))
#endif
/*!
* @function img4_firmware_attach_manifest
* Attaches a signed manifest to the firmware.
*
* @param fw
* The firmware to manipulate.
*
* @param buff
* A buffer containing a valid Image4 manifest (usually the contents of either a
* .im4m or .img4 file).
*
* Upon return, the destructor in the buffer is replaced with NULL, and the
* implementation assumes responsibility for deallocating the underlying memory.
*
* @discussion
* If this interface is called on a firmware created with the
* {@link IMG4_FIRMWARE_FLAG_ATTACHED_MANIFEST} flag, the implementation's
* behavior is undefined.
*
* This interface must be called on any firmware created with the
* {@link IMG4_FIRMWARE_FLAG_BARE} flag.
*
* The object assumes ownership of the given buffer.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_NONNULL1 OS_NONNULL2
void
img4_firmware_attach_manifest(img4_firmware_t fw,
img4_buff_t *buff);
#else
#define img4_firmware_attach_manifest(...) \
(img4if->i4if_v7.firmware_attach_manifest(__VA_ARGS__))
#endif
/*!
* @function img4_firmware_select_chip
* Returns the chip from the provided array which may be used to authenticate
* the firmware.
*
* @param fw
* The firmware to query.
*
* @param acceptable_chips
* An array of chips the caller finds acceptable to verify the firmware.
*
* @param acceptable_chips_cnt
* The number of elements in {@link acceptable_chips}.
*
* @result
* If the manifest may be authenticated by the certificate chain associated with
* one of the manifests provided in {@link acceptable_chips}, that chip is
* returned. If the manifest cannot be authenticated with any of the provided
* chips, NULL is returned.
*
* @discussion
* The result of calling this function on a firmware which does not have a
* manifest attached is undefined.
*
* If multiple chips may be used to authenticate the firmware, the
* implementation does not define which of those chips will be returned.
*
* If the firmware was created without the
* {@link IMG4_FIRMWARE_FLAG_SUBSEQUENT_STAGE} flag, this function will return
* NULL. This function cannot be used to establish new trust chains, only to
* verify an existing one.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200724
OS_EXPORT OS_WARN_RESULT
const img4_chip_t *_Nullable
img4_firmware_select_chip(const img4_firmware_t fw,
const img4_chip_select_array_t _Nonnull acceptable_chips,
size_t acceptable_chips_cnt);
#else
#define img4_firmware_select_chip(...) \
(img4if->i4if_v10.firmware_select_chip(__VA_ARGS__))
#endif
/*!
* @function img4_firmware_execute
* Authenticate the firmware and execute it within its context.
*
* @param fw
* The firmware to execute.
*
* @param chip
* The chip on which to execute the firmware.
*
* @param nonce
* The nonce to use for authentication. May be NULL if the chip environment does
* not maintain an anti-replay token or if a chained evaluation is being
* performed.
*
* @discussion
* The implementation will always invoke the
* {@link img4_firmware_authenticated_execute_t} provided in the execution
* context with either a successful result or a failure. All error handling must
* take place in that context.
*
* The {@link img4_firmware_authenticated_execute_t} is called before the
* implementation returns.
*
* The result of executing a firmware without a manifest attached (either via
* {@link img4_firmware_attach_manifest} or by creating the firmware with the
* {@link IMG4_FIRMWARE_FLAG_ATTACHED_MANIFEST} flag set) is undefined.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_NONNULL1 OS_NONNULL2
void
img4_firmware_execute(img4_firmware_t fw,
const img4_chip_t *chip,
const img4_nonce_t *_Nullable nonce);
#else
#define img4_firmware_execute(...) \
(img4if->i4if_v7.firmware_execute(__VA_ARGS__))
#endif
/*!
* @function img4_firmware_evaluate
* Evaluate the firmware for authenticity.
*
* @param fw
* The firmware to evaluate.
*
* @param chip
* The chip on which to evaluate the firmware.
*
* @param nonce
* The nonce to use for authentication. May be NULL if the chip environment does
* not maintain an anti-replay token or if a chained evaluation is being
* performed.
*
* @result
* An error code describing the result of the authentication. If authentication
* was successful, zero is returned. Otherwise, one of the following error codes
* will be returned:
*
* [EILSEQ] The firmware data is not valid Image4 data -- this will not
* be returned for firmwares created with
* {@link IMG4_FIRMWARE_FLAG_BARE}
* [EFTYPE] The attached manifest is not a valid Image4 manifest
* [ENOENT] The attached manifest does not authenticate this type of
* firmware
* [EAUTH] The attached manifest is not authentic (i.e. was not signed
* by an Apple CA)
* [EACCES] The given chip does not satisfy the constraints of the
* attached manifest
* [ESTALE] The manifest has been invalidated and is no longer valid for
* the provided chip
* [ENOEXEC] The firmware has been corrupted, or the given chip does not
* satisfy the constraints of the corresponding object in the
* attached manifest
*
* @discussion
* This interface should be used when the caller is only concerned with the
* authenticity and integrity of the firmware image and does not intend to
* execute it.
*
* The result of evaluating a firmware without a manifest attached (either via
* {@link img4_firmware_attach_manifest} or by creating the firmware with the
* {@link IMG4_FIRMWARE_FLAG_ATTACHED_MANIFEST} flag set) is undefined.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200608
OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2
errno_t
img4_firmware_evaluate(img4_firmware_t fw,
const img4_chip_t *chip,
const img4_nonce_t *_Nullable nonce);
#else
#define img4_firmware_evaluate(...) \
(img4if->i4if_v9.firmware_evaluate(__VA_ARGS__))
#endif
/*!
* @function img4_firmware_destroy
* Destroys a firmware object and releases the associated resources according to
* the runtime's specification.
*
* @param fw
* A pointer to the firmware object.
*
* Upon return, this will be replaced with a known-invalid pointer value. This
* parameter may be NULL in which case the implementation will return
* immediately.
*
* @discussion
* The implementation will invoke the provided deallocation function of the
* buffer object underlying the firmware.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT
void
img4_firmware_destroy(img4_firmware_t _Nonnull *_Nullable fw);
#else
#define img4_firmware_destroy(...) \
(img4if->i4if_v7.firmware_destroy(__VA_ARGS__))
#endif
OS_ASSUME_NONNULL_END
__END_DECLS;
#endif // __IMG4_FIRMWARE_H

View File

@ -0,0 +1,164 @@
/*!
* @header
* Interfaces for manipulating Image4 firmware images.
*/
#ifndef __IMG4_IMAGE_H
#define __IMG4_IMAGE_H
#ifndef __IMG4_INDIRECT
#error "Please #include <img4/firmware.h> instead of this file directly"
#endif // __IMG4_INDIRECT
#if IMG4_TAPI
#include "tapi.h"
#endif
OS_ASSUME_NONNULL_BEGIN
/*!
* @function img4_image_get_bytes
* Returns the authenticated payload from an Image4 image.
*
* @param image
* The image to query.
*
* @result
* A buffer which describes the authenticated payload.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_WARN_RESULT OS_NONNULL1
const img4_buff_t *
img4_image_get_bytes(img4_image_t image);
#else
#define img4_image_get_bytes(...) (img4if->i4if_v7.image_get_bytes(__VA_ARGS__))
#endif
/*!
* @function img4_image_get_property_bool
* Retrieves the Boolean value for the requested image property.
*
* @param image
* The image to query.
*
* @param _4cc
* The 4cc of the desired image property.
*
* @param storage
* A pointer to storage for a Boolean value.
*
* @result
* If the property is present for the image, a pointer to the storage provided
* in {@link storage}. If the property is not present in the image or its value
* is not a Boolean, NULL is returned.
*
* @discussion
* If the property is present for the image, a pointer to the storage provided
* in {@link storage}. If the property is not present in the image or its value
* is not a Boolean, NULL is returned.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL3
const bool *
img4_image_get_property_bool(img4_image_t image,
img4_4cc_t _4cc,
bool *storage);
#else
#define img4_image_get_property_bool(...) \
(img4if->i4if_v7.image_get_property_bool(__VA_ARGS__))
#endif
/*!
* @function img4_image_get_property_uint32
* Retrieves the unsigned 32-bit integer value for the requested image property.
*
* @param image
* The image to query.
*
* @param _4cc
* The 4cc of the desired image property.
*
* @param storage
* A pointer to storage for a 32-bit unsigned integer value.
*
* @result
* If the property is present for the image, a pointer to the storage provided
* in {@link storage}. If the property is not present in the image or its value
* is not an unsigned 32-bit integer, NULL is returned.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL3
const uint32_t *
img4_image_get_property_uint32(img4_image_t image,
img4_4cc_t _4cc,
uint32_t *storage);
#else
#define img4_image_get_property_uint32(...) \
(img4if->i4if_v7.image_get_property_uint32(__VA_ARGS__))
#endif
/*!
* @function img4_image_get_property_uint64
* Retrieves the unsigned 64-bit integer value for the requested image property.
*
* @param image
* The image to query.
*
* @param _4cc
* The 4cc of the desired image property.
*
* @param storage
* A pointer to storage for a 64-bit unsigned integer value.
*
* @result
* If the property is present for the image, a pointer to the storage provided
* in {@link storage}. If the property is not present in the image or its value
* is not an unsigned 64-bit integer, NULL is returned.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL3
const uint64_t *
img4_image_get_property_uint64(img4_image_t image,
img4_4cc_t _4cc,
uint64_t *storage);
#else
#define img4_image_get_property_uint64(...) \
(img4if->i4if_v7.image_get_property_uint64(__VA_ARGS__))
#endif
/*!
* @function img4_image_get_property_data
* Retrieves the buffer value for the requested image property.
*
* @param image
* The image to query.
*
* @param _4cc
* The 4cc of the desired image property.
*
* @param storage
* A pointer to storage for a buffer value.
*
* @result
* If the property is present for the image, a pointer to the storage provided
* in {@link storage}. If the property is not present in the image or its value
* is not a data, NULL is returned.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL3
const img4_buff_t *
img4_image_get_property_data(img4_image_t image,
img4_4cc_t _4cc,
img4_buff_t *storage);
#else
#define img4_image_get_property_data(...) \
(img4if->i4if_v7.image_get_property_data(__VA_ARGS__))
#endif
OS_ASSUME_NONNULL_END
#endif // __IMG4_IMAGE_H

View File

@ -0,0 +1,239 @@
/*!
* @header
* Provides an interface for managing nonces to govern the lifetime of a
* personalization performed with TSS. A nonce managed by this interface may
* be used in a TSS signing request as the value for the BNCH tag.
*
* These interfaces require the caller to possess the
*
* com.apple.private.security.AppleImage4.user-client
*
* entitlement.
*
* @section Threat Model
* The adversary possesses the following:
*
* 1. a manifest which was previously valid but has since been invalidated
* by rolling the nonce associated with it
* 2. user-level code execution
* 3. knowledge of the raw nonce value for the previously-valid manifest
*
* The defense against this adversary is a system in which knowledge of the raw
* nonce is insufficient to impact the evaluation of a personalization. This
* system has the following characteristics:
*
* 1. A nonce seed is stored in an nvram variable which is only writable by
* the kernel
* 2. When making a new signing request, the nonce seed is encrypted by a
* UID1-derived key in-kernel and then hashed -- the output of this
* operation the nonce to be used in the signing request
* 3. On boot, AppleImage4 obtains the nonce seed from nvram and stores it
* in a data structure which will be covered by KTRR
* 4. When evaluating a manifest, AppleImage4 reads the raw nonce from the
* KTRR-covered data structure and validates it with the same
* transformation as was done in (2)
* 5. When the nonce is to be invalidated, AppleImage4 sets a flag in an
* nvram variable which is only writable by the kernel
* 6. On the subsequent boot, AppleImage4 notices the flag, generates a new
* nonce and repeats the procedure in (3)
*
* In this system, the raw nonce seed never leaves the kernel, and the nonce
* itself is a non-reversible representation of the seed.
*/
#ifndef __IMG4_NONCE_H
#define __IMG4_NONCE_H
#ifndef __IMG4_INDIRECT
#error "Please #include <img4/firmware.h> instead of this file directly"
#endif // __IMG4_INDIRECT
#if IMG4_TAPI
#include "tapi.h"
#endif
/*!
* @typedef img4_nonce_domain_t
* An opaque type describing a nonce domain.
*/
IMG4_API_AVAILABLE_20181106
typedef struct _img4_nonce_domain img4_nonce_domain_t;
/*!
* @const IMG4_NONCE_STRUCT_VERSION
* The version of the {@link img4_nonce_t} structure supported by the
* implementation.
*/
#define IMG4_NONCE_STRUCT_VERSION ((img4_struct_version_t)0)
#define IMG4_NONCE_VERSION IMG4_NONCE_STRUCT_VERSION
/*!
* @const IMG4_NONCE_MAX_LENGTH
* The maximum length of a nonce. Currently, this is the length of a SHA2-384
* hash.
*/
#define IMG4_NONCE_MAX_LENGTH (48u)
/*!
* @typedef img4_nonce_t
* A structure describing a nonce.
*
* @field i4n_version
* The version of the structure. When declaring this structure, you must
* initialize this field to {@link IMG4_NONCE_VERSION}.
*
* @field i4n_nonce
* The bytes comprising the nonce.
*
* @field i4n_length
* The length of the nonce. Will be at most {@link IMG4_NONCE_MAX_LENGTH}.
*/
IMG4_API_AVAILABLE_20181106
typedef struct _img4_nonce {
img4_struct_version_t i4n_version;
const uint8_t i4n_nonce[IMG4_NONCE_MAX_LENGTH];
uint32_t i4n_length;
} img4_nonce_t;
/*!
* @const IMG4_NONCE_INIT
* A convenience initializer for {@link img4_nonce_t} which ensures that the
* {@link i4n_version} field is properly initialized.
*/
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#define IMG4_NONCE_INIT (img4_nonce_t){.i4n_version = IMG4_NONCE_STRUCT_VERSION}
#elif defined(__cplusplus) && __cplusplus >= 201103L
#define IMG4_NONCE_INIT (img4_nonce_t{IMG4_NONCE_STRUCT_VERSION})
#elif defined(__cplusplus)
#define IMG4_NONCE_INIT \
(img4_nonce_t((img4_nonce_t){IMG4_NONCE_STRUCT_VERSION}))
#else
#define IMG4_NONCE_INIT {IMG4_NONCE_STRUCT_VERSION}
#endif
/*!
* @const IMG4_NONCE_ZERO
* A convenience initializer for {@link img4_nonce_t} which initializes a 48-
* byte nonce of all zeroes.
*/
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#define IMG4_NONCE_ZERO (img4_nonce_t){ \
.i4n_version = IMG4_NONCE_STRUCT_VERSION, \
.i4n_nonce = {0}, \
.i4n_length = IMG4_NONCE_MAX_LENGTH, \
}
#endif
/*!
* @const IMG4_NONCE_DOMAIN_TRUST_CACHE
* The nonce domain governing trust cache personalizations. Use of this domain
* requires the
*
* com.apple.private.img4.nonce.trust-cache
*
* entitlement.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20181106
OS_EXPORT
const struct _img4_nonce_domain _img4_nonce_domain_trust_cache;
#define IMG4_NONCE_DOMAIN_TRUST_CACHE (&_img4_nonce_domain_trust_cache)
#else
#define IMG4_NONCE_DOMAIN_TRUST_CACHE (img4if->i4if_v1.nonce_domain_trust_cache)
#endif
/*!
* @const IMG4_NONCE_DOMAIN_PDI
* The nonce domain governing disk image personalizations. Use of this domain
* requires the
*
* com.apple.private.img4.nonce.pdi
*
* entitlement. The nonce for this domain is regenerated once every boot.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20181106
OS_EXPORT
const struct _img4_nonce_domain _img4_nonce_domain_pdi;
#define IMG4_NONCE_DOMAIN_PDI (&_img4_nonce_domain_pdi)
#else
#define IMG4_NONCE_DOMAIN_PDI (img4if->i4if_v3.nonce_domain_pdi)
#endif
/*!
* @const IMG4_NONCE_DOMAIN_CRYPTEX
* The nonce domain governing cryptex personalizations. Use of this domain
* requires the
*
* com.apple.private.img4.nonce.cryptex
*
* entitlement.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20181106
OS_EXPORT
const struct _img4_nonce_domain _img4_nonce_domain_cryptex;
#define IMG4_NONCE_DOMAIN_CRYPTEX (&_img4_nonce_domain_cryptex)
#else
#define IMG4_NONCE_DOMAIN_CRYPTEX (img4if->i4if_v3.nonce_domain_cryptex)
#endif
/*!
* @function img4_nonce_domain_copy_nonce
* Copies the current value of the nonce in the given domain.
*
* @param nd
* The nonce domain.
*
* @param n
* Upon successful return, storage that will contain the current nonce. The
* provided structure's {@link i4n_version} must be initialized to
* {@link IMG4_NONCE_VERSION}.
*
* @result
* Upon success, zero is returned. The implementation may also return one of the
* following error codes directly:
*
* [ESTALE] The nonce for the given domain has been invalidated, and the
* host must reboot in order to generate a new one
* [EPERM] The caller lacked the entitlement necessary to read the
* given nonce
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20181106
OS_EXPORT OS_WARN_RESULT OS_NONNULL1 OS_NONNULL2
errno_t
img4_nonce_domain_copy_nonce(const img4_nonce_domain_t *nd, img4_nonce_t *n);
#else
#define img4_nonce_domain_copy_nonce(...) \
(img4if->i4if_v1.nonce_domain_copy_nonce(__VA_ARGS__))
#endif
/*!
* @function img4_nonce_domain_roll_nonce
* Invalidates the current nonce for the given domain and forces a re-generation
* of the domain's nonce seed at the next boot.
*
* @param nd
* The nonce domain.
*
* @result
* Upon success, zero is returned. The kernel implementation will never return
* a non-zero code. The userspace implementation may return one of the following
* error codes directly:
*
* [EPERM] The caller lacked the entitlement necessary to roll the
* given nonce
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20181106
OS_EXPORT OS_NONNULL1
errno_t
img4_nonce_domain_roll_nonce(const img4_nonce_domain_t *nd);
#else
#define img4_nonce_domain_roll_nonce(...) \
(img4if->i4if_v1.nonce_domain_roll_nonce(__VA_ARGS__))
#endif
#endif // __IMG4_NONCE_H

View File

@ -0,0 +1,68 @@
/*!
* @header
* Image4 object specifications.
*/
#ifndef __IMG4_OBJECT_H
#define __IMG4_OBJECT_H
#ifndef __IMG4_INDIRECT
#error "Please #include <img4/firmware.h> instead of this file directly"
#endif // __IMG4_INDIRECT
#if IMG4_TAPI
#include "tapi.h"
#endif
OS_ASSUME_NONNULL_BEGIN
/*!
* @typedef img4_object_spec_t
* An opaque type which describes information about Image4 objects for use by
* the runtime.
*/
IMG4_API_AVAILABLE_20200508
typedef struct _img4_object_spec img4_object_spec_t;
/*!
* @const IMG4_FIRMWARE_SPEC
* The object specification for an {@link img4_firmware_t} object.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT
const img4_object_spec_t _img4_firmware_spec;
#define IMG4_FIRMWARE_SPEC (&_img4_firmware_spec)
#else
#define IMG4_FIRMWARE_SPEC (img4if->i4if_v7.firmware_spec)
#endif
/*!
* @const IMG4_FIRMWARE_SIZE_RECOMMENDED
* A constant describing the recommended stack allocation required for a
* {@link img4_firmware_t} object.
*/
#define IMG4_FIRMWARE_SIZE_RECOMMENDED (1280u)
/*!
* @const IMG4_CHIP_SPEC
* The object specification for an {@link img4_chip_t} object.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT
const img4_object_spec_t _img4_chip_spec;
#define IMG4_CHIP_SPEC (&_img4_chip_spec)
#else
#define IMG4_CHIP_SPEC (img4if->i4if_v7.chip_spec)
#endif
/*!
* @const IMG4_CHIP_SIZE_RECOMMENDED
* A constant describing the recommended stack allocation required for a
* {@link img4_chip_t} object.
*/
#define IMG4_CHIP_SIZE_RECOMMENDED (256u)
OS_ASSUME_NONNULL_END
#endif // __IMG4_OBJECT_H

View File

@ -0,0 +1,680 @@
/*!
* @header
* Image4 runtime interfaces.
*/
#ifndef __IMG4_RUNTIME_H
#define __IMG4_RUNTIME_H
#ifndef __IMG4_INDIRECT
#error "Please #include <img4/firmware.h> instead of this file directly"
#endif // __IMG4_INDIRECT
#if IMG4_TAPI
#include "tapi.h"
#endif
OS_ASSUME_NONNULL_BEGIN
/*!
* @typedef img4_identifier_t
* An enumeration describing identifiers in the Image4 specification.
*
* @const IMG4_IDENTIFIER_CEPO
* The chip epoch as documented in 2.1.1. Authoritative manifests will specify a
* certificate epoch which is greater than or equal to that of the chip.
*
* Unsigned 32-bit integer.
*
* @const IMG4_IDENTIFIER_BORD
* The board identifier as documented in 2.1.3. Authoritative manifests will
* specify a board identifier which is equal to that of the chip.
*
* Unsigned 32-bit integer.
*
* @const IMG4_IDENTIFIER_CHIP
* The chip identifier as documented in 2.1.2. Authoritative manifests will
* specify a chip identifier which is equal to that of the chip.
*
* Unsigned 32-bit integer.
*
* @const IMG4_IDENTIFIER_SDOM
* The security domain as documented in 2.1.5. Authoritative manifests will
* specify a security domain which is equal to that that of the chip.
*
* Unsigned 32-bit integer.
*
* @const IMG4_IDENTIFIER_ECID
* The unique chip identifier as documented in 2.1.4. Authoritative manifests
* will specify a unique chip identifier which is equal to that of the chip.
*
* Unsigned 64-bit integer.
*
* @const IMG4_IDENTIFIER_CPRO
* The certificate production status as documented in 2.1.6. Authoritative
* manifests will specify a certificate production status which is equal to that
* of the chip.
*
* Boolean.
*
* @const IMG4_IDENTIFIER_CSEC
* The certificate security mode as documented in 2.1.7. Authoritative manifests
* will specify a certificate security mode which is equal to that of the chip.
*
* Boolean.
*
* @const IMG4_IDENTIFIER_EPRO
* The effective production status as documented in 2.1.23. Unless the chip
* environment supports demotion, this will always be the same as
* {@link IMG4_IDENTIFIER_CPRO}. An executable firmware in an authoritative
* manifest will specify an EPRO object property which is equal to that of the
* chip post-demotion.
*
* Boolean.
*
* @const IMG4_IDENTIFIER_ESEC
* The effective security mode as documented in 2.1.25. Unless the chip
* environment supports demotion, this will always be the same as
* {@link IMG4_IDENTIFIER_CSEC}. An executable firmware in an authoritative
* manifest will specify an ESEC object property which is equal to that of the
* chip post-demotion.
*
* Boolean.
*
* @const IMG4_IDENTIFIER_IUOU
* The "internal use only unit" property. Indicates whether the chip is present
* on a server-side authlist which permits installing builds which are otherwise
* restricted to parts whose CPRO is 0. This property is only published by macOS
* devices whose root of trust is in an arm coprocessor (e.g. T2).
*
* Authoritative manifests will specify an internal-use-only-build property
* which, if true, is equal to the internal-use-only-unit property of the chip.
* If the internal-use-only-build property is false, then there is no constraint
* on the chip's internal-use-only-unit property.
*
* Boolean.
*
* @const IMG4_IDENTIFIER_RSCH
* The research fusing status. Indicates whether the chip is intended for
* security research to be performed by external parties. Authoritative
* manifests will specify a research fusing state which is equal to that of the
* chip.
*
* Boolean.
*
* @const IMG4_IDENTIFIER_CHMH
* The chained manifest hash from the previous stage of secure boot as described
* in 2.2.11. An authoritative manifest will either
*
* - specify a manifest hash which is equal to that of the previous secure
* boot stage's manifest
* - itself have a manifest hash which is equal to that of the previous
* secure boot stage's manifest
*
* If the previous stage of secure boot enabled mix-n-match, there is no
* constraint on the previous stage's manifest hash.
*
* Manifests which specify this property cannot be used to create new trust
* chains -- they may only extend existing ones.
*
* Digest.
*
* @const IMG4_IDENTIFIER_AMNM
* The allow-mix-n-match status of the chip. If mix-n-match is enabled, secure
* boot will permit different manifests to be used at each stage of boot. If the
* chip environment allows mix-n-match, evaluation will not require an anti-
* replay token to be specified, and any chained manifest hash constraints are
* ignored.
*
* Boolean.
*
* @const IMG4_IDENTIFIER_EUOU
* The engineering-use-only-unit status of the chip. This is in effect an alias
* for the {@link IMG4_IDENTIFIER_IUOU} property. Either property being present
* in the environment will satisfy a manifest's iuob constraint.
*
* Boolean.
*
* @const _IMG4_IDENTIFIER_CNT
* A convenience value representing the number of known identifiers.
*/
IMG4_API_AVAILABLE_20200508
OS_CLOSED_ENUM(img4_identifier, uint64_t,
IMG4_IDENTIFIER_CEPO,
IMG4_IDENTIFIER_BORD,
IMG4_IDENTIFIER_CHIP,
IMG4_IDENTIFIER_SDOM,
IMG4_IDENTIFIER_ECID,
IMG4_IDENTIFIER_CPRO,
IMG4_IDENTIFIER_CSEC,
IMG4_IDENTIFIER_EPRO,
IMG4_IDENTIFIER_ESEC,
IMG4_IDENTIFIER_IUOU,
IMG4_IDENTIFIER_RSCH,
IMG4_IDENTIFIER_CHMH,
IMG4_IDENTIFIER_AMNM,
IMG4_IDENTIFIER_EUOU,
_IMG4_IDENTIFIER_CNT,
);
/*!
* @const IMG4_DGST_STRUCT_VERSION
* The version of the {@link img4_dgst_t} structure supported by the
* implementation.
*/
#define IMG4_DGST_STRUCT_VERSION (0u)
/*!
* @const IMG4_DGST_MAX_LEN
* The maximum length of a digest representable by an {@link img4_dgst_t}.
*/
#define IMG4_DGST_MAX_LEN (48u)
/*!
* @typedef img4_dgst_t
* A structure representing an Image4 digest.
*
* @field i4d_len
* The version of the structure. Initialize to {@link IMG4_DGST_STRUCT_VERSION}.
*
* @field i4d_len
* The length of the digest.
*
* @field i4d_bytes
* The digest bytes.
*/
IMG4_API_AVAILABLE_20200508
typedef struct _img4_dgst {
img4_struct_version_t i4d_version;
size_t i4d_len;
uint8_t i4d_bytes[IMG4_DGST_MAX_LEN];
} img4_dgst_t;
/*!
* @const IMG4_DGST_INIT
* A convenience initializer for an {@link img4_dgst_t} structure.
*/
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#define IMG4_DGST_INIT (img4_dgst_t){ \
.i4d_version = IMG4_DGST_STRUCT_VERSION, \
.i4d_len = 0, \
.i4d_bytes = {0}, \
}
#elif defined(__cplusplus) && __cplusplus >= 201103L
#define IMG4_DGST_INIT (img4_nonce_t{ \
IMG4_DGST_STRUCT_VERSION, \
0, \
{0}, \
})
#elif defined(__cplusplus)
#define IMG4_DGST_INIT (img4_nonce_t((img4_nonce_t){ \
IMG4_DGST_STRUCT_VERSION, \
0, \
{0}, \
}))
#else
#define IMG4_DGST_INIT {IMG4_DGST_STRUCT_VERSION}
#endif
/*!
* @typedef img4_runtime_init_t
* A function which initializes the runtime.
*
* @param rt
* The runtime for which the function is being invoked.
*
* @discussion
* This function is called by the implementation prior to any other runtime
* function being called. The implementation will ensure that it is called only
* once. Any runtime with an initialization function must be registered with the
* {@link IMG4_RUNTIME_REGISTER} macro.
*/
IMG4_API_AVAILABLE_20200508
typedef void (*img4_runtime_init_t)(
const img4_runtime_t *rt
);
/*!
* @typedef img4_runtime_alloc_t
* An allocation function.
*
* @param rt
* The runtime for which the function is being invoked.
*
* @param n
* The number of bytes to allocate.
*
* @result
* A pointer to the new allocation, or NULL if there was an allocation failure.
*/
IMG4_API_AVAILABLE_20200508
typedef void *_Nullable (*img4_runtime_alloc_t)(
const img4_runtime_t *rt,
size_t n
);
/*!
* @typedef img4_runtime_dealloc_t
* A deallocation function.
*
* @param rt
* The runtime for which the function is being invoked.
*
* @param p
* A pointer to the allocation to free. The callee is expected to return
* immediately if NULL is passed.
*
* @param n
* The size of the allocation. Not all implementation may require this
* information to be specified.
*/
IMG4_API_AVAILABLE_20200508
typedef void (*img4_runtime_dealloc_t)(
const img4_runtime_t *rt,
void *_Nullable p,
size_t n
);
/*!
* @typedef img4_log_level_t
* An enumeration describing the importance/severity of a log message.
*
* @const IMG4_LOG_LEVEL_ERROR
* A fatal condition which will cause the implementation to abort its current
* operation.
*
* @const IMG4_LOG_LEVEL_INFO
* Information that may be of interest to the system operator.
*
* @const IMG4_LOG_LEVEL_DEBUG
* Information that may be of interest to the maintainer.
*
* @const _IMG4_LOG_LEVEL_CNT
* A convenience constant indicating the number of log levels.
*/
IMG4_API_AVAILABLE_20200508
OS_CLOSED_ENUM(img4_log_level, uint64_t,
IMG4_LOG_LEVEL_ERROR,
IMG4_LOG_LEVEL_INFO,
IMG4_LOG_LEVEL_DEBUG,
_IMG4_LOG_LEVEL_CNT,
);
/*!
* @typedef img4_runtime_log_t
* A function which writes log messages.
*
* @param rt
* The runtime for which the function is being invoked.
*
* @param handle
* An implementation-specific handle for the log message.
*
* @param level
* The message of the log level. The implementation is free to determine whether
* a given message is worthy of record.
*
* @param fmt
* A printf(3)-style format string.
*
* @param ...
* Arguments to be interpreted by the format string according to the
* specifications in printf(3).
*/
OS_FORMAT_PRINTF(4, 5)
IMG4_API_AVAILABLE_20200508
typedef void (*img4_runtime_log_t)(
const img4_runtime_t *rt,
void *_Nullable handle,
img4_log_level_t level,
const char *fmt,
...
);
/*!
* @typedef img4_runtime_log_handle_t
* A function which returns a log handle.
*
* @param rt
* The runtime for which the function is being invoked.
*
* @result
* A runtime-specific log handle that will be passed to the logging function.
*/
IMG4_API_AVAILABLE_20200508
typedef void *_Nullable (*img4_runtime_log_handle_t)(
const img4_runtime_t *rt
);
/*!
* @typedef img4_runtime_get_identifier_bool_t
* A function which retrieves a Boolean Image4 identifier.
*
* @param rt
* The runtime for which the function is being invoked.
*
* @param chip
* The chip for which to retrieve the identifier.
*
* @param identifier
* The identifier to retrieve.
*
* @param value
* Upon successful return, storage which is populated with the retrieved value.
*
* @result
* Upon success, the callee is expected to return zero. Otherwise, the callee
* may return one of the following error codes:
*
* [ENOTSUP] The identifier cannot be queried in the runtime
* [ENOENT] The identifier was not found in the runtime's identity
* oracle
* [ENODEV] There was an error querying the runtime's identity oracle
*/
IMG4_API_AVAILABLE_20200508
typedef errno_t (*img4_runtime_get_identifier_bool_t)(
const img4_runtime_t *rt,
const img4_chip_t *chip,
img4_identifier_t identifier,
bool *value
);
/*!
* @typedef img4_runtime_get_identifier_uint32_t
* A function which retrieves an unsigned 32-bit integer Image4 identifier.
*
* @param rt
* The runtime for which the function is being invoked.
*
* @param chip
* The chip for which to retrieve the identifier.
*
* @param identifier
* The identifier to retrieve.
*
* @param value
* Upon successful return, storage which is populated with the retrieved value.
*
* @result
* Upon success, the callee is expected to return zero. Otherwise, the callee
* may return one of the following error codes:
*
* [ENOTSUP] The identifier cannot be queried in the runtime
* [ENOENT] The identifier was not found in the runtime's identity
* oracle
* [ENODEV] There was an error querying the runtime's identity oracle
*/
IMG4_API_AVAILABLE_20200508
typedef errno_t (*img4_runtime_get_identifier_uint32_t)(
const img4_runtime_t *rt,
const img4_chip_t *chip,
img4_identifier_t identifier,
uint32_t *value
);
/*!
* @typedef img4_runtime_get_identifier_uint64_t
* A function which retrieves an unsigned 64-bit integer Image4 identifier.
*
* @param rt
* The runtime for which the function is being invoked.
*
* @param chip
* The chip for which to retrieve the identifier.
*
* @param identifier
* The identifier to retrieve.
*
* @param value
* Upon successful return, storage which is populated with the retrieved value.
*
* @result
* Upon success, the callee is expected to return zero. Otherwise, the callee
* may return one of the following error codes:
*
* [ENOTSUP] The identifier cannot be queried in the runtime
* [ENOENT] The identifier was not found in the runtime's identity
* oracle
* [ENODEV] There was an error querying the runtime's identity oracle
*/
IMG4_API_AVAILABLE_20200508
typedef errno_t (*img4_runtime_get_identifier_uint64_t)(
const img4_runtime_t *rt,
const img4_chip_t *chip,
img4_identifier_t identifier,
uint64_t *value
);
/*!
* @typedef img4_runtime_get_identifier_digest_t
* A function which retrieves a digest Image4 identifier.
*
* @param rt
* The runtime for which the function is being invoked.
*
* @param chip
* The chip for which to retrieve the identifier.
*
* @param identifier
* The identifier to retrieve.
*
* @param value
* Upon successful return, storage which is populated with the retrieved value.
*
* @result
* Upon success, the callee is expected to return zero. Otherwise, the callee
* may return one of the following error codes:
*
* [ENOTSUP] The identifier cannot be queried in the runtime
* [ENOENT] The identifier was not found in the runtime's identity
* oracle
* [ENODEV] There was an error querying the runtime's identity oracle
*/
IMG4_API_AVAILABLE_20200508
typedef errno_t (*img4_runtime_get_identifier_digest_t)(
const img4_runtime_t *rt,
const img4_chip_t *chip,
img4_identifier_t identifier,
img4_dgst_t *value
);
/*!
* @define IMG4_BUFF_STRUCT_VERSION
* The version of the {@link img4_buff_t} structure supported by the
* implementation.
*/
#define IMG4_BUFF_STRUCT_VERSION (0u)
/*!
* @struct _img4_buff
* A structure describing a buffer.
*
* @field i4b_version
* The version of the structure. Initialize to {@link IMG4_BUFF_STRUCT_VERSION}.
*
* @field i4b_bytes
* A pointer to the buffer.
*
* @field i4b_len
* The length of the buffer.
*
* @field i4b_dealloc
* The deallocation function for the buffer. May be NULL if the underlying
* memory does not require cleanup. When the implementation invokes this
* function, it will always pass {@link IMG4_RUNTIME_DEFAULT}, and the callee
* should not consult this parameter for any reason.
*/
struct _img4_buff {
img4_struct_version_t i4b_version;
uint8_t *i4b_bytes;
size_t i4b_len;
img4_runtime_dealloc_t _Nullable i4b_dealloc;
} IMG4_API_AVAILABLE_20200508;
/*!
* @const IMG4_BUFF_INIT
* A convenience initializer for the {@link img4_buff_t} structure.
*/
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#define IMG4_BUFF_INIT (img4_buff_t){ \
.i4b_version = IMG4_BUFF_STRUCT_VERSION, \
.i4b_len = 0, \
.i4b_bytes = NULL, \
.i4b_dealloc = NULL, \
}
#elif defined(__cplusplus) && __cplusplus >= 201103L
#define IMG4_BUFF_INIT (img4_buff_t{ \
IMG4_BUFF_STRUCT_VERSION, \
NULL, \
0, \
NULL, \
})
#elif defined(__cplusplus)
#define IMG4_BUFF_INIT (img4_buff_t((img4_buff_t){ \
IMG4_BUFF_STRUCT_VERSION, \
NULL, \
0, \
NULL, \
}))
#else
#define IMG4_BUFF_INIT {IMG4_BUFF_STRUCT_VERSION}
#endif
/*!
* @define IMG4_RUNTIME_STRUCT_VERSION
* The version of the {@link img4_runtime_t} structure supported by the
* implementation.
*/
#define IMG4_RUNTIME_STRUCT_VERSION (1u)
/*!
* @struct _img4_runtime
* A structure describing required primitives in the operating environment's
* runtime.
*
* @field i4rt_version
* The version of the structure supported by the implementation. In a custom
* execution context, initialize to {@link IMG4_RUNTIME_STRUCT_VERSION}.
*
* @field i4rt_name
* A string describing the environment.
*
* @field i4rt_init
* The runtime initialization function. See discussion in
* {@link img4_runtime_init_t}.
*
* @field i4rt_alloc
* The allocation function for the environment (e.g. in Darwin userspace, this
* would be a pointer to malloc(3)).
*
* @field i4rt_dealloc
* The deallocation function for the environment (e.g. in Darwin userspace, this
* would be a pointer to free(3)).
*
* @field i4rt_log
* The function which logs messages from the implementation.
*
* @field i4rt_log_handle
* The function which returns the handle to be passed to the logging function.
*
* @field i4rt_get_identifier_bool
* The function which returns Boolean identifiers.
*
* @field i4rt_get_identifier_uint32
* The function which returns unsigned 32-bit integer identifiers.
*
* @field i4rt_get_identifier_uint64
* The function which returns unsigned 64-bit integer identifiers.
*
* @field i4rt_get_identifier_digest
* The function which returns digest identifiers.
*
* @field i4rt_context
* A user-defined context pointer.
*/
struct _img4_runtime {
img4_struct_version_t i4rt_version;
const char *i4rt_name;
img4_runtime_init_t _Nullable i4rt_init;
img4_runtime_alloc_t i4rt_alloc;
img4_runtime_dealloc_t i4rt_dealloc;
img4_runtime_log_t i4rt_log;
img4_runtime_log_handle_t i4rt_log_handle;
img4_runtime_get_identifier_bool_t i4rt_get_identifier_bool;
img4_runtime_get_identifier_uint32_t i4rt_get_identifier_uint32;
img4_runtime_get_identifier_uint64_t i4rt_get_identifier_uint64;
img4_runtime_get_identifier_digest_t i4rt_get_identifier_digest;
void *_Nullable i4rt_context;
} IMG4_API_AVAILABLE_20200508;
/*!
* @function IMG4_RUNTIME_REGISTER
* Registers a runtime with the module implementation such that its
* initialization function can be called. In environments which support dynamic
* library linkage, only runtimes registered from the main executable image can
* be discovered by the implementation.
*
* @param _rt
* The img4_runtime_t structure to register.
*/
#define IMG4_RUNTIME_REGISTER(_rt) LINKER_SET_ENTRY(__img4_rt, _rt);
/*!
* @const IMG4_RUNTIME_DEFAULT
* The default runtime for the current operating environment.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT
const img4_runtime_t _img4_runtime_default;
#define IMG4_RUNTIME_DEFAULT (&_img4_runtime_default)
#else
#define IMG4_RUNTIME_DEFAULT (img4if->i4if_v7.runtime_default)
#endif
/*!
* @const IMG4_RUNTIME_PMAP_CS
* The runtime for the xnu pmap monitor. This runtime is not available outside
* the kernel-proper. On architectures which do not have an xnu monitor, this
* is merely an alias for the default kernel runtime.
*/
#if XNU_KERNEL_PRIVATE
#define IMG4_RUNTIME_PMAP_CS (img4if->i4if_v7.runtime_pmap_cs)
#endif
/*!
* @const IMG4_RUNTIME_RESTORE
* The runtime for the restore ramdisk. This runtime is not available outside
* of the Darwin userspace library.
*/
#if !KERNEL
IMG4_API_AVAILABLE_20200508
OS_EXPORT
const img4_runtime_t _img4_runtime_restore;
#define IMG4_RUNTIME_RESTORE (&_img4_runtime_restore)
#endif
/*!
* @function img4_buff_dealloc
* Deallocates a buffer according to its deallocation function.
*
* @param buff
* A pointer to the a pointer to the buffer. This parameter may be NULL, in
* which case the implementation will return immediately.
*
* @discussion
* This interface will always invoke the deallocation callback with
* {@link IMG4_RUNTIME_DEFAULT}. The callee should not consult this parameter
* for any reason.
*/
#if !XNU_KERNEL_PRIVATE
IMG4_API_AVAILABLE_20200508
OS_EXPORT
void
img4_buff_dealloc(img4_buff_t *_Nullable buff);
#else
#define img4_buff_dealloc(...) (img4if->i4if_v7.buff_dealloc(__VA_ARGS__))
#endif
OS_ASSUME_NONNULL_END
#endif // __IMG4_RUNTIME_H

View File

@ -0,0 +1,25 @@
export MakeInc_cmd=${SRCROOT}/makedefs/MakeInc.cmd
export MakeInc_def=${SRCROOT}/makedefs/MakeInc.def
export MakeInc_rule=${SRCROOT}/makedefs/MakeInc.rule
export MakeInc_dir=${SRCROOT}/makedefs/MakeInc.dir
include $(MakeInc_cmd)
include $(MakeInc_def)
EXPORT_FILES = \
fat.h \
fixup-chains.h \
loader.h \
nlist.h \
reloc.h
INSTALL_MI_LIST =
INSTALL_MI_DIR =
EXPORT_MI_LIST = ${EXPORT_FILES}
EXPORT_MI_DIR = mach-o
include $(MakeInc_rule)
include $(MakeInc_dir)

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Relocation types used in the arm implementation. Relocation entries for
* things other than instructions use the same generic relocation as discribed
* in <mach-o/reloc.h> and their r_type is ARM_RELOC_VANILLA, one of the
* *_SECTDIFF or the *_PB_LA_PTR types. The rest of the relocation types are
* for instructions. Since they are for instructions the r_address field
* indicates the 32 bit instruction that the relocation is to be preformed on.
*/
enum reloc_type_arm
{
ARM_RELOC_VANILLA, /* generic relocation as discribed above */
ARM_RELOC_PAIR, /* the second relocation entry of a pair */
ARM_RELOC_SECTDIFF, /* a PAIR follows with subtract symbol value */
ARM_RELOC_LOCAL_SECTDIFF, /* like ARM_RELOC_SECTDIFF, but the symbol
referenced was local. */
ARM_RELOC_PB_LA_PTR,/* prebound lazy pointer */
ARM_RELOC_BR24, /* 24 bit branch displacement (to a word address) */
ARM_THUMB_RELOC_BR22, /* 22 bit branch displacement (to a half-word
address) */
ARM_THUMB_32BIT_BRANCH, /* obsolete - a thumb 32-bit branch instruction
possibly needing page-spanning branch workaround */
/*
* For these two r_type relocations they always have a pair following them
* and the r_length bits are used differently. The encoding of the
* r_length is as follows:
* low bit of r_length:
* 0 - :lower16: for movw instructions
* 1 - :upper16: for movt instructions
* high bit of r_length:
* 0 - arm instructions
* 1 - thumb instructions
* the other half of the relocated expression is in the following pair
* relocation entry in the the low 16 bits of r_address field.
*/
ARM_RELOC_HALF,
ARM_RELOC_HALF_SECTDIFF
};

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2010 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Relocation types used in the arm64 implementation.
*/
enum reloc_type_arm64
{
ARM64_RELOC_UNSIGNED, // for pointers
ARM64_RELOC_SUBTRACTOR, // must be followed by a ARM64_RELOC_UNSIGNED
ARM64_RELOC_BRANCH26, // a B/BL instruction with 26-bit displacement
ARM64_RELOC_PAGE21, // pc-rel distance to page of target
ARM64_RELOC_PAGEOFF12, // offset within page, scaled by r_length
ARM64_RELOC_GOT_LOAD_PAGE21, // pc-rel distance to page of GOT slot
ARM64_RELOC_GOT_LOAD_PAGEOFF12, // offset within page of GOT slot,
// scaled by r_length
ARM64_RELOC_POINTER_TO_GOT, // for pointers to GOT slots
ARM64_RELOC_TLVP_LOAD_PAGE21, // pc-rel distance to page of TLVP slot
ARM64_RELOC_TLVP_LOAD_PAGEOFF12, // offset within page of TLVP slot,
// scaled by r_length
ARM64_RELOC_ADDEND // must be followed by PAGE21 or PAGEOFF12
};

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef _MACH_O_FAT_H_
#define _MACH_O_FAT_H_
/*
* This header file describes the structures of the file format for "fat"
* architecture specific file (wrapper design). At the begining of the file
* there is one fat_header structure followed by a number of fat_arch
* structures. For each architecture in the file, specified by a pair of
* cputype and cpusubtype, the fat_header describes the file offset, file
* size and alignment in the file of the architecture specific member.
* The padded bytes in the file to place each member on it's specific alignment
* are defined to be read as zeros and can be left as "holes" if the file system
* can support them as long as they read as zeros.
*
* All structures defined here are always written and read to/from disk
* in big-endian order.
*/
/*
* <mach/machine.h> is needed here for the cpu_type_t and cpu_subtype_t types
* and contains the constants for the possible values of these types.
*/
#include <stdint.h>
#include <mach/machine.h>
#include <architecture/byte_order.h>
#define FAT_MAGIC 0xcafebabe
#define FAT_CIGAM 0xbebafeca /* NXSwapLong(FAT_MAGIC) */
struct fat_header {
uint32_t magic; /* FAT_MAGIC */
uint32_t nfat_arch; /* number of structs that follow */
};
struct fat_arch {
cpu_type_t cputype; /* cpu specifier (int) */
cpu_subtype_t cpusubtype; /* machine specifier (int) */
uint32_t offset; /* file offset to this object file */
uint32_t size; /* size of this object file */
uint32_t align; /* alignment as a power of 2 */
};
#endif /* _MACH_O_FAT_H_ */

View File

@ -0,0 +1,257 @@
/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
*
* Copyright (c) 2018 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef __MACH_O_FIXUP_CHAINS__
#define __MACH_O_FIXUP_CHAINS__ 5
#include <stdint.h>
//#define LC_DYLD_EXPORTS_TRIE 0x80000033 // used with linkedit_data_command
//#define LC_DYLD_CHAINED_FIXUPS 0x80000034 // used with linkedit_data_command, payload is dyld_chained_fixups_header
// header of the LC_DYLD_CHAINED_FIXUPS payload
struct dyld_chained_fixups_header
{
uint32_t fixups_version; // 0
uint32_t starts_offset; // offset of dyld_chained_starts_in_image in chain_data
uint32_t imports_offset; // offset of imports table in chain_data
uint32_t symbols_offset; // offset of symbol strings in chain_data
uint32_t imports_count; // number of imported symbol names
uint32_t imports_format; // DYLD_CHAINED_IMPORT*
uint32_t symbols_format; // 0 => uncompressed, 1 => zlib compressed
};
// This struct is embedded in LC_DYLD_CHAINED_FIXUPS payload
struct dyld_chained_starts_in_image
{
uint32_t seg_count;
uint32_t seg_info_offset[1]; // each entry is offset into this struct for that segment
// followed by pool of dyld_chain_starts_in_segment data
};
// This struct is embedded in dyld_chain_starts_in_image
// and passed down to the kernel for page-in linking
struct dyld_chained_starts_in_segment
{
uint32_t size; // size of this (amount kernel needs to copy)
uint16_t page_size; // 0x1000 or 0x4000
uint16_t pointer_format; // DYLD_CHAINED_PTR_*
uint64_t segment_offset; // offset in memory to start of segment
uint32_t max_valid_pointer; // for 32-bit OS, any value beyond this is not a pointer
uint16_t page_count; // how many pages are in array
uint16_t page_start[1]; // each entry is offset in each page of first element in chain
// or DYLD_CHAINED_PTR_START_NONE if no fixups on page
// uint16_t chain_starts[1]; // some 32-bit formats may require multiple starts per page.
// for those, if high bit is set in page_starts[], then it
// is index into chain_starts[] which is a list of starts
// the last of which has the high bit set
};
enum {
DYLD_CHAINED_PTR_START_NONE = 0xFFFF, // used in page_start[] to denote a page with no fixups
DYLD_CHAINED_PTR_START_MULTI = 0x8000, // used in page_start[] to denote a page which has multiple starts
DYLD_CHAINED_PTR_START_LAST = 0x8000, // used in chain_starts[] to denote last start in list for page
};
// This struct is embedded in __TEXT,__chain_starts section in firmware
struct dyld_chained_starts_offsets
{
uint32_t pointer_format; // DYLD_CHAINED_PTR_32_FIRMWARE
uint32_t starts_count; // number of starts in array
uint32_t chain_starts[1]; // array chain start offsets
};
// values for dyld_chained_starts_in_segment.pointer_format
enum {
DYLD_CHAINED_PTR_ARM64E = 1, // stride 8, unauth target is vmaddr
DYLD_CHAINED_PTR_64 = 2, // target is vmaddr
DYLD_CHAINED_PTR_32 = 3,
DYLD_CHAINED_PTR_32_CACHE = 4,
DYLD_CHAINED_PTR_32_FIRMWARE = 5,
DYLD_CHAINED_PTR_64_OFFSET = 6, // target is vm offset
DYLD_CHAINED_PTR_ARM64E_OFFSET = 7, // old name
DYLD_CHAINED_PTR_ARM64E_KERNEL = 7, // stride 4, unauth target is vm offset
DYLD_CHAINED_PTR_64_KERNEL_CACHE = 8,
DYLD_CHAINED_PTR_ARM64E_USERLAND = 9, // stride 8, unauth target is vm offset
DYLD_CHAINED_PTR_ARM64E_FIRMWARE = 10, // stride 4, unauth target is vmaddr
DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE = 11, // stride 1, x86_64 kernel caches
};
// DYLD_CHAINED_PTR_ARM64E
struct dyld_chained_ptr_arm64e_rebase
{
uint64_t target : 43,
high8 : 8,
next : 11, // 4 or 8-byte stide
bind : 1, // == 0
auth : 1; // == 0
};
// DYLD_CHAINED_PTR_ARM64E
struct dyld_chained_ptr_arm64e_bind
{
uint64_t ordinal : 16,
zero : 16,
addend : 19, // +/-256K
next : 11, // 4 or 8-byte stide
bind : 1, // == 1
auth : 1; // == 0
};
// DYLD_CHAINED_PTR_ARM64E
struct dyld_chained_ptr_arm64e_auth_rebase
{
uint64_t target : 32, // runtimeOffset
diversity : 16,
addrDiv : 1,
key : 2,
next : 11, // 4 or 8-byte stide
bind : 1, // == 0
auth : 1; // == 1
};
// DYLD_CHAINED_PTR_ARM64E
struct dyld_chained_ptr_arm64e_auth_bind
{
uint64_t ordinal : 16,
zero : 16,
diversity : 16,
addrDiv : 1,
key : 2,
next : 11, // 4 or 8-byte stide
bind : 1, // == 1
auth : 1; // == 1
};
// DYLD_CHAINED_PTR_64/DYLD_CHAINED_PTR_64_OFFSET
struct dyld_chained_ptr_64_rebase
{
uint64_t target : 36, // 64GB max image size (DYLD_CHAINED_PTR_64 => vmAddr, DYLD_CHAINED_PTR_64_OFFSET => runtimeOffset)
high8 : 8, // top 8 bits set to this (DYLD_CHAINED_PTR_64 => after slide added, DYLD_CHAINED_PTR_64_OFFSET => before slide added)
reserved : 7, // all zeros
next : 12, // 4-byte stride
bind : 1; // == 0
};
// DYLD_CHAINED_PTR_64
struct dyld_chained_ptr_64_bind
{
uint64_t ordinal : 24,
addend : 8, // 0 thru 255
reserved : 19, // all zeros
next : 12, // 4-byte stride
bind : 1; // == 1
};
// DYLD_CHAINED_PTR_64_KERNEL_CACHE, DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE
struct dyld_chained_ptr_64_kernel_cache_rebase
{
uint64_t target : 30, // basePointers[cacheLevel] + target
cacheLevel : 2, // what level of cache to bind to (indexes a mach_header array)
diversity : 16,
addrDiv : 1,
key : 2,
next : 12, // 1 or 4-byte stide
isAuth : 1; // 0 -> not authenticated. 1 -> authenticated
};
// DYLD_CHAINED_PTR_32
// Note: for DYLD_CHAINED_PTR_32 some non-pointer values are co-opted into the chain
// as out of range rebases. If an entry in the chain is > max_valid_pointer, then it
// is not a pointer. To restore the value, subtract off the bias, which is
// (64MB+max_valid_pointer)/2.
struct dyld_chained_ptr_32_rebase
{
uint32_t target : 26, // vmaddr, 64MB max image size
next : 5, // 4-byte stride
bind : 1; // == 0
};
// DYLD_CHAINED_PTR_32
struct dyld_chained_ptr_32_bind
{
uint32_t ordinal : 20,
addend : 6, // 0 thru 63
next : 5, // 4-byte stride
bind : 1; // == 1
};
// DYLD_CHAINED_PTR_32_CACHE
struct dyld_chained_ptr_32_cache_rebase
{
uint32_t target : 30, // 1GB max dyld cache TEXT and DATA
next : 2; // 4-byte stride
};
// DYLD_CHAINED_PTR_32_FIRMWARE
struct dyld_chained_ptr_32_firmware_rebase
{
uint32_t target : 26, // 64MB max firmware TEXT and DATA
next : 6; // 4-byte stride
};
// values for dyld_chained_fixups_header.imports_format
enum {
DYLD_CHAINED_IMPORT = 1,
DYLD_CHAINED_IMPORT_ADDEND = 2,
DYLD_CHAINED_IMPORT_ADDEND64 = 3,
};
// DYLD_CHAINED_IMPORT
struct dyld_chained_import
{
uint32_t lib_ordinal : 8,
weak_import : 1,
name_offset : 23;
};
// DYLD_CHAINED_IMPORT_ADDEND
struct dyld_chained_import_addend
{
uint32_t lib_ordinal : 8,
weak_import : 1,
name_offset : 23;
int32_t addend;
};
// DYLD_CHAINED_IMPORT_ADDEND64
struct dyld_chained_import_addend64
{
uint64_t lib_ordinal : 16,
weak_import : 1,
reserved : 15,
name_offset : 32;
uint64_t addend;
};
#endif // __MACH_O_FIXUP_CHAINS__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,318 @@
/*
* Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef _MACHO_NLIST_H_
#define _MACHO_NLIST_H_
/* $NetBSD: nlist.h,v 1.5 1994/10/26 00:56:11 cgd Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nlist.h 8.2 (Berkeley) 1/21/94
*/
#include <stdint.h>
/*
* Format of a symbol table entry of a Mach-O file for 32-bit architectures.
* Modified from the BSD format. The modifications from the original format
* were changing n_other (an unused field) to n_sect and the addition of the
* N_SECT type. These modifications are required to support symbols in a larger
* number of sections not just the three sections (text, data and bss) in a BSD
* file.
*/
struct nlist {
union {
#ifndef __LP64__
char *n_name; /* for use when in-core */
#endif
uint32_t n_strx; /* index into the string table */
} n_un;
uint8_t n_type; /* type flag, see below */
uint8_t n_sect; /* section number or NO_SECT */
int16_t n_desc; /* see <mach-o/stab.h> */
uint32_t n_value; /* value of this symbol (or stab offset) */
};
/*
* This is the symbol table entry structure for 64-bit architectures.
*/
struct nlist_64 {
union {
uint32_t n_strx; /* index into the string table */
} n_un;
uint8_t n_type; /* type flag, see below */
uint8_t n_sect; /* section number or NO_SECT */
uint16_t n_desc; /* see <mach-o/stab.h> */
uint64_t n_value; /* value of this symbol (or stab offset) */
};
/*
* Symbols with a index into the string table of zero (n_un.n_strx == 0) are
* defined to have a null, "", name. Therefore all string indexes to non null
* names must not have a zero string index. This is bit historical information
* that has never been well documented.
*/
/*
* The n_type field really contains four fields:
* unsigned char N_STAB:3,
* N_PEXT:1,
* N_TYPE:3,
* N_EXT:1;
* which are used via the following masks.
*/
#define N_STAB 0xe0 /* if any of these bits set, a symbolic debugging entry */
#define N_PEXT 0x10 /* private external symbol bit */
#define N_TYPE 0x0e /* mask for the type bits */
#define N_EXT 0x01 /* external symbol bit, set for external symbols */
/*
* Only symbolic debugging entries have some of the N_STAB bits set and if any
* of these bits are set then it is a symbolic debugging entry (a stab). In
* which case then the values of the n_type field (the entire field) are given
* in <mach-o/stab.h>
*/
/*
* Values for N_TYPE bits of the n_type field.
*/
#define N_UNDF 0x0 /* undefined, n_sect == NO_SECT */
#define N_ABS 0x2 /* absolute, n_sect == NO_SECT */
#define N_SECT 0xe /* defined in section number n_sect */
#define N_PBUD 0xc /* prebound undefined (defined in a dylib) */
#define N_INDR 0xa /* indirect */
/*
* If the type is N_INDR then the symbol is defined to be the same as another
* symbol. In this case the n_value field is an index into the string table
* of the other symbol's name. When the other symbol is defined then they both
* take on the defined type and value.
*/
/*
* If the type is N_SECT then the n_sect field contains an ordinal of the
* section the symbol is defined in. The sections are numbered from 1 and
* refer to sections in order they appear in the load commands for the file
* they are in. This means the same ordinal may very well refer to different
* sections in different files.
*
* The n_value field for all symbol table entries (including N_STAB's) gets
* updated by the link editor based on the value of it's n_sect field and where
* the section n_sect references gets relocated. If the value of the n_sect
* field is NO_SECT then it's n_value field is not changed by the link editor.
*/
#define NO_SECT 0 /* symbol is not in any section */
#define MAX_SECT 255 /* 1 thru 255 inclusive */
/*
* Common symbols are represented by undefined (N_UNDF) external (N_EXT) types
* who's values (n_value) are non-zero. In which case the value of the n_value
* field is the size (in bytes) of the common symbol. The n_sect field is set
* to NO_SECT. The alignment of a common symbol may be set as a power of 2
* between 2^1 and 2^15 as part of the n_desc field using the macros below. If
* the alignment is not set (a value of zero) then natural alignment based on
* the size is used.
*/
#define GET_COMM_ALIGN(n_desc) (((n_desc) >> 8) & 0x0f)
#define SET_COMM_ALIGN(n_desc,align) \
(n_desc) = (((n_desc) & 0xf0ff) | (((align) & 0x0f) << 8))
/*
* To support the lazy binding of undefined symbols in the dynamic link-editor,
* the undefined symbols in the symbol table (the nlist structures) are marked
* with the indication if the undefined reference is a lazy reference or
* non-lazy reference. If both a non-lazy reference and a lazy reference is
* made to the same symbol the non-lazy reference takes precedence. A reference
* is lazy only when all references to that symbol are made through a symbol
* pointer in a lazy symbol pointer section.
*
* The implementation of marking nlist structures in the symbol table for
* undefined symbols will be to use some of the bits of the n_desc field as a
* reference type. The mask REFERENCE_TYPE will be applied to the n_desc field
* of an nlist structure for an undefined symbol to determine the type of
* undefined reference (lazy or non-lazy).
*
* The constants for the REFERENCE FLAGS are propagated to the reference table
* in a shared library file. In that case the constant for a defined symbol,
* REFERENCE_FLAG_DEFINED, is also used.
*/
/* Reference type bits of the n_desc field of undefined symbols */
#define REFERENCE_TYPE 0x7
/* types of references */
#define REFERENCE_FLAG_UNDEFINED_NON_LAZY 0
#define REFERENCE_FLAG_UNDEFINED_LAZY 1
#define REFERENCE_FLAG_DEFINED 2
#define REFERENCE_FLAG_PRIVATE_DEFINED 3
#define REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY 4
#define REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY 5
/*
* To simplify stripping of objects that use are used with the dynamic link
* editor, the static link editor marks the symbols defined an object that are
* referenced by a dynamicly bound object (dynamic shared libraries, bundles).
* With this marking strip knows not to strip these symbols.
*/
#define REFERENCED_DYNAMICALLY 0x0010
/*
* For images created by the static link editor with the -twolevel_namespace
* option in effect the flags field of the mach header is marked with
* MH_TWOLEVEL. And the binding of the undefined references of the image are
* determined by the static link editor. Which library an undefined symbol is
* bound to is recorded by the static linker in the high 8 bits of the n_desc
* field using the SET_LIBRARY_ORDINAL macro below. The ordinal recorded
* references the libraries listed in the Mach-O's LC_LOAD_DYLIB,
* LC_LOAD_WEAK_DYLIB, LC_REEXPORT_DYLIB, LC_LOAD_UPWARD_DYLIB, and
* LC_LAZY_LOAD_DYLIB, etc. load commands in the order they appear in the
* headers. The library ordinals start from 1.
* For a dynamic library that is built as a two-level namespace image the
* undefined references from module defined in another use the same nlist struct
* an in that case SELF_LIBRARY_ORDINAL is used as the library ordinal. For
* defined symbols in all images they also must have the library ordinal set to
* SELF_LIBRARY_ORDINAL. The EXECUTABLE_ORDINAL refers to the executable
* image for references from plugins that refer to the executable that loads
* them.
*
* The DYNAMIC_LOOKUP_ORDINAL is for undefined symbols in a two-level namespace
* image that are looked up by the dynamic linker with flat namespace semantics.
* This ordinal was added as a feature in Mac OS X 10.3 by reducing the
* value of MAX_LIBRARY_ORDINAL by one. So it is legal for existing binaries
* or binaries built with older tools to have 0xfe (254) dynamic libraries. In
* this case the ordinal value 0xfe (254) must be treated as a library ordinal
* for compatibility.
*/
#define GET_LIBRARY_ORDINAL(n_desc) (((n_desc) >> 8) & 0xff)
#define SET_LIBRARY_ORDINAL(n_desc,ordinal) \
(n_desc) = (((n_desc) & 0x00ff) | (((ordinal) & 0xff) << 8))
#define SELF_LIBRARY_ORDINAL 0x0
#define MAX_LIBRARY_ORDINAL 0xfd
#define DYNAMIC_LOOKUP_ORDINAL 0xfe
#define EXECUTABLE_ORDINAL 0xff
/*
* The bit 0x0020 of the n_desc field is used for two non-overlapping purposes
* and has two different symbolic names, N_NO_DEAD_STRIP and N_DESC_DISCARDED.
*/
/*
* The N_NO_DEAD_STRIP bit of the n_desc field only ever appears in a
* relocatable .o file (MH_OBJECT filetype). And is used to indicate to the
* static link editor it is never to dead strip the symbol.
*/
#define N_NO_DEAD_STRIP 0x0020 /* symbol is not to be dead stripped */
/*
* The N_DESC_DISCARDED bit of the n_desc field never appears in linked image.
* But is used in very rare cases by the dynamic link editor to mark an in
* memory symbol as discared and longer used for linking.
*/
#define N_DESC_DISCARDED 0x0020 /* symbol is discarded */
/*
* The N_WEAK_REF bit of the n_desc field indicates to the dynamic linker that
* the undefined symbol is allowed to be missing and is to have the address of
* zero when missing.
*/
#define N_WEAK_REF 0x0040 /* symbol is weak referenced */
/*
* The N_WEAK_DEF bit of the n_desc field indicates to the static and dynamic
* linkers that the symbol definition is weak, allowing a non-weak symbol to
* also be used which causes the weak definition to be discared. Currently this
* is only supported for symbols in coalesed sections.
*/
#define N_WEAK_DEF 0x0080 /* coalesed symbol is a weak definition */
/*
* The N_REF_TO_WEAK bit of the n_desc field indicates to the dynamic linker
* that the undefined symbol should be resolved using flat namespace searching.
*/
#define N_REF_TO_WEAK 0x0080 /* reference to a weak symbol */
/*
* The N_ARM_THUMB_DEF bit of the n_desc field indicates that the symbol is
* a defintion of a Thumb function.
*/
#define N_ARM_THUMB_DEF 0x0008 /* symbol is a Thumb function (ARM) */
/*
* The N_SYMBOL_RESOLVER bit of the n_desc field indicates that the
* that the function is actually a resolver function and should
* be called to get the address of the real function to use.
* This bit is only available in .o files (MH_OBJECT filetype)
*/
#define N_SYMBOL_RESOLVER 0x0100
/*
* The N_ALT_ENTRY bit of the n_desc field indicates that the
* symbol is pinned to the previous content.
*/
#define N_ALT_ENTRY 0x0200
#ifndef __STRICT_BSD__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*
* The function nlist(3) from the C library.
*/
extern int nlist (const char *filename, struct nlist *list);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __STRICT_BSD__ */
#endif /* _MACHO_LIST_H_ */

View File

@ -0,0 +1,203 @@
/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/* $NetBSD: exec.h,v 1.6 1994/10/27 04:16:05 cgd Exp $ */
/*
* Copyright (c) 1993 Christopher G. Demetriou
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _MACHO_RELOC_H_
#define _MACHO_RELOC_H_
#include <stdint.h>
/*
* Format of a relocation entry of a Mach-O file. Modified from the 4.3BSD
* format. The modifications from the original format were changing the value
* of the r_symbolnum field for "local" (r_extern == 0) relocation entries.
* This modification is required to support symbols in an arbitrary number of
* sections not just the three sections (text, data and bss) in a 4.3BSD file.
* Also the last 4 bits have had the r_type tag added to them.
*/
struct relocation_info {
int32_t r_address; /* offset in the section to what is being
relocated */
uint32_t r_symbolnum:24, /* symbol index if r_extern == 1 or section
ordinal if r_extern == 0 */
r_pcrel:1, /* was relocated pc relative already */
r_length:2, /* 0=byte, 1=word, 2=long, 3=quad */
r_extern:1, /* does not include value of sym referenced */
r_type:4; /* if not 0, machine specific relocation type */
};
#define R_ABS 0 /* absolute relocation type for Mach-O files */
/*
* The r_address is not really the address as it's name indicates but an offset.
* In 4.3BSD a.out objects this offset is from the start of the "segment" for
* which relocation entry is for (text or data). For Mach-O object files it is
* also an offset but from the start of the "section" for which the relocation
* entry is for. See comments in <mach-o/loader.h> about the r_address feild
* in images for used with the dynamic linker.
*
* In 4.3BSD a.out objects if r_extern is zero then r_symbolnum is an ordinal
* for the segment the symbol being relocated is in. These ordinals are the
* symbol types N_TEXT, N_DATA, N_BSS or N_ABS. In Mach-O object files these
* ordinals refer to the sections in the object file in the order their section
* structures appear in the headers of the object file they are in. The first
* section has the ordinal 1, the second 2, and so on. This means that the
* same ordinal in two different object files could refer to two different
* sections. And further could have still different ordinals when combined
* by the link-editor. The value R_ABS is used for relocation entries for
* absolute symbols which need no further relocation.
*/
/*
* For RISC machines some of the references are split across two instructions
* and the instruction does not contain the complete value of the reference.
* In these cases a second, or paired relocation entry, follows each of these
* relocation entries, using a PAIR r_type, which contains the other part of the
* reference not contained in the instruction. This other part is stored in the
* pair's r_address field. The exact number of bits of the other part of the
* reference store in the r_address field is dependent on the particular
* relocation type for the particular architecture.
*/
/*
* To make scattered loading by the link editor work correctly "local"
* relocation entries can't be used when the item to be relocated is the value
* of a symbol plus an offset (where the resulting expresion is outside the
* block the link editor is moving, a blocks are divided at symbol addresses).
* In this case. where the item is a symbol value plus offset, the link editor
* needs to know more than just the section the symbol was defined. What is
* needed is the actual value of the symbol without the offset so it can do the
* relocation correctly based on where the value of the symbol got relocated to
* not the value of the expression (with the offset added to the symbol value).
* So for the NeXT 2.0 release no "local" relocation entries are ever used when
* there is a non-zero offset added to a symbol. The "external" and "local"
* relocation entries remain unchanged.
*
* The implemention is quite messy given the compatibility with the existing
* relocation entry format. The ASSUMPTION is that a section will never be
* bigger than 2**24 - 1 (0x00ffffff or 16,777,215) bytes. This assumption
* allows the r_address (which is really an offset) to fit in 24 bits and high
* bit of the r_address field in the relocation_info structure to indicate
* it is really a scattered_relocation_info structure. Since these are only
* used in places where "local" relocation entries are used and not where
* "external" relocation entries are used the r_extern field has been removed.
*
* For scattered loading to work on a RISC machine where some of the references
* are split across two instructions the link editor needs to be assured that
* each reference has a unique 32 bit reference (that more than one reference is
* NOT sharing the same high 16 bits for example) so it move each referenced
* item independent of each other. Some compilers guarantees this but the
* compilers don't so scattered loading can be done on those that do guarantee
* this.
*/
#if defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__)
/*
* The reason for the ifdef's of __BIG_ENDIAN__ and __LITTLE_ENDIAN__ are that
* when stattered relocation entries were added the mistake of using a mask
* against a structure that is made up of bit fields was used. To make this
* design work this structure must be laid out in memory the same way so the
* mask can be applied can check the same bit each time (r_scattered).
*/
#endif /* defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__) */
#define R_SCATTERED 0x80000000 /* mask to be applied to the r_address field
of a relocation_info structure to tell that
is is really a scattered_relocation_info
stucture */
struct scattered_relocation_info {
#ifdef __BIG_ENDIAN__
uint32_t r_scattered:1, /* 1=scattered, 0=non-scattered (see above) */
r_pcrel:1, /* was relocated pc relative already */
r_length:2, /* 0=byte, 1=word, 2=long, 3=quad */
r_type:4, /* if not 0, machine specific relocation type */
r_address:24; /* offset in the section to what is being
relocated */
int32_t r_value; /* the value the item to be relocated is
refering to (without any offset added) */
#endif /* __BIG_ENDIAN__ */
#ifdef __LITTLE_ENDIAN__
uint32_t
r_address:24, /* offset in the section to what is being
relocated */
r_type:4, /* if not 0, machine specific relocation type */
r_length:2, /* 0=byte, 1=word, 2=long, 3=quad */
r_pcrel:1, /* was relocated pc relative already */
r_scattered:1; /* 1=scattered, 0=non-scattered (see above) */
int32_t r_value; /* the value the item to be relocated is
refering to (without any offset added) */
#endif /* __LITTLE_ENDIAN__ */
};
/*
* Relocation types used in a generic implementation. Relocation entries for
* normal things use the generic relocation as discribed above and their r_type
* is GENERIC_RELOC_VANILLA (a value of zero).
*
* Another type of generic relocation, GENERIC_RELOC_SECTDIFF, is to support
* the difference of two symbols defined in different sections. That is the
* expression "symbol1 - symbol2 + constant" is a relocatable expression when
* both symbols are defined in some section. For this type of relocation the
* both relocations entries are scattered relocation entries. The value of
* symbol1 is stored in the first relocation entry's r_value field and the
* value of symbol2 is stored in the pair's r_value field.
*
* A special case for a prebound lazy pointer is needed to beable to set the
* value of the lazy pointer back to its non-prebound state. This is done
* using the GENERIC_RELOC_PB_LA_PTR r_type. This is a scattered relocation
* entry where the r_value feild is the value of the lazy pointer not prebound.
*/
enum reloc_type_generic
{
GENERIC_RELOC_VANILLA, /* generic relocation as discribed above */
GENERIC_RELOC_PAIR, /* Only follows a GENERIC_RELOC_SECTDIFF */
GENERIC_RELOC_SECTDIFF,
GENERIC_RELOC_PB_LA_PTR, /* prebound lazy pointer */
GENERIC_RELOC_LOCAL_SECTDIFF,
GENERIC_RELOC_TLV /* thread local variables */
};
#endif /* _MACHO_RELOC_H_ */

View File

@ -0,0 +1,123 @@
/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#ifndef _MACHO_STAB_H_
#define _MACHO_STAB_H_
/* $NetBSD: stab.h,v 1.4 1994/10/26 00:56:25 cgd Exp $ */
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)stab.h 5.2 (Berkeley) 4/4/91
*/
/*
* This file gives definitions supplementing <nlist.h> for permanent symbol
* table entries of Mach-O files. Modified from the BSD definitions. The
* modifications from the original definitions were changing what the values of
* what was the n_other field (an unused field) which is now the n_sect field.
* These modifications are required to support symbols in an arbitrary number of
* sections not just the three sections (text, data and bss) in a BSD file.
* The values of the defined constants have NOT been changed.
*
* These must have one of the N_STAB bits on. The n_value fields are subject
* to relocation according to the value of their n_sect field. So for types
* that refer to things in sections the n_sect field must be filled in with the
* proper section ordinal. For types that are not to have their n_value field
* relocatated the n_sect field must be NO_SECT.
*/
/*
* Symbolic debugger symbols. The comments give the conventional use for
*
* .stabs "n_name", n_type, n_sect, n_desc, n_value
*
* where n_type is the defined constant and not listed in the comment. Other
* fields not listed are zero. n_sect is the section ordinal the entry is
* refering to.
*/
#define N_GSYM 0x20 /* global symbol: name,,NO_SECT,type,0 */
#define N_FNAME 0x22 /* procedure name (f77 kludge): name,,NO_SECT,0,0 */
#define N_FUN 0x24 /* procedure: name,,n_sect,linenumber,address */
#define N_STSYM 0x26 /* static symbol: name,,n_sect,type,address */
#define N_LCSYM 0x28 /* .lcomm symbol: name,,n_sect,type,address */
#define N_BNSYM 0x2e /* begin nsect sym: 0,,n_sect,0,address */
#define N_AST 0x32 /* AST file path: name,,NO_SECT,0,0 */
#define N_OPT 0x3c /* emitted with gcc2_compiled and in gcc source */
#define N_RSYM 0x40 /* register sym: name,,NO_SECT,type,register */
#define N_SLINE 0x44 /* src line: 0,,n_sect,linenumber,address */
#define N_ENSYM 0x4e /* end nsect sym: 0,,n_sect,0,address */
#define N_SSYM 0x60 /* structure elt: name,,NO_SECT,type,struct_offset */
#define N_SO 0x64 /* source file name: name,,n_sect,0,address */
#define N_OSO 0x66 /* object file name: name,,0,0,st_mtime */
#define N_LSYM 0x80 /* local sym: name,,NO_SECT,type,offset */
#define N_BINCL 0x82 /* include file beginning: name,,NO_SECT,0,sum */
#define N_SOL 0x84 /* #included file name: name,,n_sect,0,address */
#define N_PARAMS 0x86 /* compiler parameters: name,,NO_SECT,0,0 */
#define N_VERSION 0x88 /* compiler version: name,,NO_SECT,0,0 */
#define N_OLEVEL 0x8A /* compiler -O level: name,,NO_SECT,0,0 */
#define N_PSYM 0xa0 /* parameter: name,,NO_SECT,type,offset */
#define N_EINCL 0xa2 /* include file end: name,,NO_SECT,0,0 */
#define N_ENTRY 0xa4 /* alternate entry: name,,n_sect,linenumber,address */
#define N_LBRAC 0xc0 /* left bracket: 0,,NO_SECT,nesting level,address */
#define N_EXCL 0xc2 /* deleted include file: name,,NO_SECT,0,sum */
#define N_RBRAC 0xe0 /* right bracket: 0,,NO_SECT,nesting level,address */
#define N_BCOMM 0xe2 /* begin common: name,,NO_SECT,0,0 */
#define N_ECOMM 0xe4 /* end common: name,,n_sect,0,0 */
#define N_ECOML 0xe8 /* end common (local name): 0,,n_sect,0,address */
#define N_LENG 0xfe /* second stab entry with length information */
/*
* for the berkeley pascal compiler, pc(1):
*/
#define N_PC 0x30 /* global pascal symbol: name,,NO_SECT,subtype,line */
#endif /* _MACHO_STAB_H_ */

View File

@ -0,0 +1,185 @@
/*
* Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Relocations for x86_64 are a bit different than for other architectures in
* Mach-O: Scattered relocations are not used. Almost all relocations produced
* by the compiler are external relocations. An external relocation has the
* r_extern bit set to 1 and the r_symbolnum field contains the symbol table
* index of the target label.
*
* When the assembler is generating relocations, if the target label is a local
* label (begins with 'L'), then the previous non-local label in the same
* section is used as the target of the external relocation. An addend is used
* with the distance from that non-local label to the target label. Only when
* there is no previous non-local label in the section is an internal
* relocation used.
*
* The addend (i.e. the 4 in _foo+4) is encoded in the instruction (Mach-O does
* not have RELA relocations). For PC-relative relocations, the addend is
* stored directly in the instruction. This is different from other Mach-O
* architectures, which encode the addend minus the current section offset.
*
* The relocation types are:
*
* X86_64_RELOC_UNSIGNED // for absolute addresses
* X86_64_RELOC_SIGNED // for signed 32-bit displacement
* X86_64_RELOC_BRANCH // a CALL/JMP instruction with 32-bit displacement
* X86_64_RELOC_GOT_LOAD // a MOVQ load of a GOT entry
* X86_64_RELOC_GOT // other GOT references
* X86_64_RELOC_SUBTRACTOR // must be followed by a X86_64_RELOC_UNSIGNED
*
* The following are sample assembly instructions, followed by the relocation
* and section content they generate in an object file:
*
* call _foo
* r_type=X86_64_RELOC_BRANCH, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
* E8 00 00 00 00
*
* call _foo+4
* r_type=X86_64_RELOC_BRANCH, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
* E8 04 00 00 00
*
* movq _foo@GOTPCREL(%rip), %rax
* r_type=X86_64_RELOC_GOT_LOAD, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
* 48 8B 05 00 00 00 00
*
* pushq _foo@GOTPCREL(%rip)
* r_type=X86_64_RELOC_GOT, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
* FF 35 00 00 00 00
*
* movl _foo(%rip), %eax
* r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
* 8B 05 00 00 00 00
*
* movl _foo+4(%rip), %eax
* r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
* 8B 05 04 00 00 00
*
* movb $0x12, _foo(%rip)
* r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
* C6 05 FF FF FF FF 12
*
* movl $0x12345678, _foo(%rip)
* r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_foo
* C7 05 FC FF FF FF 78 56 34 12
*
* .quad _foo
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
* 00 00 00 00 00 00 00 00
*
* .quad _foo+4
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
* 04 00 00 00 00 00 00 00
*
* .quad _foo - _bar
* r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
* 00 00 00 00 00 00 00 00
*
* .quad _foo - _bar + 4
* r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_bar
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
* 04 00 00 00 00 00 00 00
*
* .long _foo - _bar
* r_type=X86_64_RELOC_SUBTRACTOR, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_bar
* r_type=X86_64_RELOC_UNSIGNED, r_length=2, r_extern=1, r_pcrel=0, r_symbolnum=_foo
* 00 00 00 00
*
* lea L1(%rip), %rax
* r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=1, r_pcrel=1, r_symbolnum=_prev
* 48 8d 05 12 00 00 00
* // assumes _prev is the first non-local label 0x12 bytes before L1
*
* lea L0(%rip), %rax
* r_type=X86_64_RELOC_SIGNED, r_length=2, r_extern=0, r_pcrel=1, r_symbolnum=3
* 48 8d 05 56 00 00 00
* // assumes L0 is in third section and there is no previous non-local label.
* // The rip-relative-offset of 0x00000056 is L0-address_of_next_instruction.
* // address_of_next_instruction is the address of the relocation + 4.
*
* add $6,L0(%rip)
* r_type=X86_64_RELOC_SIGNED_1, r_length=2, r_extern=0, r_pcrel=1, r_symbolnum=3
* 83 05 18 00 00 00 06
* // assumes L0 is in third section and there is no previous non-local label.
* // The rip-relative-offset of 0x00000018 is L0-address_of_next_instruction.
* // address_of_next_instruction is the address of the relocation + 4 + 1.
* // The +1 comes from SIGNED_1. This is used because the relocation is not
* // at the end of the instruction.
*
* .quad L1
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev
* 12 00 00 00 00 00 00 00
* // assumes _prev is the first non-local label 0x12 bytes before L1
*
* .quad L0
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=0, r_pcrel=0, r_symbolnum=3
* 56 00 00 00 00 00 00 00
* // assumes L0 is in third section, has an address of 0x00000056 in .o
* // file, and there is no previous non-local label
*
* .quad _foo - .
* r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
* EE FF FF FF FF FF FF FF
* // assumes _prev is the first non-local label 0x12 bytes before this
* // .quad
*
* .quad _foo - L1
* r_type=X86_64_RELOC_SUBTRACTOR, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_prev
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_extern=1, r_pcrel=0, r_symbolnum=_foo
* EE FF FF FF FF FF FF FF
* // assumes _prev is the first non-local label 0x12 bytes before L1
*
* .quad L1 - _prev
* // No relocations. This is an assembly time constant.
* 12 00 00 00 00 00 00 00
* // assumes _prev is the first non-local label 0x12 bytes before L1
*
*
*
* In final linked images, there are only two valid relocation kinds:
*
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_pcrel=0, r_extern=1, r_symbolnum=sym_index
* This tells dyld to add the address of a symbol to a pointer sized (8-byte)
* piece of data (i.e on disk the 8-byte piece of data contains the addend). The
* r_symbolnum contains the index into the symbol table of the target symbol.
*
* r_type=X86_64_RELOC_UNSIGNED, r_length=3, r_pcrel=0, r_extern=0, r_symbolnum=0
* This tells dyld to adjust the pointer sized (8-byte) piece of data by the amount
* the containing image was loaded from its base address (e.g. slide).
*
*/
enum reloc_type_x86_64
{
X86_64_RELOC_UNSIGNED, // for absolute addresses
X86_64_RELOC_SIGNED, // for signed 32-bit displacement
X86_64_RELOC_BRANCH, // a CALL/JMP instruction with 32-bit displacement
X86_64_RELOC_GOT_LOAD, // a MOVQ load of a GOT entry
X86_64_RELOC_GOT, // other GOT references
X86_64_RELOC_SUBTRACTOR, // must be followed by a X86_64_RELOC_UNSIGNED
X86_64_RELOC_SIGNED_1, // for signed 32-bit displacement with a -1 addend
X86_64_RELOC_SIGNED_2, // for signed 32-bit displacement with a -2 addend
X86_64_RELOC_SIGNED_4, // for signed 32-bit displacement with a -4 addend
X86_64_RELOC_TLV, // for thread local variables
};

384
EXTERNAL_HEADERS/ptrauth.h Normal file
View File

@ -0,0 +1,384 @@
/*===---- ptrauth.h - Pointer authentication -------------------------------===
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*===-----------------------------------------------------------------------===
*/
#ifndef __PTRAUTH_H
#define __PTRAUTH_H
#include <stdint.h>
typedef enum {
ptrauth_key_asia = 0,
ptrauth_key_asib = 1,
ptrauth_key_asda = 2,
ptrauth_key_asdb = 3,
/* A process-independent key which can be used to sign code pointers.
Signing and authenticating with this key is a no-op in processes
which disable ABI pointer authentication. */
ptrauth_key_process_independent_code = ptrauth_key_asia,
/* A process-specific key which can be used to sign code pointers.
Signing and authenticating with this key is enforced even in processes
which disable ABI pointer authentication. */
ptrauth_key_process_dependent_code = ptrauth_key_asib,
/* A process-independent key which can be used to sign data pointers.
Signing and authenticating with this key is a no-op in processes
which disable ABI pointer authentication. */
ptrauth_key_process_independent_data = ptrauth_key_asda,
/* A process-specific key which can be used to sign data pointers.
Signing and authenticating with this key is a no-op in processes
which disable ABI pointer authentication. */
ptrauth_key_process_dependent_data = ptrauth_key_asdb,
/* The key used to sign C function pointers.
The extra data is always 0. */
ptrauth_key_function_pointer = ptrauth_key_process_independent_code,
/* The key used to sign return addresses on the stack.
The extra data is based on the storage address of the return address.
On ARM64, that is always the storage address of the return address plus 8
(or, in other words, the value of the stack pointer on function entry) */
ptrauth_key_return_address = ptrauth_key_process_dependent_code,
/* The key used to sign frame pointers on the stack.
The extra data is based on the storage address of the frame pointer.
On ARM64, that is always the storage address of the frame pointer plus 16
(or, in other words, the value of the stack pointer on function entry) */
ptrauth_key_frame_pointer = ptrauth_key_process_dependent_data,
/* The key used to sign block function pointers, including:
invocation functions,
block object copy functions,
block object destroy functions,
__block variable copy functions, and
__block variable destroy functions.
The extra data is always the address at which the function pointer
is stored.
Note that block object pointers themselves (i.e. the direct
representations of values of block-pointer type) are not signed. */
ptrauth_key_block_function = ptrauth_key_asia,
/* The key used to sign C++ v-table pointers.
The extra data is always 0. */
ptrauth_key_cxx_vtable_pointer = ptrauth_key_asda,
/* Other pointers signed under the ABI use private ABI rules. */
} ptrauth_key;
/* An integer type of the appropriate size for an extra-data argument. */
typedef uintptr_t ptrauth_extra_data_t;
/* An integer type of the appropriate size for a generic signature. */
typedef uintptr_t ptrauth_generic_signature_t;
/* A signed pointer value embeds the original pointer together with
a signature that attests to the validity of that pointer. Because
this signature must use only "spare" bits of the pointer, a
signature's validity is probabilistic in practice: it is unlikely
but still plausible that an invalidly-derived signature will
somehow equal the correct signature and therefore successfully
authenticate. Nonetheless, this scheme provides a strong degree
of protection against certain kinds of attacks. */
/* Authenticating a pointer that was not signed with the given key
and extra-data value will (likely) fail. However, an
authentication failure will not lead immediately to a trap.
Instead, it will yield a value which is guaranteed to trap
if actually dereferenced. */
/* The null function pointer is always the all-zero bit pattern.
Signing an all-zero bit pattern will embed a (likely) non-zero
signature in the result, and so the result will not seem to be
a null function pointer. Authenticating this value will yield
a null function pointer back. However, authenticating an
all-zero bit pattern will probably fail, because the
authentication will expect a (likely) non-zero signature to
embedded in the value.
Because of this, if a pointer may validly be null, you should
check for null before attempting to authenticate it. */
#ifdef __PTRAUTH_INTRINSICS__
/* Strip the signature from a value without authenticating it.
If the value is a function pointer, the result will not be a
legal function pointer because of the missing signature, and
attempting to call it will result in an authentication failure.
The value must be an expression of pointer type.
The key must be a constant expression of type ptrauth_key.
The result will have the same type as the original value. */
#define ptrauth_strip(__value, __key) \
__builtin_ptrauth_strip(__value, __key)
/* Blend a pointer and a small integer to form a new extra-data
discriminator. Not all bits of the inputs are guaranteed to
contribute to the result.
On ARM64, only the low 16 bits of the integer will be considered.
For the purposes of ptrauth_sign_constant, the result of calling
this function is considered a constant expression if the arguments
are constant. Some restrictions may be imposed on the pointer.
The first argument must be an expression of pointer type.
The second argument must be an expression of integer type.
The result will have type uintptr_t. */
#define ptrauth_blend_discriminator(__pointer, __integer) \
__builtin_ptrauth_blend_discriminator(__pointer, __integer)
/* Compute the 16-bit integer discriminator of the given type.
The argument must be a type.
*/
#if __has_builtin(__builtin_ptrauth_type_discriminator)
#define ptrauth_type_discriminator(__type) \
__builtin_ptrauth_type_discriminator(__type)
#else
#define ptrauth_type_discriminator(__type) ((uintptr_t)0)
#endif
/* Compute the constant discriminator used by Clang to sign pointers with the
given C function pointer type.
A call to this function is an integer constant expression*/
#if __has_feature(ptrauth_function_pointer_type_discrimination)
#define ptrauth_function_pointer_type_discriminator(__type) \
__builtin_ptrauth_type_discriminator(__type)
#else
#define ptrauth_function_pointer_type_discriminator(__type) ((uintptr_t)0)
#endif
/* Add a signature to the given pointer value using a specific key,
using the given extra data as a salt to the signing process.
The value must be a constant expression of pointer type.
The key must be a constant expression of type ptrauth_key.
The extra data must be a constant expression of pointer or integer type;
if an integer, it will be coerced to ptrauth_extra_data_t.
The result will have the same type as the original value.
This is a constant expression if the extra data is an integer or
null pointer constant. */
#define ptrauth_sign_constant(__value, __key, __data) \
__builtin_ptrauth_sign_constant(__value, __key, __data)
/* Add a signature to the given pointer value using a specific key,
using the given extra data as a salt to the signing process.
This operation does not authenticate the original value and is
therefore potentially insecure if an attacker could possibly
control that value.
The value must be an expression of pointer type.
The key must be a constant expression of type ptrauth_key.
The extra data must be an expression of pointer or integer type;
if an integer, it will be coerced to ptrauth_extra_data_t.
The result will have the same type as the original value. */
#define ptrauth_sign_unauthenticated(__value, __key, __data) \
__builtin_ptrauth_sign_unauthenticated(__value, __key, __data)
/* Authenticate a pointer using one scheme and resign it using another.
If the result is subsequently authenticated using the new scheme, that
authentication is guaranteed to fail if and only if the initial
authentication failed.
The value must be an expression of pointer type.
The key must be a constant expression of type ptrauth_key.
The extra data must be an expression of pointer or integer type;
if an integer, it will be coerced to ptrauth_extra_data_t.
The result will have the same type as the original value.
This operation is guaranteed to not leave the intermediate value
available for attack before it is re-signed.
Do not pass a null pointer to this function. A null pointer
will not successfully authenticate. */
#define ptrauth_auth_and_resign(__value, __old_key, __old_data, __new_key, __new_data) \
__builtin_ptrauth_auth_and_resign(__value, __old_key, __old_data, __new_key, __new_data)
/* Authenticate a pointer using one scheme and resign it as a C
function pointer.
If the result is subsequently authenticated using the new scheme, that
authentication is guaranteed to fail if and only if the initial
authentication failed.
The value must be an expression of function pointer type.
The key must be a constant expression of type ptrauth_key.
The extra data must be an expression of pointer or integer type;
if an integer, it will be coerced to ptrauth_extra_data_t.
The result will have the same type as the original value.
This operation is guaranteed to not leave the intermediate value
available for attack before it is re-signed. Additionally, if this
expression is used syntactically as the function expression in a
call, only a single authentication will be performed. */
#define ptrauth_auth_function(__value, __old_key, __old_data) \
ptrauth_auth_and_resign(__value, __old_key, __old_data, ptrauth_key_function_pointer, 0)
/* Cast a pointer to the given type without changing any signature.
The type must have the same size as a pointer type.
The type of value must have the same size as a pointer type, and will be
converted to an rvalue prior to the cast.
The result has type given by the first argument.
The result has an identical bit-pattern to the input pointer. */
#define ptrauth_nop_cast(__type, __value) \
({ union { \
typeof(__value) __fptr; \
typeof(__type) __opaque; \
} __storage; \
__storage.__fptr = (__value); \
__storage.__opaque; })
/* Authenticate a data pointer.
The value must be an expression of non-function pointer type.
The key must be a constant expression of type ptrauth_key.
The extra data must be an expression of pointer or integer type;
if an integer, it will be coerced to ptrauth_extra_data_t.
The result will have the same type as the original value.
If the authentication fails, dereferencing the resulting pointer
will fail. */
#define ptrauth_auth_data(__value, __old_key, __old_data) \
__builtin_ptrauth_auth(__value, __old_key, __old_data)
/* Return an extra-discriminator value which can validly be used
as the second argument to ptrauth_blend_discriminator or the
third argument to the __ptrauth qualifier.
The argument must be a string literal.
A call to this function is an integer constant expression. */
#define ptrauth_string_discriminator(__string) \
__builtin_ptrauth_string_discriminator(__string)
/* Compute a full pointer-width generic signature for the given
value, using the given data as a salt.
This generic signature is process-independent, but may not be
consistent across reboots.
This can be used to validate the integrity of arbitrary data
by storing a signature for that data together with it. Because
the signature is pointer-sized, if the stored signature matches
the result of re-signing the current data, a match provides very
strong evidence that the data has not been corrupted.
The value must be an expression of pointer or integer type; if
an integer, it will be coerced to uintptr_t.
The extra data must be an expression of pointer or integer type;
if an integer, it will be coerced to ptrauth_extra_data_t.
The result will have type ptrauth_generic_signature_t.
This operation will compute a meaningful signature even in processes
which disable ABI pointer authentication. */
#define ptrauth_sign_generic_data(__value, __data) \
__builtin_ptrauth_sign_generic_data(__value, __data)
/* Define some standard __ptrauth qualifiers used in the ABI. */
#define __ptrauth_function_pointer \
__ptrauth(ptrauth_key_function_pointer,0,0)
#define __ptrauth_return_address \
__ptrauth(ptrauth_key_return_address,1,0)
#define __ptrauth_block_invocation_pointer \
__ptrauth(ptrauth_key_function_pointer,1,0)
#define __ptrauth_block_copy_helper \
__ptrauth(ptrauth_key_function_pointer,1,0)
#define __ptrauth_block_destroy_helper \
__ptrauth(ptrauth_key_function_pointer,1,0)
#define __ptrauth_block_byref_copy_helper \
__ptrauth(ptrauth_key_function_pointer,1,0)
#define __ptrauth_block_byref_destroy_helper \
__ptrauth(ptrauth_key_function_pointer,1,0)
#define __ptrauth_objc_method_list_imp \
__ptrauth(ptrauth_key_function_pointer,1,0)
#define __ptrauth_cxx_vtable_pointer \
__ptrauth(ptrauth_key_cxx_vtable_pointer,0,0)
#define __ptrauth_cxx_vtt_vtable_pointer \
__ptrauth(ptrauth_key_cxx_vtable_pointer,0,0)
#define __ptrauth_swift_heap_object_destructor \
__ptrauth(ptrauth_key_function_pointer,1,0xbbbf)
/* Some situations in the C++ and Swift ABIs use declaration-specific
or type-specific extra discriminators. */
#define __ptrauth_cxx_virtual_function_pointer(__declkey) \
__ptrauth(ptrauth_key_function_pointer,1,__declkey)
#define __ptrauth_swift_function_pointer(__typekey) \
__ptrauth(ptrauth_key_function_pointer,0,__typekey)
#define __ptrauth_swift_class_method_pointer(__declkey) \
__ptrauth(ptrauth_key_function_pointer,1,__declkey)
#define __ptrauth_swift_protocol_witness_function_pointer(__declkey) \
__ptrauth(ptrauth_key_function_pointer,1,__declkey)
#define __ptrauth_swift_value_witness_function_pointer(__key) \
__ptrauth(ptrauth_key_function_pointer,1,__key)
#else
#define ptrauth_strip(__value, __key) ({ (void)__key; __value; })
#define ptrauth_blend_discriminator(__pointer, __integer) ({ (void)__pointer; (void)__integer; (uintptr_t)0; })
#define ptrauth_type_discriminator(__type) ((uintptr_t)0)
#define ptrauth_function_pointer_type_discriminator(__type) ((uintptr_t)0)
#define ptrauth_sign_constant(__value, __key, __data) ({ (void)__key; (void)__data; __value; })
#define ptrauth_sign_unauthenticated(__value, __key, __data) ({ (void)__key; (void)__data; __value; })
#define ptrauth_auth_and_resign(__value, __old_key, __old_data, __new_key, __new_data) ({ \
(void)__old_key; \
(void)__old_data; \
(void)__new_key; \
(void)__new_data; \
__value; })
#define ptrauth_auth_function(__value, __old_key, __old_data) ({ (void)__old_key; (void)__old_data; __value; })
#define ptrauth_nop_cast(__type, __value) ((__type)__value)
#define ptrauth_auth_data(__value, __old_key, __old_data) ({ (void)__old_key; (void)__old_data; __value; })
#define ptrauth_string_discriminator(__string) ({ (void)__string; (int)0; })
#define ptrauth_sign_generic_data(__value, __data) ({ (void)__value; (void)__data; (ptrauth_generic_signature_t)0; })
#define __ptrauth_function_pointer
#define __ptrauth_return_address
#define __ptrauth_block_invocation_pointer
#define __ptrauth_block_copy_helper
#define __ptrauth_block_destroy_helper
#define __ptrauth_block_byref_copy_helper
#define __ptrauth_block_byref_destroy_helper
#define __ptrauth_objc_method_list_imp
#define __ptrauth_cxx_vtable_pointer
#define __ptrauth_cxx_vtt_vtable_pointer
#define __ptrauth_swift_heap_object_destructor
#define __ptrauth_cxx_virtual_function_pointer(__declkey)
#define __ptrauth_swift_function_pointer(__typekey)
#define __ptrauth_swift_class_method_pointer(__declkey)
#define __ptrauth_swift_protocol_witness_function_pointer(__declkey)
#define __ptrauth_swift_value_witness_function_pointer(__key)
#endif /* __PTRAUTH_INTRINSICS__ */
#endif /* __PTRAUTH_H */

50
EXTERNAL_HEADERS/stdarg.h Normal file
View File

@ -0,0 +1,50 @@
/*===---- stdarg.h - Variable argument handling ----------------------------===
*
* Copyright (c) 2008 Eli Friedman
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*===-----------------------------------------------------------------------===
*/
#ifndef __STDARG_H
#define __STDARG_H
#ifndef _VA_LIST
typedef __builtin_va_list va_list;
#define _VA_LIST
#endif
#define va_start(ap, param) __builtin_va_start(ap, param)
#define va_end(ap) __builtin_va_end(ap)
#define va_arg(ap, type) __builtin_va_arg(ap, type)
/* GCC always defines __va_copy, but does not define va_copy unless in c99 mode
* or -ansi is not specified, since it was not part of C90.
*/
#define __va_copy(d,s) __builtin_va_copy(d,s)
#if __STDC_VERSION__ >= 199900L || __cplusplus >= 201103L || !defined(__STRICT_ANSI__)
#define va_copy(dest, src) __builtin_va_copy(dest, src)
#endif
/* Hack required to make standard headers work, at least on Ubuntu */
#define __GNUC_VA_LIST 1
typedef __builtin_va_list __gnuc_va_list;
#endif /* __STDARG_H */

View File

@ -0,0 +1,198 @@
/*===---- stdatomic.h - Standard header for atomic types and operations -----===
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*===-----------------------------------------------------------------------===
*/
#ifndef __clang__
#error unsupported compiler
#endif
#ifndef __CLANG_STDATOMIC_H
#define __CLANG_STDATOMIC_H
/* If we're hosted, fall back to the system's stdatomic.h. FreeBSD, for
* example, already has a Clang-compatible stdatomic.h header.
*/
#if __STDC_HOSTED__ && __has_include_next(<stdatomic.h>)
# include_next <stdatomic.h>
#else
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* 7.17.1 Introduction */
#define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
#define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
#define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
#define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
#define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
#define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
#define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
#define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
#define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
#define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
/* 7.17.2 Initialization */
#define ATOMIC_VAR_INIT(value) (value)
#define atomic_init __c11_atomic_init
/* 7.17.3 Order and consistency */
typedef enum memory_order {
memory_order_relaxed = __ATOMIC_RELAXED,
memory_order_consume = __ATOMIC_CONSUME,
memory_order_acquire = __ATOMIC_ACQUIRE,
memory_order_release = __ATOMIC_RELEASE,
memory_order_acq_rel = __ATOMIC_ACQ_REL,
memory_order_seq_cst = __ATOMIC_SEQ_CST
} memory_order;
#define kill_dependency(y) (y)
/* 7.17.4 Fences */
#ifndef KERNEL
/* These should be provided by the libc implementation. */
void atomic_thread_fence(memory_order);
void atomic_signal_fence(memory_order);
#endif
#define atomic_thread_fence(order) __c11_atomic_thread_fence(order)
#define atomic_signal_fence(order) __c11_atomic_signal_fence(order)
/* 7.17.5 Lock-free property */
#define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj)))
/* 7.17.6 Atomic integer types */
#ifdef __cplusplus
typedef _Atomic(bool) atomic_bool;
#else
typedef _Atomic(_Bool) atomic_bool;
#endif
typedef _Atomic(char) atomic_char;
typedef _Atomic(signed char) atomic_schar;
typedef _Atomic(unsigned char) atomic_uchar;
typedef _Atomic(short) atomic_short;
typedef _Atomic(unsigned short) atomic_ushort;
typedef _Atomic(int) atomic_int;
typedef _Atomic(unsigned int) atomic_uint;
typedef _Atomic(long) atomic_long;
typedef _Atomic(unsigned long) atomic_ulong;
typedef _Atomic(long long) atomic_llong;
typedef _Atomic(unsigned long long) atomic_ullong;
typedef _Atomic(uint_least16_t) atomic_char16_t;
typedef _Atomic(uint_least32_t) atomic_char32_t;
typedef _Atomic(wchar_t) atomic_wchar_t;
typedef _Atomic(int_least8_t) atomic_int_least8_t;
typedef _Atomic(uint_least8_t) atomic_uint_least8_t;
typedef _Atomic(int_least16_t) atomic_int_least16_t;
typedef _Atomic(uint_least16_t) atomic_uint_least16_t;
typedef _Atomic(int_least32_t) atomic_int_least32_t;
typedef _Atomic(uint_least32_t) atomic_uint_least32_t;
typedef _Atomic(int_least64_t) atomic_int_least64_t;
typedef _Atomic(uint_least64_t) atomic_uint_least64_t;
typedef _Atomic(int_fast8_t) atomic_int_fast8_t;
typedef _Atomic(uint_fast8_t) atomic_uint_fast8_t;
typedef _Atomic(int_fast16_t) atomic_int_fast16_t;
typedef _Atomic(uint_fast16_t) atomic_uint_fast16_t;
typedef _Atomic(int_fast32_t) atomic_int_fast32_t;
typedef _Atomic(uint_fast32_t) atomic_uint_fast32_t;
typedef _Atomic(int_fast64_t) atomic_int_fast64_t;
typedef _Atomic(uint_fast64_t) atomic_uint_fast64_t;
typedef _Atomic(intptr_t) atomic_intptr_t;
typedef _Atomic(uintptr_t) atomic_uintptr_t;
typedef _Atomic(size_t) atomic_size_t;
typedef _Atomic(ptrdiff_t) atomic_ptrdiff_t;
typedef _Atomic(intmax_t) atomic_intmax_t;
typedef _Atomic(uintmax_t) atomic_uintmax_t;
/* 7.17.7 Operations on atomic types */
#define atomic_store(object, desired) __c11_atomic_store(object, desired, __ATOMIC_SEQ_CST)
#define atomic_store_explicit __c11_atomic_store
#define atomic_load(object) __c11_atomic_load(object, __ATOMIC_SEQ_CST)
#define atomic_load_explicit __c11_atomic_load
#define atomic_exchange(object, desired) __c11_atomic_exchange(object, desired, __ATOMIC_SEQ_CST)
#define atomic_exchange_explicit __c11_atomic_exchange
#define atomic_compare_exchange_strong(object, expected, desired) __c11_atomic_compare_exchange_strong(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define atomic_compare_exchange_strong_explicit __c11_atomic_compare_exchange_strong
#define atomic_compare_exchange_weak(object, expected, desired) __c11_atomic_compare_exchange_weak(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define atomic_compare_exchange_weak_explicit __c11_atomic_compare_exchange_weak
#define atomic_fetch_add(object, operand) __c11_atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_add_explicit __c11_atomic_fetch_add
#define atomic_fetch_sub(object, operand) __c11_atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_sub_explicit __c11_atomic_fetch_sub
#define atomic_fetch_or(object, operand) __c11_atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_or_explicit __c11_atomic_fetch_or
#define atomic_fetch_xor(object, operand) __c11_atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_xor_explicit __c11_atomic_fetch_xor
#define atomic_fetch_and(object, operand) __c11_atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_and_explicit __c11_atomic_fetch_and
/* 7.17.8 Atomic flag type and operations */
typedef struct atomic_flag { atomic_bool _Value; } atomic_flag;
#define ATOMIC_FLAG_INIT { 0 }
#ifndef KERNEL
/* These should be provided by the libc implementation. */
#ifdef __cplusplus
bool atomic_flag_test_and_set(volatile atomic_flag *);
bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order);
#else
_Bool atomic_flag_test_and_set(volatile atomic_flag *);
_Bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order);
#endif
void atomic_flag_clear(volatile atomic_flag *);
void atomic_flag_clear_explicit(volatile atomic_flag *, memory_order);
#endif
#define atomic_flag_test_and_set(object) __c11_atomic_exchange(&(object)->_Value, 1, __ATOMIC_SEQ_CST)
#define atomic_flag_test_and_set_explicit(object, order) __c11_atomic_exchange(&(object)->_Value, 1, order)
#define atomic_flag_clear(object) __c11_atomic_store(&(object)->_Value, 0, __ATOMIC_SEQ_CST)
#define atomic_flag_clear_explicit(object, order) __c11_atomic_store(&(object)->_Value, 0, order)
#ifdef __cplusplus
}
#endif
#endif /* __STDC_HOSTED__ */
#endif /* __CLANG_STDATOMIC_H */

View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2000 Jeroen Ruigrok van der Werven <asmodai@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/include/stdbool.h,v 1.6 2002/08/16 07:33:14 alfred Exp $
*/
#ifndef _STDBOOL_H_
#define _STDBOOL_H_
#define __bool_true_false_are_defined 1
#ifndef __cplusplus
#define false 0
#define true 1
#define bool _Bool
#if __STDC_VERSION__ < 199901L && __GNUC__ < 3
typedef int _Bool;
#endif
#endif /* !__cplusplus */
#endif /* !_STDBOOL_H_ */

70
EXTERNAL_HEADERS/stddef.h Normal file
View File

@ -0,0 +1,70 @@
/*===---- stddef.h - Basic type definitions --------------------------------===
*
* Copyright (c) 2008 Eli Friedman
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*===-----------------------------------------------------------------------===
*/
#ifndef __STDDEF_H
#define __STDDEF_H
#undef NULL
#ifdef __cplusplus
#if __cplusplus >= 201103L
#define NULL nullptr
#else
#undef __null // VC++ hack.
#define NULL __null
#endif
#else
#define NULL ((void*)0)
#endif
#ifndef _PTRDIFF_T
#define _PTRDIFF_T
typedef __typeof__(((int*)NULL)-((int*)NULL)) ptrdiff_t;
#endif
#ifndef _SIZE_T
#define _SIZE_T
typedef __typeof__(sizeof(int)) size_t;
#endif
#ifndef __cplusplus
#ifndef _WCHAR_T
#define _WCHAR_T
typedef __WCHAR_TYPE__ wchar_t;
#endif
#endif
#ifndef offsetof
#define offsetof(t, d) __builtin_offsetof(t, d)
#endif
#endif /* __STDDEF_H */
/* Some C libraries expect to see a wint_t here. Others (notably MinGW) will use
__WINT_TYPE__ directly; accommodate both by requiring __need_wint_t */
#if defined(__need_wint_t)
#if !defined(_WINT_T)
#define _WINT_T
typedef __WINT_TYPE__ wint_t;
#endif /* _WINT_T */
#undef __need_wint_t
#endif /* __need_wint_t */

228
EXTERNAL_HEADERS/stdint.h Normal file
View File

@ -0,0 +1,228 @@
/*
* Copyright (c) 2000-2010 Apple Inc.
* All rights reserved.
*/
#ifndef _KERNEL_STDINT_H_
#define _KERNEL_STDINT_H_
#ifndef KERNEL
/* For user-space code that may include this header */
#include_next <stdint.h>
#else /* KERNEL */
#include <machine/types.h>
#if __LP64__
#define __WORDSIZE 64
#else
#define __WORDSIZE 32
#endif
/* from ISO/IEC 988:1999 spec */
/* 7.18.1.1 Exact-width integer types */
/* int8_t is defined in <machine/types.h> */
/* int16_t is defined in <machine/types.h> */
/* int32_t is defined in <machine/types.h> */
/* int64_t is defined in <machine/types.h> */
typedef u_int8_t uint8_t; /* u_int8_t is defined in <machine/types.h> */
typedef u_int16_t uint16_t; /* u_int16_t is defined in <machine/types.h> */
typedef u_int32_t uint32_t; /* u_int32_t is defined in <machine/types.h> */
typedef u_int64_t uint64_t; /* u_int64_t is defined in <machine/types.h> */
/* 7.18.1.2 Minimum-width integer types */
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
/* 7.18.1.3 Fastest-width integer types */
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
/* 7.18.1.4 Integer types capable of holding object pointers */
/* intptr_t is defined in <machine/types.h> */
/* uintptr_t is defined in <machine/types.h> */
/* 7.18.1.5 Greatest-width integer types */
#ifdef __INTMAX_TYPE__
typedef __INTMAX_TYPE__ intmax_t;
#else
#ifdef __LP64__
typedef long int intmax_t;
#else
typedef long long int intmax_t;
#endif /* __LP64__ */
#endif /* __INTMAX_TYPE__ */
#ifdef __UINTMAX_TYPE__
typedef __UINTMAX_TYPE__ uintmax_t;
#else
#ifdef __LP64__
typedef long unsigned int uintmax_t;
#else
typedef long long unsigned int uintmax_t;
#endif /* __LP64__ */
#endif /* __UINTMAX_TYPE__ */
/* 7.18.4 Macros for integer constants */
#define INT8_C(v) (v)
#define INT16_C(v) (v)
#define INT32_C(v) (v)
#define INT64_C(v) (v ## LL)
#define UINT8_C(v) (v)
#define UINT16_C(v) (v)
#define UINT32_C(v) (v ## U)
#define UINT64_C(v) (v ## ULL)
#ifdef __LP64__
#define INTMAX_C(v) (v ## L)
#define UINTMAX_C(v) (v ## UL)
#else
#define INTMAX_C(v) (v ## LL)
#define UINTMAX_C(v) (v ## ULL)
#endif
/* 7.18.2 Limits of specified-width integer types:
* These #defines specify the minimum and maximum limits
* of each of the types declared above.
*
* They must have "the same type as would an expression that is an
* object of the corresponding type converted according to the integer
* promotion".
*/
/* 7.18.2.1 Limits of exact-width integer types */
#define INT8_MAX 127
#define INT16_MAX 32767
#define INT32_MAX 2147483647
#define INT64_MAX 9223372036854775807LL
#define INT8_MIN -128
#define INT16_MIN -32768
/*
Note: the literal "most negative int" cannot be written in C --
the rules in the standard (section 6.4.4.1 in C99) will give it
an unsigned type, so INT32_MIN (and the most negative member of
any larger signed type) must be written via a constant expression.
*/
#define INT32_MIN (-INT32_MAX-1)
#define INT64_MIN (-INT64_MAX-1)
#define UINT8_MAX 255
#define UINT16_MAX 65535
#define UINT32_MAX 4294967295U
#define UINT64_MAX 18446744073709551615ULL
/* 7.18.2.2 Limits of minimum-width integer types */
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
/* 7.18.2.3 Limits of fastest minimum-width integer types */
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
/* 7.18.2.4 Limits of integer types capable of holding object pointers */
#if __WORDSIZE == 64
#define INTPTR_MAX 9223372036854775807L
#else
#define INTPTR_MAX 2147483647L
#endif
#define INTPTR_MIN (-INTPTR_MAX-1)
#if __WORDSIZE == 64
#define UINTPTR_MAX 18446744073709551615UL
#else
#define UINTPTR_MAX 4294967295UL
#endif
/* 7.18.2.5 Limits of greatest-width integer types */
#define INTMAX_MAX INTMAX_C(9223372036854775807)
#define UINTMAX_MAX UINTMAX_C(18446744073709551615)
#define INTMAX_MIN (-INTMAX_MAX-1)
/* 7.18.3 "Other" */
#if __WORDSIZE == 64
#define PTRDIFF_MIN INTMAX_MIN
#define PTRDIFF_MAX INTMAX_MAX
#else
#define PTRDIFF_MIN INT32_MIN
#define PTRDIFF_MAX INT32_MAX
#endif
#define SIZE_MAX UINTPTR_MAX
#if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1
#define RSIZE_MAX (SIZE_MAX >> 1)
#endif
#ifndef WCHAR_MAX
# ifdef __WCHAR_MAX__
# define WCHAR_MAX __WCHAR_MAX__
# else
# define WCHAR_MAX 0x7fffffff
# endif
#endif
/* WCHAR_MIN should be 0 if wchar_t is an unsigned type and
(-WCHAR_MAX-1) if wchar_t is a signed type. Unfortunately,
it turns out that -fshort-wchar changes the signedness of
the type. */
#ifndef WCHAR_MIN
# if WCHAR_MAX == 0xffff
# define WCHAR_MIN 0
# else
# define WCHAR_MIN (-WCHAR_MAX-1)
# endif
#endif
#define WINT_MIN INT32_MIN
#define WINT_MAX INT32_MAX
#define SIG_ATOMIC_MIN INT32_MIN
#define SIG_ATOMIC_MAX INT32_MAX
#endif /* KERNEL */
#endif /* _KERNEL_STDINT_H_ */

View File

@ -0,0 +1,13 @@
export MakeInc_cmd=${SRCROOT}/makedefs/MakeInc.cmd
export MakeInc_def=${SRCROOT}/makedefs/MakeInc.def
export MakeInc_rule=${SRCROOT}/makedefs/MakeInc.rule
export MakeInc_dir=${SRCROOT}/makedefs/MakeInc.dir
include $(MakeInc_cmd)
include $(MakeInc_def)
INSTINC_SUBDIRS = \
_pthread
include $(MakeInc_rule)
include $(MakeInc_dir)

View File

@ -0,0 +1,21 @@
export MakeInc_cmd=${SRCROOT}/makedefs/MakeInc.cmd
export MakeInc_def=${SRCROOT}/makedefs/MakeInc.def
export MakeInc_rule=${SRCROOT}/makedefs/MakeInc.rule
export MakeInc_dir=${SRCROOT}/makedefs/MakeInc.dir
include $(MakeInc_cmd)
include $(MakeInc_def)
EXPORT_FILES = \
_pthread_types.h
EXPORT_MI_LIST = ${EXPORT_FILES}
EXPORT_MI_DIR = sys/_pthread
INSTALL_KF_MI_LCL_LIST = $(empty)
INSTALL_KF_MI_LIST = $(empty)
include $(MakeInc_rule)
include $(MakeInc_dir)

View File

@ -0,0 +1,120 @@
/*
* Copyright (c) 2003-2013 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. The rights granted to you under the License
* may not be used to create, or enable the creation or redistribution of,
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
*
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
#ifndef _SYS__PTHREAD_TYPES_H_
#define _SYS__PTHREAD_TYPES_H_
#include <sys/cdefs.h>
// pthread opaque structures
#if defined(__LP64__)
#define __PTHREAD_SIZE__ 8176
#define __PTHREAD_ATTR_SIZE__ 56
#define __PTHREAD_MUTEXATTR_SIZE__ 8
#define __PTHREAD_MUTEX_SIZE__ 56
#define __PTHREAD_CONDATTR_SIZE__ 8
#define __PTHREAD_COND_SIZE__ 40
#define __PTHREAD_ONCE_SIZE__ 8
#define __PTHREAD_RWLOCK_SIZE__ 192
#define __PTHREAD_RWLOCKATTR_SIZE__ 16
#else // !__LP64__
#define __PTHREAD_SIZE__ 4088
#define __PTHREAD_ATTR_SIZE__ 36
#define __PTHREAD_MUTEXATTR_SIZE__ 8
#define __PTHREAD_MUTEX_SIZE__ 40
#define __PTHREAD_CONDATTR_SIZE__ 4
#define __PTHREAD_COND_SIZE__ 24
#define __PTHREAD_ONCE_SIZE__ 4
#define __PTHREAD_RWLOCK_SIZE__ 124
#define __PTHREAD_RWLOCKATTR_SIZE__ 12
#endif // !__LP64__
struct __darwin_pthread_handler_rec {
void (*__routine)(void *); // Routine to call
void *__arg; // Argument to pass
struct __darwin_pthread_handler_rec *__next;
};
struct _opaque_pthread_attr_t {
long __sig;
char __opaque[__PTHREAD_ATTR_SIZE__];
};
struct _opaque_pthread_cond_t {
long __sig;
char __opaque[__PTHREAD_COND_SIZE__];
};
struct _opaque_pthread_condattr_t {
long __sig;
char __opaque[__PTHREAD_CONDATTR_SIZE__];
};
struct _opaque_pthread_mutex_t {
long __sig;
char __opaque[__PTHREAD_MUTEX_SIZE__];
};
struct _opaque_pthread_mutexattr_t {
long __sig;
char __opaque[__PTHREAD_MUTEXATTR_SIZE__];
};
struct _opaque_pthread_once_t {
long __sig;
char __opaque[__PTHREAD_ONCE_SIZE__];
};
struct _opaque_pthread_rwlock_t {
long __sig;
char __opaque[__PTHREAD_RWLOCK_SIZE__];
};
struct _opaque_pthread_rwlockattr_t {
long __sig;
char __opaque[__PTHREAD_RWLOCKATTR_SIZE__];
};
struct _opaque_pthread_t {
long __sig;
struct __darwin_pthread_handler_rec *__cleanup_stack;
char __opaque[__PTHREAD_SIZE__];
};
typedef struct _opaque_pthread_attr_t __darwin_pthread_attr_t;
typedef struct _opaque_pthread_cond_t __darwin_pthread_cond_t;
typedef struct _opaque_pthread_condattr_t __darwin_pthread_condattr_t;
typedef unsigned long __darwin_pthread_key_t;
typedef struct _opaque_pthread_mutex_t __darwin_pthread_mutex_t;
typedef struct _opaque_pthread_mutexattr_t __darwin_pthread_mutexattr_t;
typedef struct _opaque_pthread_once_t __darwin_pthread_once_t;
typedef struct _opaque_pthread_rwlock_t __darwin_pthread_rwlock_t;
typedef struct _opaque_pthread_rwlockattr_t __darwin_pthread_rwlockattr_t;
typedef struct _opaque_pthread_t *__darwin_pthread_t;
#endif // _SYS__PTHREAD_TYPES_H_

358
Makefile Normal file
View File

@ -0,0 +1,358 @@
#
# Copyright (C) 1999-2020 Apple Inc. All rights reserved.
#
ifndef VERSDIR
export VERSDIR := $(shell /bin/pwd)
endif
ifndef SRCROOT
export SRCROOT := $(shell /bin/pwd)
endif
ifndef OBJROOT
export OBJROOT = $(SRCROOT)/BUILD/obj
endif
ifndef DSTROOT
export DSTROOT = $(SRCROOT)/BUILD/dst
endif
ifndef SYMROOT
export SYMROOT = $(SRCROOT)/BUILD/sym
endif
ifndef MallocNanoZone
export MallocNanoZone := 1
endif
# Avoid make default rules, make becomes faster
MAKEFLAGS+=r
export MakeInc_top=${VERSDIR}/makedefs/MakeInc.top
export MakeInc_kernel=${VERSDIR}/makedefs/MakeInc.kernel
export MakeInc_cmd=${VERSDIR}/makedefs/MakeInc.cmd
export MakeInc_def=${VERSDIR}/makedefs/MakeInc.def
export MakeInc_rule=${VERSDIR}/makedefs/MakeInc.rule
export MakeInc_dir=${VERSDIR}/makedefs/MakeInc.dir
#
# Dispatch non-xnu build aliases to their own build
# systems. All xnu variants start with MakeInc_top.
#
ifneq ($(findstring Libsyscall,$(RC_ProjectName)),)
include $(MakeInc_cmd)
ifeq ($(RC_ProjectName),Libsyscall_headers_Sim)
TARGET=-target Libsyscall_headers_Sim
endif
ifeq ($(RC_ProjectName),Libsyscall_driverkit)
TARGET=-target Libsyscall_driverkit
endif
default: install
# default to OS X
SDKROOT ?= macosx.internal
installhdrs install:
cd libsyscall ; \
xcodebuild $@ $(TARGET) \
$(MAKEOVERRIDES) \
"SRCROOT=$(SRCROOT)/libsyscall" \
"OBJROOT=$(OBJROOT)" \
"SYMROOT=$(SYMROOT)" \
"DSTROOT=$(DSTROOT)" \
"SDKROOT=$(SDKROOT)"
Libsyscall_driverkit: install
.PHONY: Libsyscall_driverkit
clean:
installsrc:
pax -rw . $(SRCROOT)
else ifneq ($(findstring libkxld_host,$(RC_ProjectName)),)
include $(MakeInc_cmd)
default: install
installhdrs install clean:
$(MAKE) -C libkern/kxld $@ USE_APPLE_PB_SUPPORT=all PRODUCT_TYPE=ARCHIVE
installsrc:
$(_v)$(MKDIR) $(SRCROOT)
$(_v)$(FIND) -x . \! \( \( -name BUILD -o -name .svn -o -name .git -o -name cscope.\* -o -name \*~ \) -prune \) -print0 | $(PAX) -rw -p a -d0 $(SRCROOT)
$(_v)$(CHMOD) -R go+rX $(SRCROOT)
else ifneq ($(findstring libkxld,$(RC_ProjectName)),)
include $(MakeInc_cmd)
default: install
installhdrs install clean:
$(MAKE) -C libkern/kxld $@ USE_APPLE_PB_SUPPORT=all
installsrc:
$(_v)$(MKDIR) $(SRCROOT)
$(_v)$(FIND) -x . \! \( \( -name BUILD -o -name .svn -o -name .git -o -name cscope.\* -o -name \*~ \) -prune \) -print0 | $(PAX) -rw -p a -d0 $(SRCROOT)
$(_v)$(CHMOD) -R go+rX $(SRCROOT)
else ifneq ($(findstring libkmod,$(RC_ProjectName)),)
default: install
installhdrs install:
cd libkern/kmod ; \
xcodebuild $@ \
$(MAKEOVERRIDES) \
"SRCROOT=$(SRCROOT)/libkern/kmod" \
"OBJROOT=$(OBJROOT)" \
"SYMROOT=$(SYMROOT)" \
"DSTROOT=$(DSTROOT)" \
"SDKROOT=$(SDKROOT)"
clean:
installsrc:
pax -rw . $(SRCROOT)
else ifneq ($(findstring xnu_tests,$(RC_ProjectName)),)
export SYSCTL_HW_PHYSICALCPU := $(shell /usr/sbin/sysctl -n hw.physicalcpu)
export SYSCTL_HW_LOGICALCPU := $(shell /usr/sbin/sysctl -n hw.logicalcpu)
MAKEJOBS := --jobs=$(shell expr $(SYSCTL_HW_LOGICALCPU) + 1)
default: install
installhdrs:
install: xnu_tests
clean:
installsrc:
pax -rw . $(SRCROOT)
else ifeq ($(RC_ProjectName),xnu_tests_driverkit)
export SYSCTL_HW_PHYSICALCPU := $(shell /usr/sbin/sysctl -n hw.physicalcpu)
export SYSCTL_HW_LOGICALCPU := $(shell /usr/sbin/sysctl -n hw.logicalcpu)
MAKEJOBS := --jobs=$(shell expr $(SYSCTL_HW_LOGICALCPU) + 1)
default: install
installhdrs:
install: xnu_tests_driverkit
clean:
installsrc:
pax -rw . $(SRCROOT)
else # all other RC_ProjectName
ifndef CURRENT_BUILD_CONFIG
# avoid having to include MakeInc.cmd
ifeq ($(RC_XBS),YES)
_v =
else ifeq ($(VERBOSE),YES)
_v =
else
_v = @
endif
#
# Setup for parallel sub-makes, taking into account physical and logical
# CPUs. If the system does not support SMT, use N+1.
# If MAKEJOBS or -jN is passed on the make line, that takes precedence.
#
export SYSCTL_HW_PHYSICALCPU := $(shell /usr/sbin/sysctl -n hw.physicalcpu)
export SYSCTL_HW_LOGICALCPU := $(shell /usr/sbin/sysctl -n hw.logicalcpu)
MAKEJOBS := --jobs=$(shell expr $(SYSCTL_HW_LOGICALCPU) + 1)
TOP_TARGETS = \
clean \
installsrc \
exporthdrs \
all all_desktop all_embedded \
all_release_embedded all_development_embedded \
installhdrs installhdrs_desktop installhdrs_embedded \
installhdrs_release_embedded installhdrs_development_embedded \
install install_desktop install_embedded \
install_release_embedded install_development_embedded \
install_kernels \
cscope tags TAGS \
help
DEFAULT_TARGET = all
# Targets for internal build system debugging
TOP_TARGETS += \
print_exports print_exports_first_build_config \
setup \
build \
config \
install_textfiles \
install_config
ifeq ($(BUILD_JSON_COMPILATION_DATABASE),1)
MAKEARGS += -B
DEFAULT_TARGET := build
endif
.PHONY: $(TOP_TARGETS)
default: $(DEFAULT_TARGET)
ifneq ($(REMOTEBUILD),)
$(TOP_TARGETS):
$(_v)$(VERSDIR)/tools/remote_build.sh _REMOTEBUILD_TARGET=$@ _REMOTEBUILD_MAKE=$(MAKE) $(if $(filter --,$(MAKEFLAGS)),-,)$(MAKEFLAGS)
else
$(TOP_TARGETS):
$(_v)$(MAKE) $(MAKEARGS) -r $(if $(filter -j,$(MAKEFLAGS)),,$(MAKEJOBS)) -f $(MakeInc_top) $@
endif
else # CURRENT_BUILD_CONFIG
include $(MakeInc_cmd)
include $(MakeInc_def)
ALL_SUBDIRS = \
security \
bsd \
iokit \
osfmk \
pexpert \
libkern \
libsa \
config \
san
CONFIG_SUBDIRS = config tools san
INSTINC_SUBDIRS = $(ALL_SUBDIRS) EXTERNAL_HEADERS
INSTINC_SUBDIRS_X86_64 = $(INSTINC_SUBDIRS)
INSTINC_SUBDIRS_X86_64H = $(INSTINC_SUBDIRS)
INSTINC_SUBDIRS_ARM = $(INSTINC_SUBDIRS)
INSTINC_SUBDIRS_ARM64 = $(INSTINC_SUBDIRS)
EXPINC_SUBDIRS = $(ALL_SUBDIRS)
EXPINC_SUBDIRS_X86_64 = $(EXPINC_SUBDIRS)
EXPINC_SUBDIRS_X86_64H = $(EXPINC_SUBDIRS)
EXPINC_SUBDIRS_ARM = $(EXPINC_SUBDIRS)
EXPINC_SUBDIRS_ARM64 = $(EXPINC_SUBDIRS)
SETUP_SUBDIRS = SETUP san bsd
COMP_SUBDIRS_X86_64 = $(ALL_SUBDIRS)
COMP_SUBDIRS_X86_64H = $(ALL_SUBDIRS)
COMP_SUBDIRS_ARM = $(ALL_SUBDIRS)
COMP_SUBDIRS_ARM64 = $(ALL_SUBDIRS)
INSTTEXTFILES_SUBDIRS = \
bsd
INSTTEXTFILES_SUBDIRS_X86_64 = $(INSTTEXTFILES_SUBDIRS)
INSTTEXTFILES_SUBDIRS_X86_64H = $(INSTTEXTFILES_SUBDIRS)
INSTTEXTFILES_SUBDIRS_ARM = $(INSTTEXTFILES_SUBDIRS)
INSTTEXTFILES_SUBDIRS_ARM64 = $(INSTTEXTFILES_SUBDIRS)
include $(MakeInc_kernel)
include $(MakeInc_rule)
include $(MakeInc_dir)
endif # CURRENT_BUILD_CONFIG
endif # all other RC_ProjectName
installapi_libkdd installhdrs_libkdd install_libkdd:
cd libkdd; \
xcodebuild -target Default $(subst _libkdd,,$@) \
$(MAKEOVERRIDES) \
"SRCROOT=$(SRCROOT)/libkdd" \
"OBJROOT=$(OBJROOT)" \
"SYMROOT=$(SYMROOT)" \
"DSTROOT=$(DSTROOT)" \
"SDKROOT=$(SDKROOT)"
installapi_libkdd_tests installhdrs_libkdd_tests install_libkdd_tests:
cd libkdd; \
xcodebuild -target tests $(subst _libkdd_tests,,$@) \
$(MAKEOVERRIDES) \
"SRCROOT=$(SRCROOT)/libkdd" \
"OBJROOT=$(OBJROOT)" \
"SYMROOT=$(SYMROOT)" \
"DSTROOT=$(DSTROOT)" \
"SDKROOT=$(SDKROOT)"
installapi_libkdd_host installhdrs_libkdd_host install_libkdd_host:
cd libkdd; \
xcodebuild -configuration ReleaseHost -target kdd.framework $(subst _libkdd_host,,$@) \
$(MAKEOVERRIDES) \
"SRCROOT=$(SRCROOT)/libkdd" \
"OBJROOT=$(OBJROOT)" \
"SYMROOT=$(SYMROOT)" \
"DSTROOT=$(DSTROOT)" \
"SDKROOT=$(SDKROOT)"
# "xnu_tests" and "testbots" are targets that can be invoked via a standalone
# "make xnu_tests" or via buildit/XBS with the RC_ProjectName=xnu_tests.
# Define the target here in the outermost scope of the initial Makefile
xnu_tests:
$(MAKE) -C $(SRCROOT)/tools/tests $(if $(filter -j,$(MAKEFLAGS)),,$(MAKEJOBS)) \
SRCROOT=$(SRCROOT)/tools/tests
$(MAKE) -C $(SRCROOT)/tests $(if $(filter -j,$(MAKEFLAGS)),,$(MAKEJOBS)) \
SRCROOT=$(SRCROOT)/tests
xnu_tests_driverkit:
$(MAKE) -C $(SRCROOT)/tests/driverkit $(if $(filter -j,$(MAKEFLAGS)),,$(MAKEJOBS)) \
SRCROOT=$(SRCROOT)/tests/driverkit
include $(MakeInc_cmd)
#
# The "analyze" target defined below invokes Clang Static Analyzer
# with a predefined set of checks and options for the project.
#
# By default, analysis results are available in BUILD/StaticAnalyzer.
# Set this variable in your make invocation to use a different directory.
# Note that these results are only deleted when the build directory
# is cleaned. They aren't deleted every time the analyzer is re-run,
# but they are deleted after "make clean".
STATIC_ANALYZER_OUTPUT_DIR ?= $(SRCROOT)/BUILD/StaticAnalyzer
# By default, the default make target is analyzed. You can analyze
# other targets by setting this variable in your make invocation.
STATIC_ANALYZER_TARGET ?=
# You can pass additional flags to scan-build by setting this variable
# in your make invocation. For example, you can enable additional checks.
STATIC_ANALYZER_EXTRA_FLAGS ?=
analyze:
# This is where the reports are going to be available.
# Old reports are deleted on make clean only.
$(_v)$(MKDIR) $(STATIC_ANALYZER_OUTPUT_DIR)
# Recursively build the requested target under scan-build.
# Exclude checks that weren't deemed to be security critical,
# like null pointer dereferences.
$(_v)$(XCRUN) $(SCAN_BUILD) -o $(STATIC_ANALYZER_OUTPUT_DIR) \
-disable-checker deadcode.DeadStores \
-disable-checker core.NullDereference \
-disable-checker core.DivideZero \
$(STATIC_ANALYZER_EXTRA_FLAGS) \
$(MAKE) $(STATIC_ANALYZER_TARGET) QUIET=1 2>&1 | $(GREP) "^scan-build:"
.PHONY: analyze

416
README.md Normal file
View File

@ -0,0 +1,416 @@
What is XNU?
===========
XNU kernel is part of the Darwin operating system for use in macOS and iOS operating systems. XNU is an acronym for X is Not Unix.
XNU is a hybrid kernel combining the Mach kernel developed at Carnegie Mellon University with components from FreeBSD and a C++ API for writing drivers called IOKit.
XNU runs on x86_64 for both single processor and multi-processor configurations.
XNU Source Tree
===============
* `config` - configurations for exported apis for supported architecture and platform
* `SETUP` - Basic set of tools used for configuring the kernel, versioning and kextsymbol management.
* `EXTERNAL_HEADERS` - Headers sourced from other projects to avoid dependency cycles when building. These headers should be regularly synced when source is updated.
* `libkern` - C++ IOKit library code for handling of drivers and kexts.
* `libsa` - kernel bootstrap code for startup
* `libsyscall` - syscall library interface for userspace programs
* `libkdd` - source for user library for parsing kernel data like kernel chunked data.
* `makedefs` - top level rules and defines for kernel build.
* `osfmk` - Mach kernel based subsystems
* `pexpert` - Platform specific code like interrupt handling, atomics etc.
* `security` - Mandatory Access Check policy interfaces and related implementation.
* `bsd` - BSD subsystems code
* `tools` - A set of utilities for testing, debugging and profiling kernel.
How to build XNU
================
Building `DEVELOPMENT` kernel
-----------------------------
The xnu make system can build kernel based on `KERNEL_CONFIGS` & `ARCH_CONFIGS` variables as arguments.
Here is the syntax:
make SDKROOT=<sdkroot> ARCH_CONFIGS=<arch> KERNEL_CONFIGS=<variant>
Where:
* \<sdkroot>: path to macOS SDK on disk. (defaults to `/`)
* \<variant>: can be `debug`, `development`, `release`, `profile` and configures compilation flags and asserts throughout kernel code.
* \<arch> : can be valid arch to build for. (E.g. `X86_64`)
To build a kernel for the same architecture as running OS, just type
$ make
$ make SDKROOT=macosx.internal
Additionally, there is support for configuring architectures through `ARCH_CONFIGS` and kernel configurations with `KERNEL_CONFIGS`.
$ make SDKROOT=macosx.internal ARCH_CONFIGS=X86_64 KERNEL_CONFIGS=DEVELOPMENT
$ make SDKROOT=macosx.internal ARCH_CONFIGS=X86_64 KERNEL_CONFIGS="RELEASE DEVELOPMENT DEBUG"
Note:
* By default, architecture is set to the build machine architecture, and the default kernel
config is set to build for DEVELOPMENT.
This will also create a bootable image, kernel.[config], and a kernel binary
with symbols, kernel.[config].unstripped.
To intall the kernel into a DSTROOT, use the `install_kernels` target:
$ make install_kernels DSTROOT=/tmp/xnu-dst
Hint:
For a more satisfying kernel debugging experience, with access to all
local variables and arguments, but without all the extra check of the
DEBUG kernel, add something like:
CFLAGS_DEVELOPMENTARM64="-O0 -g -DKERNEL_STACK_MULTIPLIER=2"
CXXFLAGS_DEVELOPMENTARM64="-O0 -g -DKERNEL_STACK_MULTIPLIER=2"
to your make command.
Replace DEVELOPMENT and ARM64 with the appropriate build and platform.
* To build with RELEASE kernel configuration
make KERNEL_CONFIGS=RELEASE SDKROOT=/path/to/SDK
Building FAT kernel binary
--------------------------
Define architectures in your environment or when running a make command.
$ make ARCH_CONFIGS="X86_64" exporthdrs all
Other makefile options
----------------------
* $ make MAKEJOBS=-j8 # this will use 8 processes during the build. The default is 2x the number of active CPUS.
* $ make -j8 # the standard command-line option is also accepted
* $ make -w # trace recursive make invocations. Useful in combination with VERBOSE=YES
* $ make BUILD_LTO=0 # build without LLVM Link Time Optimization
* $ make REMOTEBUILD=user@remotehost # perform build on remote host
* $ make BUILD_JSON_COMPILATION_DATABASE=1 # Build Clang JSON Compilation Database
The XNU build system can optionally output color-formatted build output. To enable this, you can either
set the `XNU_LOGCOLORS` environment variable to `y`, or you can pass `LOGCOLORS=y` to the make command.
Debug information formats
=========================
By default, a DWARF debug information repository is created during the install phase; this is a "bundle" named kernel.development.\<variant>.dSYM
To select the older STABS debug information format (where debug information is embedded in the kernel.development.unstripped image), set the BUILD_STABS environment variable.
$ export BUILD_STABS=1
$ make
Building KernelCaches
=====================
To test the xnu kernel, you need to build a kernelcache that links the kexts and
kernel together into a single bootable image.
To build a kernelcache you can use the following mechanisms:
* Using automatic kernelcache generation with `kextd`.
The kextd daemon keeps watching for changing in `/System/Library/Extensions` directory.
So you can setup new kernel as
$ cp BUILD/obj/DEVELOPMENT/X86_64/kernel.development /System/Library/Kernels/
$ touch /System/Library/Extensions
$ ps -e | grep kextd
* Manually invoking `kextcache` to build new kernelcache.
$ kextcache -q -z -a x86_64 -l -n -c /var/tmp/kernelcache.test -K /var/tmp/kernel.test /System/Library/Extensions
Running KernelCache on Target machine
=====================================
The development kernel and iBoot supports configuring boot arguments so that we can safely boot into test kernel and, if things go wrong, safely fall back to previously used kernelcache.
Following are the steps to get such a setup:
1. Create kernel cache using the kextcache command as `/kernelcache.test`
2. Copy exiting boot configurations to alternate file
$ cp /Library/Preferences/SystemConfiguration/com.apple.Boot.plist /next_boot.plist
3. Update the kernelcache and boot-args for your setup
$ plutil -insert "Kernel Cache" -string "kernelcache.test" /next_boot.plist
$ plutil -replace "Kernel Flags" -string "debug=0x144 -v kernelsuffix=test " /next_boot.plist
4. Copy the new config to `/Library/Preferences/SystemConfiguration/`
$ cp /next_boot.plist /Library/Preferences/SystemConfiguration/boot.plist
5. Bless the volume with new configs.
$ sudo -n bless --mount / --setBoot --nextonly --options "config=boot"
The `--nextonly` flag specifies that use the `boot.plist` configs only for one boot.
So if the kernel panic's you can easily power reboot and recover back to original kernel.
Creating tags and cscope
========================
Set up your build environment and from the top directory, run:
$ make tags # this will build ctags and etags on a case-sensitive volume, only ctags on case-insensitive
$ make TAGS # this will build etags
$ make cscope # this will build cscope database
How to install a new header file from XNU
=========================================
To install IOKit headers, see additional comments in [iokit/IOKit/Makefile]().
XNU installs header files at the following locations -
a. $(DSTROOT)/System/Library/Frameworks/Kernel.framework/Headers
b. $(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders
c. $(DSTROOT)/usr/include/
d. $(DSTROOT)/System/DriverKit/usr/include/
e. $(DSTROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
`Kernel.framework` is used by kernel extensions.\
The `System.framework` and `/usr/include` are used by user level applications. \
`/System/DriverKit/usr/include` is used by userspace drivers. \
The header files in framework's `PrivateHeaders` are only available for ** Apple Internal Development **.
The directory containing the header file should have a Makefile that
creates the list of files that should be installed at different locations.
If you are adding the first header file in a directory, you will need to
create Makefile similar to `xnu/bsd/sys/Makefile`.
Add your header file to the correct file list depending on where you want
to install it. The default locations where the header files are installed
from each file list are -
a. `DATAFILES` : To make header file available in user level -
`$(DSTROOT)/usr/include`
b. `DRIVERKIT_DATAFILES` : To make header file available to DriverKit userspace drivers -
`$(DSTROOT)/System/DriverKit/usr/include`
c. `PRIVATE_DATAFILES` : To make header file available to Apple internal in
user level -
`$(DSTROOT)/System/Library/Frameworks/System.framework/PrivateHeaders`
d. `KERNELFILES` : To make header file available in kernel level -
`$(DSTROOT)/System/Library/Frameworks/Kernel.framework/Headers`
`$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders`
e. `PRIVATE_KERNELFILES` : To make header file available to Apple internal
for kernel extensions -
`$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders`
The Makefile combines the file lists mentioned above into different
install lists which are used by build system to install the header files. There
are two types of install lists: machine-dependent and machine-independent.
These lists are indicated by the presence of `MD` and `MI` in the build
setting, respectively. If your header is architecture-specific, then you should
use a machine-dependent install list (e.g. `INSTALL_MD_LIST`). If your header
should be installed for all architectures, then you should use a
machine-independent install list (e.g. `INSTALL_MI_LIST`).
If the install list that you are interested does not exist, create it
by adding the appropriate file lists. The default install lists, its
member file lists and their default location are described below -
a. `INSTALL_MI_LIST` : Installs header file to a location that is available to everyone in user level.
Locations -
$(DSTROOT)/usr/include
Definition -
INSTALL_MI_LIST = ${DATAFILES}
b. `INSTALL_DRIVERKIT_MI_LIST` : Installs header file to a location that is
available to DriverKit userspace drivers.
Locations -
$(DSTROOT)/System/DriverKit/usr/include
Definition -
INSTALL_DRIVERKIT_MI_LIST = ${DRIVERKIT_DATAFILES}
c. `INSTALL_MI_LCL_LIST` : Installs header file to a location that is available
for Apple internal in user level.
Locations -
$(DSTROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
Definition -
INSTALL_MI_LCL_LIST = ${PRIVATE_DATAFILES}
d. `INSTALL_KF_MI_LIST` : Installs header file to location that is available
to everyone for kernel extensions.
Locations -
$(DSTROOT)/System/Library/Frameworks/Kernel.framework/Headers
Definition -
INSTALL_KF_MI_LIST = ${KERNELFILES}
e. `INSTALL_KF_MI_LCL_LIST` : Installs header file to location that is
available for Apple internal for kernel extensions.
Locations -
$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders
Definition -
INSTALL_KF_MI_LCL_LIST = ${KERNELFILES} ${PRIVATE_KERNELFILES}
f. `EXPORT_MI_LIST` : Exports header file to all of xnu (bsd/, osfmk/, etc.)
for compilation only. Does not install anything into the SDK.
Definition -
EXPORT_MI_LIST = ${KERNELFILES} ${PRIVATE_KERNELFILES}
g. `INSTALL_MODULEMAP_INCDIR_MI_LIST` : Installs module map file to a
location that is available to everyone in user level, installing at the
root of INCDIR.
Locations -
$(DSTROOT)/usr/include
Definition -
INSTALL_MODULEMAP_INCDIR_MI_LIST = ${MODULEMAP_INCDIR_FILES}
If you want to install the header file in a sub-directory of the paths
described in (1), specify the directory name using two variables
`INSTALL_MI_DIR` and `EXPORT_MI_DIR` as follows -
INSTALL_MI_DIR = dirname
EXPORT_MI_DIR = dirname
A single header file can exist at different locations using the steps
mentioned above. However it might not be desirable to make all the code
in the header file available at all the locations. For example, you
want to export a function only to kernel level but not user level.
You can use C language's pre-processor directive (#ifdef, #endif, #ifndef)
to control the text generated before a header file is installed. The kernel
only includes the code if the conditional macro is TRUE and strips out
code for FALSE conditions from the header file.
Some pre-defined macros and their descriptions are -
a. `PRIVATE` : If defined, enclosed definitions are considered System
Private Interfaces. These are visible within xnu and
exposed in user/kernel headers installed within the AppleInternal
"PrivateHeaders" sections of the System and Kernel frameworks.
b. `KERNEL_PRIVATE` : If defined, enclosed code is available to all of xnu
kernel and Apple internal kernel extensions and omitted from user
headers.
c. `BSD_KERNEL_PRIVATE` : If defined, enclosed code is visible exclusively
within the xnu/bsd module.
d. `MACH_KERNEL_PRIVATE`: If defined, enclosed code is visible exclusively
within the xnu/osfmk module.
e. `XNU_KERNEL_PRIVATE`: If defined, enclosed code is visible exclusively
within xnu.
f. `KERNEL` : If defined, enclosed code is available within xnu and kernel
extensions and is not visible in user level header files. Only the
header files installed in following paths will have the code -
$(DSTROOT)/System/Library/Frameworks/Kernel.framework/Headers
$(DSTROOT)/System/Library/Frameworks/Kernel.framework/PrivateHeaders
g. `DRIVERKIT`: If defined, enclosed code is visible exclusively in the
DriverKit SDK headers used by userspace drivers.
Conditional compilation
=======================
`xnu` offers the following mechanisms for conditionally compiling code:
a. *CPU Characteristics* If the code you are guarding has specific
characterstics that will vary only based on the CPU architecture being
targeted, use this option. Prefer checking for features of the
architecture (e.g. `__LP64__`, `__LITTLE_ENDIAN__`, etc.).
b. *New Features* If the code you are guarding, when taken together,
implements a feature, you should define a new feature in `config/MASTER`
and use the resulting `CONFIG` preprocessor token (e.g. for a feature
named `config_virtual_memory`, check for `#if CONFIG_VIRTUAL_MEMORY`).
This practice ensures that existing features may be brought to other
platforms by simply changing a feature switch.
c. *Existing Features* You can use existing features if your code is
strongly tied to them (e.g. use `SECURE_KERNEL` if your code implements
new functionality that is exclusively relevant to the trusted kernel and
updates the definition/understanding of what being a trusted kernel means).
It is recommended that you avoid compiling based on the target platform. `xnu`
does not define the platform macros from `TargetConditionals.h`
(`TARGET_OS_OSX`, `TARGET_OS_IOS`, etc.).
There is a deprecated `TARGET_OS_EMBEDDED` macro, but this should be avoided
as it is in general too broad a definition for most functionality.
Please refer to TargetConditionals.h for a full picture.
How to add a new syscall
========================
Testing the kernel
==================
XNU kernel has multiple mechanisms for testing.
* Assertions - The DEVELOPMENT and DEBUG kernel configs are compiled with assertions enabled. This allows developers to easily
test invariants and conditions.
* XNU Power On Self Tests (`XNUPOST`): The XNUPOST config allows for building the kernel with basic set of test functions
that are run before first user space process is launched. Since XNU is hybrid between MACH and BSD, we have two locations where
tests can be added.
xnu/osfmk/tests/ # For testing mach based kernel structures and apis.
bsd/tests/ # For testing BSD interfaces.
Please follow the documentation at [osfmk/tests/README.md](osfmk/tests/README.md)
* User level tests: The `tools/tests/` directory holds all the tests that verify syscalls and other features of the xnu kernel.
The make target `xnu_tests` can be used to build all the tests supported.
$ make RC_ProjectName=xnu_tests SDKROOT=/path/to/SDK
These tests are individual programs that can be run from Terminal and report tests status by means of std posix exit codes (0 -> success) and/or stdout.
Please read detailed documentation in [tools/tests/unit_tests/README.md](tools/tests/unit_tests/README.md)
Kernel data descriptors
=======================
XNU uses different data formats for passing data in its api. The most standard way is using syscall arguments. But for complex data
it often relies of sending memory saved by C structs. This packaged data transport mechanism is fragile and leads to broken interfaces
between user space programs and kernel apis. `libkdd` directory holds user space library that can parse custom data provided by the
same version of kernel. The kernel chunked data format is described in detail at [libkdd/README.md](libkdd/README.md).
Debugging the kernel
====================
The xnu kernel supports debugging with a remote kernel debugging protocol (kdp). Please refer documentation at [technical note] [TN2063]
By default the kernel is setup to reboot on a panic. To debug a live kernel, the kdp server is setup to listen for UDP connections
over ethernet. For machines without ethernet port, this behavior can be altered with use of kernel boot-args. Following are some
common options.
* `debug=0x144` - setups debug variables to start kdp debugserver on panic
* `-v` - print kernel logs on screen. By default XNU only shows grey screen with boot art.
* `kdp_match_name=en1` - Override default port selection for kdp. Supported for ethernet, thunderbolt and serial debugging.
To debug a panic'ed kernel, use llvm debugger (lldb) along with unstripped symbol rich kernel binary.
sh$ lldb kernel.development.unstripped
And then you can connect to panic'ed machine with `kdp_remote [ip addr]` or `gdb_remote [hostip : port]` commands.
Each kernel is packaged with kernel specific debug scripts as part of the build process. For security reasons these special commands
and scripts do not get loaded automatically when lldb is connected to machine. Please add the following setting to your `~/.lldbinit`
if you wish to always load these macros.
settings set target.load-script-from-symbol-file true
The `tools/lldbmacros` directory contains the source for each of these commands. Please follow the [README.md](tools/lldbmacros/README.md)
for detailed explanation of commands and their usage.
[TN2118]: https://developer.apple.com/library/mac/technotes/tn2004/tn2118.html#//apple_ref/doc/uid/DTS10003352 "Kernel Core Dumps"
[TN2063]: https://developer.apple.com/library/mac/technotes/tn2063/_index.html "Understanding and Debugging Kernel Panics"
[Kernel Programming Guide]: https://developer.apple.com/library/mac/documentation/Darwin/Conceptual/KernelProgramming/build/build.html#//apple_ref/doc/uid/TP30000905-CH221-BABDGEGF

22
SETUP/Makefile Normal file
View File

@ -0,0 +1,22 @@
export MakeInc_cmd=${SRCROOT}/makedefs/MakeInc.cmd
export MakeInc_def=${SRCROOT}/makedefs/MakeInc.def
export MakeInc_rule=${SRCROOT}/makedefs/MakeInc.rule
export MakeInc_dir=${SRCROOT}/makedefs/MakeInc.dir
include $(MakeInc_cmd)
include $(MakeInc_def)
SETUP_SUBDIRS = \
config \
kextsymboltool \
setsegname \
decomment \
installfile \
replacecontents
ifeq ($(BUILD_JSON_COMPILATION_DATABASE),1)
SETUP_SUBDIRS += json_compilation_db
endif
include $(MakeInc_rule)
include $(MakeInc_dir)

42
SETUP/config/Makefile Normal file
View File

@ -0,0 +1,42 @@
export MakeInc_cmd=${SRCROOT}/makedefs/MakeInc.cmd
export MakeInc_def=${SRCROOT}/makedefs/MakeInc.def
export MakeInc_rule=${SRCROOT}/makedefs/MakeInc.rule
export MakeInc_dir=${SRCROOT}/makedefs/MakeInc.dir
include $(MakeInc_cmd)
include $(MakeInc_def)
OBJS = externs.o main.o mkheaders.o mkioconf.o mkmakefile.o \
openp.o searchp.o lexer.yy.o parser.o
CFLAGS = -isysroot $(HOST_SDKROOT) -mmacosx-version-min=$(HOST_OS_VERSION) -g -O0 -I$(SOURCE) -I.
CFLAGS += -DYY_NO_INPUT
WARNFLAGS = -Wall
LDFLAGS = -isysroot $(HOST_SDKROOT) -mmacosx-version-min=$(HOST_OS_VERSION)
config: $(OBJS)
@$(LOG_HOST_LD) "$@"
$(_v)$(HOST_CC) $(LDFLAGS) -o $@ $^
@$(LOG_HOST_CODESIGN) "$@"
$(_v)env CODESIGN_ALLOCATE=$(HOST_CODESIGN_ALLOCATE) $(HOST_CODESIGN) -s - $@
%.o: %.c
@$(LOG_HOST_CC) "$@"
$(_v)$(HOST_CC) $(WARNFLAGS) $(CFLAGS) -c -o $@ $<
parser.c: parser.y
@$(LOG_HOST_BISON) "$@"
$(_v)$(HOST_BISON) -y -d -d -o $@ $<
lexer.yy.c: lexer.l
@$(LOG_HOST_FLEX) "$@"
$(_v)env M4=$(HOST_GM4) $(HOST_FLEX) --header-file=lexer.yy.h -o $@ $<
main.o mkheaders.o mkioconf.o mkmakefile.o lexer.yy.c: parser.c
do_build_setup:: config
include $(MakeInc_rule)
include $(MakeInc_dir)

173
SETUP/config/config.h Normal file
View File

@ -0,0 +1,173 @@
/*
* Copyright (c) 1999-2009 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License."
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Mach Operating System
* Copyright (c) 1990 Carnegie-Mellon University
* Copyright (c) 1989 Carnegie-Mellon University
* Copyright (c) 1988 Carnegie-Mellon University
* Copyright (c) 1987 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)config.h 5.8 (Berkeley) 6/18/88
*/
/*
* Config.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/param.h>
#include <stdlib.h>
#include <string.h>
struct file_list {
struct file_list *f_next;
char *f_fn; /* the name */
u_char f_type; /* see below */
u_char f_flags; /* see below */
short f_special; /* requires special make rule */
char *f_needs;
char *f_extra; /* stuff to add to make line */
};
/*
* Types.
*/
#define DRIVER 1
#define NORMAL 2
#define INVISIBLE 3
#define PROFILING 4
/*
* Attributes (flags).
*/
#define CONFIGDEP 0x01 /* obsolete? */
#define OPTIONSDEF 0x02 /* options definition entry */
#define LIBRARYDEP 0x04 /* include file in library build */
struct device {
int d_type; /* CONTROLLER, DEVICE, bus adaptor */
const char *d_name; /* name of device (e.g. rk11) */
int d_slave; /* slave number */
#define QUES -1 /* -1 means '?' */
#define UNKNOWN -2 /* -2 means not set yet */
int d_flags; /* nlags for device init */
struct device *d_next; /* Next one in list */
char *d_init; /* pseudo device init routine name */
};
/*
* Config has a global notion of which machine type is
* being used. It uses the name of the machine in choosing
* files and directories. Thus if the name of the machine is ``vax'',
* it will build from ``Makefile.vax'' and use ``../vax/inline''
* in the makerules, etc.
*/
extern const char *machinename;
/*
* In order to configure and build outside the kernel source tree,
* we may wish to specify where the source tree lives.
*/
extern const char *source_directory;
extern const char *object_directory;
extern char *config_directory;
FILE *fopenp(const char *fpath, char *file, char *complete, const char *ftype);
const char *get_VPATH(void);
#define VPATH get_VPATH()
/*
* A set of options may also be specified which are like CPU types,
* but which may also specify values for the options.
* A separate set of options may be defined for make-style options.
*/
struct opt {
char *op_name;
char *op_value;
struct opt *op_next;
};
extern struct opt *opt, *mkopt, *opt_tail, *mkopt_tail;
const char *get_word(FILE *fp);
char *ns(const char *str);
char *qu(int num);
char *path(const char *file);
extern int do_trace;
extern struct device *dtab;
dev_t nametodev(char *name, int defunit, char defpartition);
char *devtoname(dev_t dev);
extern char errbuf[80];
extern int yyline;
extern struct file_list *ftab, *conf_list, **confp;
extern char *build_directory;
extern int profiling;
#define eq(a, b) (!strcmp(a,b))
#define DEV_MASK 0x7
#define DEV_SHIFT 3
/* External function references */
char *get_rest(FILE *fp);
int yyparse(void);
void yyerror(const char *s);
void mkioconf(void);
void makefile(void);
void headers(void);
int opteq(const char *cp, const char *dp);
void init_dev(struct device *dp);
void newdev(struct device *dp);
void dev_param(struct device *dp, const char *str, long num);
int searchp(const char *spath, char *file, char *fullname, int (*func)(char *));

305
SETUP/config/doconf Executable file
View File

@ -0,0 +1,305 @@
#!/bin/csh -f
set path = ($path .)
######################################################################
# HISTORY
# 1-Dec-87 Michael Young (mwyoung) at Carnegie-Mellon University
# Added "-verbose" switch, so this script produces no output
# in the normal case.
#
# 10-Oct-87 Mike Accetta (mja) at Carnegie-Mellon University
# Flushed cmu_*.h and spin_locks.h
# [ V5.1(XF18) ]
#
# 6-Apr-87 Avadis Tevanian (avie) at Carnegie-Mellon University
# Use MASTER.local and MASTER.<machine>.local for generation of
# configuration files in addition to MASTER and MASTER.<machine>.
#
# 25-Mar-87 Mike Accetta (mja) at Carnegie-Mellon University
# Removed use of obsolete wb_*.h files when building the feature
# list; modified to save the previous configuration file and
# display the differences between it and the new file.
# [ V5.1(F8) ]
#
# 25-Mar-87 Avadis Tevanian (avie) at Carnegie-Mellon University
# If there is no /etc/machine just print out a message telling
# user to use the -cpu option. I thought this script was supposed
# to work even without a /etc/machine, but it doesn't... and this
# is the easiest way out.
#
# 13-Mar-87 Mike Accetta (mja) at Carnegie-Mellon University
# Added "romp_fpa.h" file to extra features for the RT.
# [ V5.1(F7) ]
#
# 11-Mar-87 Mike Accetta (mja) at Carnegie-Mellon University
# Updated to maintain the appropriate configuration features file
# in the "machine" directory whenever the corresponding
# configuration is generated. This replaces the old mechanism of
# storing this directly in the <sys/features.h> file since it was
# machine dependent and also precluded building programs for more
# than one configuration from the same set of sources.
# [ V5.1(F6) ]
#
# 21-Feb-87 Mike Accetta (mja) at Carnegie-Mellon University
# Fixed to require wired-in cpu type names for only those
# machines where the kernel name differs from that provided by
# /etc/machine (i.e. IBMRT => ca and SUN => sun3); updated to
# permit configuration descriptions in both machine indepedent
# and dependent master configuration files so that attributes can
# be grouped accordingly.
# [ V5.1(F3) ]
#
# 17-Jan-87 Mike Accetta (mja) at Carnegie-Mellon University
# Updated to work from any directory at the same level as
# "conf"; generate configuration from both MASTER and
# MASTER.<machine-type> files; added -cpu switch.
# [ V5.1(F1) ]
#
# 18-Aug-86 Mike Accetta (mja) at Carnegie-Mellon University
# Added -make switch and changed meaning of -config; upgraded to
# allow multiple attributes per configuration and to define
# configurations in terms of these attributes within MASTER.
#
# 14-Apr-83 Mike Accetta (mja) at Carnegie-Mellon University
# Added -config switch to only run /etc/config without
# "make depend" and "make".
#
######################################################################
set prog=$0
set prog=$prog:t
set nonomatch
set OBJDIR=../BUILD
set SOURCEDIR=.
set CONFIG_DIR=$OBJROOT/SETUP/config
set MASTER_CONF_DIR=.
unset doconfig
unset beverbose
unset MACHINE
unset profile
unset SOC_CONFIG
unset PLATFORM
while ($#argv >= 1)
if ("$argv[1]" =~ -*) then
switch ("$argv[1]")
case "-c":
case "-config":
set doconfig
breaksw
case "-cpu":
if ($#argv < 2) then
echo "${prog}: missing argument to ${argv[1]}"
exit 1
endif
set MACHINE="$argv[2]"
shift
breaksw
case "-soc":
if ($#argv < 2) then
echo "${prog}: missing argument to ${argv[1]}"
exit 1
endif
set SOC_CONFIG="$argv[2]"
shift
breaksw
case "-platform":
if ($#argv < 2) then
echo "${prog}: missing argument to ${argv[1]}"
exit 1
endif
set PLATFORM="$argv[2]"
shift
breaksw
case "-d":
if ($#argv < 2) then
echo "${prog}: missing argument to ${argv[1]}"
exit 1
endif
set OBJDIR="$argv[2]"
shift
breaksw
case "-m":
if ($#argv < 2) then
echo "${prog}: missing argument to ${argv[1]}"
exit 1
endif
set MASTER_CONF_DIR="$argv[2]"
shift
breaksw
case "-s":
if ($#argv < 2) then
echo "${prog}: missing argument to ${argv[1]}"
exit 1
endif
set SOURCEDIR="$argv[2]"
shift
breaksw
case "-verbose":
set beverbose
breaksw
case "-p":
case "-profile":
set profile
breaksw
default:
echo "${prog}: ${argv[1]}: unknown switch"
exit 1
breaksw
endsw
shift
else
break
endif
end
if ($#argv == 0) set argv=(GENERIC)
if (! $?MACHINE) then
echo "${prog}: MACHINE not set"
exit 1
endif
set cpu=`echo $MACHINE | tr A-Z a-z`
set ID=`echo $MACHINE | tr a-z A-Z`
set MASTER_DIR=${MASTER_CONF_DIR}
set MASTER = ${MASTER_DIR}/MASTER
foreach master_file (${MASTER}.${cpu}.${SOC_CONFIG}.${PLATFORM} ${MASTER}.${cpu}.${SOC_CONFIG} ${MASTER}.${cpu}.${PLATFORM} ${MASTER}.${cpu})
if (-f $master_file) then
set MASTER_CPU = $master_file
break
endif
end
if ($?beverbose) then
echo MASTER_CPU=$MASTER_CPU
endif
foreach SYS ($argv)
set SYSID=${SYS}_${ID}
set SYSCONF=$OBJDIR/config.$SYSID
set BLDDIR=$OBJDIR
if ($?beverbose) then
echo "[ generating $SYSID from $MASTER_DIR/MASTER{,.$cpu}{,.local} ]"
endif
echo +$SYS \
| \
cat $MASTER $MASTER_CPU - \
$MASTER $MASTER_CPU \
| \
unifdef -t -DPLATFORM_${PLATFORM} -DCPU_$cpu -DSOC_CONFIG_${SOC_CONFIG} -DSYS_${SYS} - \
| \
sed -n \
-e "/^+/{" \
-e "s;[-+];#&;gp" \
-e 't loop' \
-e ': loop' \
-e 'n' \
-e '/^#/b loop' \
-e '/^$/b loop' \
-e 's;^\([^#]*\).*#[ ]*<\(.*\)>[ ]*$;\2#\1;' \
-e 't not' \
-e 's;\([^#]*\).*;#\1;' \
-e 't not' \
-e ': not' \
-e 's;[ ]*$;;' \
-e 's;^\!\(.*\);\1#\!;' \
-e 'p' \
-e 't loop' \
-e 'b loop' \
-e '}' \
-e "/^[^#]/d" \
-e 's; ; ;g' \
-e "s;^# *\([^ ]*\)[ ]*=[ ]*\[\(.*\)\].*;\1#\2;p" \
| \
awk '-F#' '\
part == 0 && $1 != "" {\
m[$1]=m[$1] " " $2;\
next;\
}\
part == 0 && $1 == "" {\
for (i=NF;i>1;i--){\
s=substr($i,2);\
c[++na]=substr($i,1,1);\
a[na]=s;\
}\
while (na > 0){\
s=a[na];\
d=c[na--];\
if (m[s] == "") {\
f[s]=d;\
} else {\
nx=split(m[s],x," ");\
for (j=nx;j>0;j--) {\
z=x[j];\
a[++na]=z;\
c[na]=d;\
}\
}\
}\
part=1;\
next;\
}\
part != 0 {\
if ($1 != "") {\
n=split($1,x,",");\
ok=0;\
for (i=1;i<=n;i++) {\
if (f[x[i]] == "+") {\
ok=1;\
}\
}\
if (NF > 2 && ok == 0 || NF <= 2 && ok != 0) {\
print $2; \
}\
} else { \
print $2; \
}\
}\
' >$SYSCONF.new
if (-z $SYSCONF.new) then
echo "${prog}: ${$SYSID}: no such configuration in $MASTER_DIR/MASTER{,.$cpu}"
rm -f $SYSCONF.new
endif
#
# These paths are used by config.
#
# "builddir" is the name of the directory where kernel binaries
# are put. It is a single path element, never absolute, and is
# always relative to "objectdir". "builddir" is used by config
# solely to determine where to put files created by "config" (e.g.
# the created Makefile and *.h's.)
#
# "objectdir" is the name of the directory which will hold "builddir".
# It is a path; if relative, it is relative to the current directory
# where config is run. It's sole use is to be prepended to "builddir"
# to indicate where config-created files are to be placed (see above).
#
# "sourcedir" is the location of the sources used to build the kernel.
# It is a path; if relative, it is relative to the directory specified
# by the concatenation of "objectdir" and "builddir" (i.e. where the
# kernel binaries are put).
#
echo 'builddir "."' >> $SYSCONF.new
echo 'objectdir "'$OBJDIR'"' >> $SYSCONF.new
set SRCDIR=`dirname $SOURCE`
echo 'sourcedir "'$SRCROOT'"' >> $SYSCONF.new
if (-f $SYSCONF) then
diff $SYSCONF $SYSCONF.new
rm -f $SYSCONF.old
mv $SYSCONF $SYSCONF.old
endif
rm -f $SYSCONF
mv $SYSCONF.new $SYSCONF
if ($?doconfig) then
if ($?beverbose) then
echo "[ configuring $SYSID ]"
endif
if ($?profile) then
$CONFIG_DIR/config -c $SOURCEDIR -p $SYSCONF
else
$CONFIG_DIR/config -c $SOURCEDIR $SYSCONF
endif
endif
end

63
SETUP/config/externs.c Normal file
View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License."
*
* @APPLE_LICENSE_HEADER_END@
*/
/* Copyright (c) Apple Computer, Inc. All rights reserved. */
#include <config.h>
/*
* Config has a global notion of which machine type is
* being used. It uses the name of the machine in choosing
* files and directories. Thus if the name of the machine is ``vax'',
* it will build from ``Makefile.vax'' and use ``../vax/inline''
* in the makerules, etc.
*/
const char *machinename;
/*
* In order to configure and build outside the kernel source tree,
* we may wish to specify where the source tree lives.
*/
const char *source_directory;
const char *object_directory;
char *config_directory;
/*
* A set of options may also be specified which are like CPU types,
* but which may also specify values for the options.
* A separate set of options may be defined for make-style options.
*/
struct opt *opt, *mkopt, *opt_tail, *mkopt_tail;
int do_trace;
struct device *dtab;
char errbuf[80];
int yyline;
struct file_list *ftab, *conf_list, **confp;
char *build_directory;
int profiling = 0;

168
SETUP/config/lexer.l Normal file
View File

@ -0,0 +1,168 @@
%{
/*
* Mach Operating System
* Copyright (c) 1990 Carnegie-Mellon University
* Copyright (c) 1989 Carnegie-Mellon University
* Copyright (c) 1988 Carnegie-Mellon University
* Copyright (c) 1987 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)config.l 5.5 (Berkeley) 6/18/88
*/
#include <ctype.h>
#include "parser.h"
#include "config.h"
int kw_lookup(char *word);
int octal(char *str);
int hex(char *str);
int yylex(void);
#define tprintf if (do_trace) printf
/*
* Key word table
*/
struct kt {
const char *kt_name;
int kt_val;
} key_words[] = {
{ "builddir", BUILDDIR },
{ "init", INIT },
{ "machine", MACHINE },
{ "makeoptions", MAKEOPTIONS },
{ "makevariables", MAKEOPTIONS },
{ "objectdir", OBJECTDIR },
{ "options", OPTIONS },
{ "pseudo-device",PSEUDO_DEVICE },
{ "sourcedir", SOURCEDIR },
{ "trace", TRACE },
{ 0, 0 },
};
%}
%option nounput
WORD ([A-Za-z_][-A-Za-z_]*|[A-Z][-A-Za-z_0-9]*)
WORD1 ([A-Za-z_][-A-Za-z_0-9]*)
%%
{WORD} |
{WORD1} {
int i;
if ((i = kw_lookup(yytext)) == -1)
{
yylval.str = yytext;
tprintf("id(%s) ", yytext);
return ID;
}
tprintf("(%s) ", yytext);
return i;
}
\"[^"]+\" {
yytext[strlen(yytext)-1] = '\0';
yylval.str = yytext + 1;
return ID;
}
0[0-7]* {
yylval.val = octal(yytext);
tprintf("#O:%o ", yylval.val);
return NUMBER;
}
0x[0-9a-fA-F]+ {
yylval.val = hex(yytext);
tprintf("#X:%x ", yylval.val);
return NUMBER;
}
[1-9][0-9]* {
yylval.val = atoi(yytext);
tprintf("#D:%d ", yylval.val);
return NUMBER;
}
"?" {
yylval.val = -1;
tprintf("? ");
return NUMBER;
}
\n/[ \t] {
yyline++;
tprintf("\n... ");
}
\n {
yyline++;
tprintf("\n");
return SEMICOLON;
}
#.* { /* Ignored (comment) */; }
[ \t]* { /* Ignored (white space) */; }
";" { return SEMICOLON; }
"," { return COMMA; }
"=" { return EQUALS; }
. { return yytext[0]; }
%%
/*
* kw_lookup
* Look up a string in the keyword table. Returns a -1 if the
* string is not a keyword otherwise it returns the keyword number
*/
int
kw_lookup(char *word)
{
register struct kt *kp;
for (kp = key_words; kp->kt_name != 0; kp++)
if (eq(word, kp->kt_name))
return kp->kt_val;
return -1;
}
/*
* Number conversion routines
*/
int
octal(char *str)
{
int num;
(void) sscanf(str, "%o", &num);
return num;
}
int
hex(char *str)
{
int num;
(void) sscanf(str+2, "%x", &num);
return num;
}
int
yywrap()
{
return 1;
}

227
SETUP/config/main.c Normal file
View File

@ -0,0 +1,227 @@
/*
* Copyright (c) 1999-2009 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License."
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Mach Operating System
* Copyright (c) 1990 Carnegie-Mellon University
* Copyright (c) 1989 Carnegie-Mellon University
* Copyright (c) 1988 Carnegie-Mellon University
* Copyright (c) 1987 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1980 Regents of the University of California.\n\
All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] __attribute__((used)) = "@(#)main.c 5.9 (Berkeley) 6/18/88";
#endif /* not lint */
#include <stdio.h>
#include <ctype.h>
#include "parser.h"
#include "config.h"
/*
* Config builds a set of files for building a UNIX
* system given a description of the desired system.
*/
int
main(int argc, char *argv[])
{
source_directory = ".."; /* default */
object_directory = "..";
config_directory = (char *) 0;
while ((argc > 1) && (argv[1][0] == '-')) {
char *c;
argv++; argc--;
for (c = &argv[0][1]; *c; c++) {
switch (*c) {
case 'b':
build_directory = argv[1];
goto check_arg;
case 'd':
source_directory = argv[1];
goto check_arg;
case 'o':
object_directory = argv[1];
goto check_arg;
case 'c':
config_directory = argv[1];
check_arg:
if (argv[1] == (char *) 0) {
goto usage_error;
}
argv++; argc--;
break;
case 'p':
profiling++;
break;
default:
goto usage_error;
}
}
}
if (config_directory == (char *) 0) {
config_directory =
malloc((unsigned) strlen(source_directory) + 6);
(void) sprintf(config_directory, "%s/conf", source_directory);
}
if (argc != 2) {
usage_error: ;
fprintf(stderr, "usage: config [ -bcdo dir ] [ -p ] sysname\n");
exit(1);
}
if (!build_directory) {
build_directory = argv[1];
}
if (freopen(argv[1], "r", stdin) == NULL) {
perror(argv[1]);
exit(2);
}
dtab = NULL;
confp = &conf_list;
opt = 0;
if (yyparse()) {
exit(3);
}
mkioconf(); /* ioconf.c */
makefile(); /* build Makefile */
headers(); /* make a lot of .h files */
return 0;
}
/*
* get_word
* returns EOF on end of file
* NULL on end of line
* pointer to the word otherwise
*/
const char *
get_word(FILE *fp)
{
static char line[80];
int ch;
char *cp;
while ((ch = getc(fp)) != EOF) {
if (ch != ' ' && ch != '\t') {
break;
}
}
if (ch == EOF) {
return (char *)EOF;
}
if (ch == '\n') {
return NULL;
}
if (ch == '|') {
return "|";
}
cp = line;
*cp++ = ch;
while ((ch = getc(fp)) != EOF) {
if (isspace(ch)) {
break;
}
*cp++ = ch;
}
*cp = 0;
if (ch == EOF) {
return (char *)EOF;
}
(void) ungetc(ch, fp);
return line;
}
/*
* get_rest
* returns EOF on end of file
* NULL on end of line
* pointer to the word otherwise
*/
char *
get_rest(FILE *fp)
{
static char line[80];
int ch;
char *cp;
cp = line;
while ((ch = getc(fp)) != EOF) {
if (ch == '\n') {
break;
}
*cp++ = ch;
}
*cp = 0;
if (ch == EOF) {
return (char *)EOF;
}
return line;
}
/*
* prepend the path to a filename
*/
char *
path(const char *file)
{
char *cp;
cp = malloc((unsigned)(strlen(build_directory) +
strlen(file) +
strlen(object_directory) +
3));
(void) sprintf(cp, "%s/%s/%s", object_directory, build_directory, file);
return cp;
}

232
SETUP/config/mkheaders.c Normal file
View File

@ -0,0 +1,232 @@
/*
* Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License."
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Mach Operating System
* Copyright (c) 1990 Carnegie-Mellon University
* Copyright (c) 1989 Carnegie-Mellon University
* Copyright (c) 1988 Carnegie-Mellon University
* Copyright (c) 1987 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static char sccsid[] __attribute__((used)) = "@(#)mkheaders.c 5.5 (Berkeley) 6/18/88";
#endif /* not lint */
/*
* Make all the .h files for the optional entries
*/
#include <stdio.h>
#include <unistd.h> /* unlink */
#include <ctype.h>
#include "config.h"
#include "parser.h"
static void do_count(const char *dev, const char *hname, int search);
static void do_header(const char *dev, const char *hname, int count);
static char *toheader(const char *dev);
static char *tomacro(const char *dev);
void
headers(void)
{
struct file_list *fl;
for (fl = ftab; fl != 0; fl = fl->f_next) {
if (fl->f_needs != 0) {
do_count(fl->f_needs, fl->f_needs, 1);
}
}
}
/*
* count all the devices of a certain type and recurse to count
* whatever the device is connected to
*/
void
do_count(const char *dev, const char *hname, int search)
{
struct device *dp;
int count;
for (count = 0, dp = dtab; dp != 0; dp = dp->d_next) {
if (eq(dp->d_name, dev)) {
if (dp->d_type == PSEUDO_DEVICE) {
count =
dp->d_slave != UNKNOWN ? dp->d_slave : 1;
if (dp->d_flags) {
dev = NULL;
}
break;
}
}
}
do_header(dev, hname, count);
}
static void
do_header(const char *dev, const char *hname, int count)
{
char *file, *name;
const char *inw;
char *inwcopy;
struct file_list *fl = NULL; /* may exit for(;;) uninitted */
struct file_list *fl_head, *fl_prev;
FILE *inf, *outf;
int inc, oldcount;
file = toheader(hname);
name = tomacro(dev?dev:hname) + (dev == NULL);
inf = fopen(file, "r");
oldcount = -1;
if (inf == 0) {
(void) unlink(file);
outf = fopen(file, "w");
if (outf == 0) {
perror(file);
exit(1);
}
fprintf(outf, "#define %s %d\n", name, count);
(void) fclose(outf);
file = path("meta_features.h");
outf = fopen(file, "a");
if (outf == 0) {
perror(file);
exit(1);
}
fprintf(outf, "#include <%s.h>\n", hname);
(void) fclose(outf);
return;
}
fl_head = 0;
for (;;) {
const char *cp;
if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) {
break;
}
if ((inw = get_word(inf)) == 0 || inw == (char *)EOF) {
break;
}
inwcopy = ns(inw);
cp = get_word(inf);
if (cp == 0 || cp == (char *)EOF) {
break;
}
inc = atoi(cp);
if (eq(inwcopy, name)) {
oldcount = inc;
inc = count;
}
cp = get_word(inf);
if (cp == (char *)EOF) {
break;
}
fl = (struct file_list *) malloc(sizeof *fl);
fl->f_fn = inwcopy;
fl->f_type = inc;
fl->f_next = fl_head;
fl_head = fl;
}
(void) fclose(inf);
if (count == oldcount) {
while (fl != 0) {
fl_prev = fl;
fl = fl->f_next;
free((char *)fl_prev);
}
return;
}
if (oldcount == -1) {
fl = (struct file_list *) malloc(sizeof *fl);
fl->f_fn = name;
fl->f_type = count;
fl->f_next = fl_head;
fl_head = fl;
}
unlink(file);
outf = fopen(file, "w");
if (outf == 0) {
perror(file);
exit(1);
}
for (fl = fl_head; fl != 0; fl = fl->f_next) {
fprintf(outf, "#define %s %d\n",
fl->f_fn, count ? fl->f_type : 0);
free((char *)fl);
}
(void) fclose(outf);
}
/*
* convert a dev name to a .h file name
*/
static char *
toheader(const char *dev)
{
static char hbuf[MAXPATHLEN];
(void) snprintf(hbuf, sizeof hbuf, "%s.h", path(dev));
hbuf[MAXPATHLEN - 1] = '\0';
return hbuf;
}
/*
* convert a dev name to a macro name
*/
static char *
tomacro(const char *dev)
{
static char mbuf[FILENAME_MAX];
char *cp;
cp = mbuf;
*cp++ = 'N';
while (*dev) {
if (!islower(*dev)) {
*cp++ = *dev++;
} else {
*cp++ = toupper(*dev++);
}
}
*cp++ = 0;
return mbuf;
}

103
SETUP/config/mkioconf.c Normal file
View File

@ -0,0 +1,103 @@
/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License."
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Mach Operating System
* Copyright (c) 1990 Carnegie-Mellon University
* Copyright (c) 1989 Carnegie-Mellon University
* Copyright (c) 1988 Carnegie-Mellon University
* Copyright (c) 1987 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <stdio.h>
#include <unistd.h> /* for unlink */
#include "parser.h"
#include "config.h"
/*
* build the ioconf.c file
*/
void pseudo_inits(FILE *fp);
void
mkioconf(void)
{
FILE *fp;
unlink(path("ioconf.c"));
fp = fopen(path("ioconf.c"), "w");
if (fp == 0) {
perror(path("ioconf.c"));
exit(1);
}
fprintf(fp, "#include <dev/busvar.h>\n");
fprintf(fp, "\n");
pseudo_inits(fp);
(void) fclose(fp);
}
void
pseudo_inits(FILE *fp)
{
struct device *dp;
int count;
fprintf(fp, "\n");
for (dp = dtab; dp != 0; dp = dp->d_next) {
if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) {
continue;
}
fprintf(fp, "extern int %s(int);\n", dp->d_init);
}
fprintf(fp, "\nstruct pseudo_init pseudo_inits[] = {\n");
for (dp = dtab; dp != 0; dp = dp->d_next) {
if (dp->d_type != PSEUDO_DEVICE || dp->d_init == 0) {
continue;
}
count = dp->d_slave;
if (count <= 0) {
count = 1;
}
fprintf(fp, "\t{%d,\t%s},\n", count, dp->d_init);
}
fprintf(fp, "\t{0,\t0},\n};\n");
}

821
SETUP/config/mkmakefile.c Normal file
View File

@ -0,0 +1,821 @@
/*
* Copyright (c) 1999-2016 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License."
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* Mach Operating System
* Copyright (c) 1990 Carnegie-Mellon University
* Copyright (c) 1989 Carnegie-Mellon University
* Copyright (c) 1988 Carnegie-Mellon University
* Copyright (c) 1987 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static char sccsid[] __attribute__((used)) = "@(#)mkmakefile.c 5.21 (Berkeley) 6/18/88";
#endif /* not lint */
/*
* Build the makefile for the system, from
* the information in the files files and the
* additional files for the machine being compiled to.
*/
#include <stdio.h>
#include <unistd.h> /* for unlink */
#include <ctype.h>
#include "parser.h"
#include "config.h"
void read_files(void);
void do_objs(FILE *fp, const char *msg, int ext, int flags);
void do_files(FILE *fp, const char *msg, char ext);
void do_machdep(FILE *ofp);
void do_rules(FILE *f);
void copy_dependencies(FILE *makin, FILE *makout);
struct file_list *fl_lookup(char *file);
struct file_list *fltail_lookup(char *file);
struct file_list *new_fent(void);
void put_source_file_name(FILE *fp, struct file_list *tp);
#define next_word(fp, wd) \
{ const char *word = get_word(fp); \
if (word == (char *)EOF) \
return; \
else \
wd = word; \
}
static struct file_list *fcur;
const char *tail(const char *fn);
char *allCaps(char *str);
/*
* Lookup a file, by name.
*/
struct file_list *
fl_lookup(char *file)
{
struct file_list *fp;
for (fp = ftab; fp != 0; fp = fp->f_next) {
if (eq(fp->f_fn, file)) {
return fp;
}
}
return 0;
}
/*
* Lookup a file, by final component name.
*/
struct file_list *
fltail_lookup(char *file)
{
struct file_list *fp;
for (fp = ftab; fp != 0; fp = fp->f_next) {
if (eq(tail(fp->f_fn), tail(file))) {
return fp;
}
}
return 0;
}
/*
* Make a new file list entry
*/
struct file_list *
new_fent(void)
{
struct file_list *fp;
fp = (struct file_list *) malloc(sizeof *fp);
fp->f_needs = 0;
fp->f_next = 0;
fp->f_flags = 0;
fp->f_type = 0;
fp->f_extra = (char *) 0;
if (fcur == 0) {
fcur = ftab = fp;
} else {
fcur->f_next = fp;
}
fcur = fp;
return fp;
}
char *COPTS;
const char *
get_VPATH(void)
{
static char *vpath = NULL;
if ((vpath == NULL) &&
((vpath = getenv("VPATH")) != NULL) &&
(*vpath != ':')) {
char *buf = malloc((unsigned)(strlen(vpath) + 2));
vpath = strcat(strcpy(buf, ":"), vpath);
}
return vpath ? vpath : "";
}
/*
* Build the makefile from the skeleton
*/
void
makefile(void)
{
FILE *ifp, *ofp;
FILE *dfp;
char pname[BUFSIZ];
char line[BUFSIZ];
struct opt *op;
read_files();
(void) sprintf(line, "%s/Makefile.template", config_directory);
ifp = fopenp(VPATH, line, pname, "r");
if (ifp == 0) {
perror(line);
exit(1);
}
dfp = fopen(path("Makefile"), "r");
rename(path("Makefile"), path("Makefile.old"));
unlink(path("Makefile.old"));
ofp = fopen(path("Makefile"), "w");
if (ofp == 0) {
perror(path("Makefile"));
exit(1);
}
fprintf(ofp, "SOURCE_DIR=%s\n", source_directory);
fprintf(ofp, "export CONFIG_DEFINES =");
if (profiling) {
fprintf(ofp, " -DGPROF");
}
for (op = opt; op; op = op->op_next) {
if (op->op_value) {
fprintf(ofp, " -D%s=\"%s\"", op->op_name, op->op_value);
} else {
fprintf(ofp, " -D%s", op->op_name);
}
}
fprintf(ofp, "\n");
for (op = mkopt; op; op = op->op_next) {
if (op->op_value) {
fprintf(ofp, "%s=%s\n", op->op_name, op->op_value);
} else {
fprintf(ofp, "%s\n", op->op_name);
}
}
while (fgets(line, BUFSIZ, ifp) != 0) {
if (*line == '%') {
goto percent;
}
if (profiling && strncmp(line, "COPTS=", 6) == 0) {
char *cp;
fprintf(ofp,
"GPROF.EX=$(SOURCE_DIR)/machdep/%s/gmon.ex\n", machinename);
cp = index(line, '\n');
if (cp) {
*cp = 0;
}
cp = line + 6;
while (*cp && (*cp == ' ' || *cp == '\t')) {
cp++;
}
COPTS = malloc((unsigned)(strlen(cp) + 1));
if (COPTS == 0) {
printf("config: out of memory\n");
exit(1);
}
strcpy(COPTS, cp);
fprintf(ofp, "%s -pg\n", line);
continue;
}
fprintf(ofp, "%s", line);
continue;
percent:
if (eq(line, "%OBJS\n")) {
do_objs(ofp, "OBJS=", -1, 0);
} else if (eq(line, "%LIBOBJS\n")) {
do_objs(ofp, "LIBOBJS=", -1, LIBRARYDEP);
} else if (eq(line, "%CFILES\n")) {
do_files(ofp, "CFILES=", 'c');
do_objs(ofp, "COBJS=", 'c', 0);
} else if (eq(line, "%CXXFILES\n")) {
do_files(ofp, "CXXFILES=", 'p');
do_objs(ofp, "CXXOBJS=", 'p', 0);
} else if (eq(line, "%SFILES\n")) {
do_files(ofp, "SFILES=", 's');
do_objs(ofp, "SOBJS=", 's', 0);
} else if (eq(line, "%MACHDEP\n")) {
do_machdep(ofp);
} else if (eq(line, "%RULES\n")) {
do_rules(ofp);
} else {
fprintf(stderr,
"Unknown %% construct in generic makefile: %s",
line);
}
}
if (dfp != NULL) {
copy_dependencies(dfp, ofp);
(void) fclose(dfp);
}
(void) fclose(ifp);
(void) fclose(ofp);
}
/*
* Read in the information about files used in making the system.
* Store it in the ftab linked list.
*/
void
read_files(void)
{
FILE *fp;
struct file_list *tp, *pf;
struct device *dp;
struct opt *op;
const char *wd;
char *this, *needs;
const char *devorprof;
int options;
int not_option;
int for_xnu_lib;
char pname[BUFSIZ];
char fname[1024];
char *rest = (char *) 0;
int nreqs, first = 1, isdup;
ftab = 0;
(void) sprintf(fname, "%s/files", config_directory);
openit:
fp = fopenp(VPATH, fname, pname, "r");
if (fp == 0) {
perror(fname);
exit(1);
}
next:
options = 0;
rest = (char *) 0;
/*
* filename [ standard | optional ]
* [ dev* | profiling-routine ] [ device-driver]
*/
wd = get_word(fp);
if (wd == (char *)EOF) {
(void) fclose(fp);
if (first == 1) {
(void) sprintf(fname, "%s/files.%s", config_directory, machinename);
first++;
goto openit;
}
return;
}
if (wd == 0) {
goto next;
}
/*
* Allow comment lines beginning witha '#' character.
*/
if (*wd == '#') {
while ((wd = get_word(fp)) && wd != (char *)EOF) {
;
}
goto next;
}
this = ns(wd);
next_word(fp, wd);
if (wd == 0) {
printf("%s: No type for %s.\n",
fname, this);
exit(1);
}
if ((pf = fl_lookup(this)) && (pf->f_type != INVISIBLE || pf->f_flags)) {
isdup = 1;
} else {
isdup = 0;
}
tp = 0;
nreqs = 0;
devorprof = "";
needs = 0;
for_xnu_lib = 0;
if (eq(wd, "standard")) {
goto checkdev;
}
if (!eq(wd, "optional")) {
printf("%s: %s must be optional or standard\n", fname, this);
exit(1);
}
if (strncmp(this, "OPTIONS/", 8) == 0) {
options++;
}
not_option = 0;
nextopt:
next_word(fp, wd);
if (wd == 0) {
goto doneopt;
}
if (eq(wd, "not")) {
not_option = !not_option;
goto nextopt;
}
devorprof = wd;
if (eq(wd, "device-driver") || eq(wd, "profiling-routine")) {
next_word(fp, wd);
goto save;
}
if (eq(wd, "xnu-library")) {
for_xnu_lib = 1;
goto nextopt;
}
nreqs++;
if (needs == 0 && nreqs == 1) {
needs = ns(wd);
}
if (isdup) {
goto invis;
}
if (options) {
struct opt *lop = 0;
struct device tdev;
/*
* Allocate a pseudo-device entry which we will insert into
* the device list below. The flags field is set non-zero to
* indicate an internal entry rather than one generated from
* the configuration file. The slave field is set to define
* the corresponding symbol as 0 should we fail to find the
* option in the option list.
*/
init_dev(&tdev);
tdev.d_name = ns(wd);
tdev.d_type = PSEUDO_DEVICE;
tdev.d_flags++;
tdev.d_slave = 0;
for (op = opt; op; lop = op, op = op->op_next) {
char *od = allCaps(ns(wd));
/*
* Found an option which matches the current device
* dependency identifier. Set the slave field to
* define the option in the header file.
*/
if (strcmp(op->op_name, od) == 0) {
tdev.d_slave = 1;
if (lop == 0) {
opt = op->op_next;
} else {
lop->op_next = op->op_next;
}
free(op);
op = 0;
}
free(od);
if (op == 0) {
break;
}
}
newdev(&tdev);
}
for (dp = dtab; dp != 0; dp = dp->d_next) {
if (eq(dp->d_name, wd) && (dp->d_type != PSEUDO_DEVICE || dp->d_slave)) {
if (not_option) {
goto invis; /* dont want file if option present */
} else {
goto nextopt;
}
}
}
if (not_option) {
goto nextopt; /* want file if option missing */
}
for (op = opt; op != 0; op = op->op_next) {
if (op->op_value == 0 && opteq(op->op_name, wd)) {
if (nreqs == 1) {
free(needs);
needs = 0;
}
goto nextopt;
}
}
invis:
while ((wd = get_word(fp)) != 0) {
;
}
if (tp == 0) {
tp = new_fent();
}
tp->f_fn = this;
tp->f_type = INVISIBLE;
tp->f_needs = needs;
tp->f_flags = isdup;
goto next;
doneopt:
if (nreqs == 0) {
printf("%s: what is %s optional on?\n",
fname, this);
exit(1);
}
checkdev:
if (wd) {
if (*wd == '|') {
goto getrest;
}
next_word(fp, wd);
if (wd && eq(wd, "xnu-library")) {
for_xnu_lib = 1;
next_word(fp, wd);
}
if (wd) {
devorprof = wd;
next_word(fp, wd);
}
}
save:
getrest:
if (wd) {
if (*wd == '|') {
rest = ns(get_rest(fp));
} else {
printf("%s: syntax error describing %s\n",
fname, this);
exit(1);
}
}
if (eq(devorprof, "profiling-routine") && profiling == 0) {
goto next;
}
if (tp == 0) {
tp = new_fent();
}
tp->f_fn = this;
tp->f_extra = rest;
if (options) {
tp->f_type = INVISIBLE;
} else if (eq(devorprof, "device-driver")) {
tp->f_type = DRIVER;
} else if (eq(devorprof, "profiling-routine")) {
tp->f_type = PROFILING;
} else {
tp->f_type = NORMAL;
}
tp->f_flags = 0;
tp->f_needs = needs;
if (pf && pf->f_type == INVISIBLE) {
pf->f_flags = 1; /* mark as duplicate */
}
if (for_xnu_lib) {
tp->f_flags |= LIBRARYDEP;
}
goto next;
}
int
opteq(const char *cp, const char *dp)
{
char c, d;
for (;; cp++, dp++) {
if (*cp != *dp) {
c = isupper(*cp) ? tolower(*cp) : *cp;
d = isupper(*dp) ? tolower(*dp) : *dp;
if (c != d) {
return 0;
}
}
if (*cp == 0) {
return 1;
}
}
}
void
put_source_file_name(FILE *fp, struct file_list *tp)
{
if ((tp->f_fn[0] == '.') && (tp->f_fn[1] == '/')) {
fprintf(fp, "%s ", tp->f_fn);
} else {
fprintf(fp, "$(SOURCE_DIR)/%s ", tp->f_fn);
}
}
void
do_objs(FILE *fp, const char *msg, int ext, int flags)
{
struct file_list *tp;
int lpos, len;
char *cp;
char och;
const char *sp;
fprintf(fp, "%s", msg);
lpos = strlen(msg);
for (tp = ftab; tp != 0; tp = tp->f_next) {
if (tp->f_type == INVISIBLE) {
continue;
}
/*
* Check flags (if any)
*/
if (flags && ((tp->f_flags & flags) != flags)) {
continue;
}
/*
* Check for '.o' file in list
*/
cp = tp->f_fn + (len = strlen(tp->f_fn)) - 1;
if (ext != -1 && *cp != ext) {
continue;
} else if (*cp == 'o') {
if (len + lpos > 72) {
lpos = 8;
fprintf(fp, "\\\n\t");
}
put_source_file_name(fp, tp);
fprintf(fp, " ");
lpos += len + 1;
continue;
}
sp = tail(tp->f_fn);
cp = (char *)sp + (len = strlen(sp)) - 1;
och = *cp;
*cp = 'o';
if (len + lpos > 72) {
lpos = 8;
fprintf(fp, "\\\n\t");
}
fprintf(fp, "%s ", sp);
lpos += len + 1;
*cp = och;
}
putc('\n', fp);
}
void
do_files(FILE *fp, const char *msg, char ext)
{
struct file_list *tp;
int lpos, len = 0; /* dvw: init to 0 */
fprintf(fp, "%s", msg);
lpos = 8;
for (tp = ftab; tp != 0; tp = tp->f_next) {
if (tp->f_type == INVISIBLE) {
continue;
}
if (tp->f_fn[strlen(tp->f_fn) - 1] != ext) {
continue;
}
/*
* Always generate a newline.
* Our Makefile's aren't readable anyway.
*/
lpos = 8;
fprintf(fp, "\\\n\t");
put_source_file_name(fp, tp);
lpos += len + 1;
}
putc('\n', fp);
}
/*
* Include machine dependent makefile in output
*/
void
do_machdep(FILE *ofp)
{
FILE *ifp;
char pname[BUFSIZ];
char line[BUFSIZ];
(void) sprintf(line, "%s/Makefile.%s", config_directory, machinename);
ifp = fopenp(VPATH, line, pname, "r");
if (ifp == 0) {
perror(line);
exit(1);
}
while (fgets(line, BUFSIZ, ifp) != 0) {
if (profiling && (strncmp(line, "LIBS=", 5) == 0)) {
fprintf(ofp, "LIBS=${LIBS_P}\n");
} else {
fputs(line, ofp);
}
}
fclose(ifp);
}
const char *
tail(const char *fn)
{
const char *cp;
cp = rindex(fn, '/');
if (cp == 0) {
return fn;
}
return cp + 1;
}
/*
* Create the makerules for each file
* which is part of the system.
* Devices are processed with the special c2 option -i
* which avoids any problem areas with i/o addressing
* (e.g. for the VAX); assembler files are processed by as.
*/
void
do_rules(FILE *f)
{
char *cp;
char *np, och;
const char *tp;
struct file_list *ftp;
const char *extras = ""; /* dvw: init to "" */
char *source_dir;
char och_upper;
const char *nl = "";
for (ftp = ftab; ftp != 0; ftp = ftp->f_next) {
if (ftp->f_type == INVISIBLE) {
continue;
}
cp = (np = ftp->f_fn) + strlen(ftp->f_fn) - 1;
och = *cp;
/*
* Don't compile '.o' files
*/
if (och == 'o') {
continue;
}
/*
* Determine where sources should come from
*/
if ((np[0] == '.') && (np[1] == '/')) {
source_dir = "";
np += 2;
} else {
source_dir = "$(SOURCE_DIR)/";
}
*cp = '\0';
tp = tail(np); /* dvw: init tp before 'if' */
fprintf(f, "-include %sd\n", tp);
fprintf(f, "%so: %s%s%c\n", tp, source_dir, np, och);
if (och == 's') {
fprintf(f, "\t${S_RULE_0}\n");
fprintf(f, "\t${S_RULE_1A}%s%.*s${S_RULE_1B}%s\n",
source_dir, (int)(tp - np), np, nl);
fprintf(f, "\t${S_RULE_2}%s\n", nl);
continue;
}
extras = "";
switch (ftp->f_type) {
case NORMAL:
goto common;
break;
case DRIVER:
extras = "_D";
goto common;
break;
case PROFILING:
if (!profiling) {
continue;
}
if (COPTS == 0) {
fprintf(stderr,
"config: COPTS undefined in generic makefile");
COPTS = "";
}
extras = "_P";
goto common;
common:
och_upper = och + 'A' - 'a';
fprintf(f, "\t${%c_RULE_0%s}\n", och_upper, extras);
fprintf(f, "\t${%c_RULE_1A%s}", och_upper, extras);
if (ftp->f_extra) {
fprintf(f, "%s", ftp->f_extra);
}
fprintf(f, "%s%.*s${%c_RULE_1B%s}%s\n",
source_dir, (int)(tp - np), np, och_upper, extras, nl);
fprintf(f, "\t${%c_RULE_2%s}%s\n", och_upper, extras, nl);
fprintf(f, "\t${%c_RULE_3%s}%s\n", och_upper, extras, nl);
fprintf(f, "\t$(if ${%c_RULE_4A%s},${%c_RULE_4A%s}",
och_upper, extras, och_upper, extras);
if (ftp->f_extra) {
fprintf(f, "%s", ftp->f_extra);
}
fprintf(f, "%s%.*s${%c_RULE_4B%s}%s)\n",
source_dir, (int)(tp - np), np, och_upper, extras, nl);
break;
default:
printf("Don't know rules for %s\n", np);
break;
}
*cp = och;
}
}
char *
allCaps(char *str)
{
char *cp = str;
while (*str) {
if (islower(*str)) {
*str = toupper(*str);
}
str++;
}
return cp;
}
#define OLDSALUTATION "# DO NOT DELETE THIS LINE"
#define LINESIZE 1024
static char makbuf[LINESIZE]; /* one line buffer for makefile */
void
copy_dependencies(FILE *makin, FILE *makout)
{
int oldlen = (sizeof OLDSALUTATION - 1);
while (fgets(makbuf, LINESIZE, makin) != NULL) {
if (!strncmp(makbuf, OLDSALUTATION, oldlen)) {
break;
}
}
while (fgets(makbuf, LINESIZE, makin) != NULL) {
if (oldlen != 0) {
if (makbuf[0] == '\n') {
continue;
} else {
oldlen = 0;
}
}
fputs(makbuf, makout);
}
}

97
SETUP/config/openp.c Normal file
View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License."
*
* @APPLE_LICENSE_HEADER_END@
*/
/* openp, fopenp -- search pathlist and open file
*
* Usage:
* i = openp (path,file,complete,flags,mode)
* f = fopenp (path,file,complete,type)
* int i,flags,mode;
* FILE *f;
* char *path,*file,*complete,*type;
*
* Openp searches for "file" in the pathlist "path";
* when the file is found and can be opened by open()
* with the specified "flags" and "mode", then the full filename
* is copied into "complete" and openp returns the file
* descriptor. If no such file is found, openp returns -1.
* Fopenp performs the same function, using fopen() instead
* of open() and type instead of flags/mode; it returns 0 if no
* file is found.
*
* HISTORY
* 30-Apr-85 Steven Shafer (sas) at Carnegie-Mellon University
* Adapted for 4.2 BSD UNIX. Added new parameter to openp.c;
* changed names of flags, mode, and type parameters to reflect
* current manual entries for open and fopen.
*
* 20-Nov-79 Steven Shafer (sas) at Carnegie-Mellon University
* Created for VAX.
*
*/
#include <stdio.h>
#include <fcntl.h> /* open */
#include "config.h"
int openp(const char *fpath, char *file, char *complete, int flags, int mode);
static int flgs, mod, value;
static const char *ftyp;
static FILE *fvalue;
static int
func(char *fnam)
{
value = open(fnam, flgs, mod);
return value < 0;
}
static int
ffunc(char *fnam)
{
fvalue = fopen(fnam, ftyp);
return fvalue == 0;
}
int
openp(const char *fpath, char *file, char *complete, int flags, int mode)
{
flgs = flags;
mod = mode;
if (searchp(fpath, file, complete, func) < 0) {
return -1;
}
return value;
}
FILE *
fopenp(const char *fpath, char *file, char *complete, const char *ftype)
{
ftyp = ftype;
if (searchp(fpath, file, complete, ffunc) < 0) {
return 0;
}
return fvalue;
}

292
SETUP/config/parser.y Normal file
View File

@ -0,0 +1,292 @@
/*
* Mach Operating System
* Copyright (c) 1990 Carnegie-Mellon University
* Copyright (c) 1989 Carnegie-Mellon University
* Copyright (c) 1988 Carnegie-Mellon University
* Copyright (c) 1987 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* Copyright (c) 1988 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#)config.y 5.8 (Berkeley) 6/18/88
*/
%union {
char *str;
int val;
struct file_list *file;
struct idlst *lst;
}
%token BUILDDIR
%token COMMA
%token EQUALS
%token INIT
%token MACHINE
%token OBJECTDIR
%token OPTIONS
%token MAKEOPTIONS
%token PSEUDO_DEVICE
%token SEMICOLON
%token SOURCEDIR
%token TRACE
%token <str> ID
%token <val> NUMBER
%type <str> Save_id
%type <str> Opt_value
%type <str> Dev
%{
#include "config.h"
#include <ctype.h>
#include <stdio.h>
struct device cur;
struct device *curp = 0;
char *temp_id;
char *val_id;
/* char *malloc(); */
int yylex(void);
void deverror(const char *systemname, const char *devtype);
%}
%%
Configuration:
Many_specs
;
Many_specs:
Many_specs Spec
|
/* lambda */
;
Spec:
Device_spec SEMICOLON
{ newdev(&cur); } |
Config_spec SEMICOLON
|
TRACE SEMICOLON
{ do_trace = !do_trace; } |
SEMICOLON
|
error SEMICOLON
;
Config_spec:
MACHINE Save_id
{ machinename = ns($2); }
|
OPTIONS Opt_list
|
MAKEOPTIONS Mkopt_list
|
BUILDDIR Save_id
{ build_directory = ns($2); }
|
OBJECTDIR Save_id
{ object_directory = ns($2); }
|
SOURCEDIR Save_id
{ source_directory = ns($2); }
;
Opt_list:
Opt_list COMMA Option
|
Option
;
Option:
Save_id
{
struct opt *op = (struct opt *)malloc(sizeof (struct opt));
op->op_name = ns($1);
op->op_next = (struct opt *) 0;
op->op_value = 0;
if (opt == (struct opt *) 0)
opt = op;
else
opt_tail->op_next = op;
opt_tail = op;
free(temp_id);
} |
Save_id EQUALS Opt_value
{
struct opt *op = (struct opt *)malloc(sizeof (struct opt));
op->op_name = ns($1);
op->op_next = (struct opt *) 0;
op->op_value = ns($3);
if (opt == (struct opt *) 0)
opt = op;
else
opt_tail->op_next = op;
opt_tail = op;
free(temp_id);
if (val_id)
free(val_id);
} ;
Opt_value:
ID
{ $$ = val_id = ns($1); } |
NUMBER
{ char nb[16];
(void) sprintf(nb, "%u", $1);
$$ = val_id = ns(nb);
} |
/* lambda from MIPS -- WHY */
{ $$ = val_id = ns(""); }
;
Save_id:
ID
{ $$ = temp_id = ns($1); }
;
Mkopt_list:
Mkopt_list COMMA Mkoption
|
Mkoption
;
Mkoption:
Save_id
{
struct opt *op = (struct opt *)malloc(sizeof (struct opt));
op->op_name = ns($1);
op->op_next = (struct opt *) 0;
op->op_value = 0;
mkopt = op;
free(temp_id);
} |
Save_id EQUALS Opt_value
{
struct opt *op = (struct opt *)malloc(sizeof (struct opt));
op->op_name = ns($1);
op->op_next = (struct opt *) 0;
op->op_value = ns($3);
if (mkopt == (struct opt *) 0)
mkopt = op;
else
mkopt_tail->op_next = op;
mkopt_tail = op;
free(temp_id);
if (val_id)
free(val_id);
} ;
Dev:
ID
{ $$ = ns($1); }
;
Device_spec:
PSEUDO_DEVICE Init_dev Dev
{
cur.d_name = $3;
cur.d_type = PSEUDO_DEVICE;
} |
PSEUDO_DEVICE Init_dev Dev NUMBER
{
cur.d_name = $3;
cur.d_type = PSEUDO_DEVICE;
cur.d_slave = $4;
} |
PSEUDO_DEVICE Init_dev Dev INIT ID
{
cur.d_name = $3;
cur.d_type = PSEUDO_DEVICE;
cur.d_init = ns($5);
} |
PSEUDO_DEVICE Init_dev Dev NUMBER INIT ID
{
cur.d_name = $3;
cur.d_type = PSEUDO_DEVICE;
cur.d_slave = $4;
cur.d_init = ns($6);
};
Init_dev:
/* lambda */
{ init_dev(&cur); };
%%
void
yyerror(const char *s)
{
fprintf(stderr, "config: line %d: %s\n", yyline, s);
}
/*
* return the passed string in a new space
*/
char *
ns(const char *str)
{
register char *cp;
cp = malloc((unsigned)(strlen(str)+1));
(void) strcpy(cp, str);
return (cp);
}
/*
* add a device to the list of devices
*/
void
newdev(struct device *dp)
{
register struct device *np;
np = (struct device *) malloc(sizeof *np);
*np = *dp;
if (curp == 0)
dtab = np;
else
curp->d_next = np;
curp = np;
curp->d_next = 0;
}
void
init_dev(struct device *dp)
{
dp->d_name = "OHNO!!!";
dp->d_type = PSEUDO_DEVICE;
dp->d_flags = 0;
dp->d_slave = UNKNOWN;
dp->d_init = 0;
}
void
deverror(const char *systemname, const char *devtype)
{
fprintf(stderr, "config: %s: %s device not configured\n",
systemname, devtype);
}

94
SETUP/config/searchp.c Normal file
View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License."
*
* @APPLE_LICENSE_HEADER_END@
*/
/* searchp -- search through pathlist for file
*
* Usage: p = searchp (path,file,fullname,func);
* char *p, *path, *file, *fullname;
* int (*func)();
*
* Searchp will parse "path", a list of pathnames separated
* by colons, prepending each pathname to "file". The resulting
* filename will be passed to "func", a function provided by the
* user. This function must return zero if the search is
* successful (i.e. ended), and non-zero if the search must
* continue. If the function returns zero (success), then
* searching stops, the full filename is placed into "fullname",
* and searchp returns 0. If the pathnames are all unsuccessfully
* examined, then searchp returns -1.
* If "file" begins with a slash, it is assumed to be an
* absolute pathname and the "path" list is not used. Note
* that this rule is used by Bell's cc also; whereas Bell's
* sh uses the rule that any filename which CONTAINS a slash
* is assumed to be absolute. The execlp and execvp procedures
* also use this latter rule. In my opinion, this is bogosity.
*
* HISTORY
* 01-Apr-86 Rudy Nedved (ern) at Carnegie-Mellon University
* 4.1BSD system ignores trailing slashes. 4.2BSD does not.
* Therefore don't add a seperating slash if there is a null
* filename.
*
* 23-Oct-82 Steven Shafer (sas) at Carnegie-Mellon University
* Fixed two bugs: (1) calling function as "func" instead of
* "(*func)", (2) omitting trailing null name implied by trailing
* colon in path. Latter bug fixed by introducing "lastchar" and
* changing final loop test to look for "*lastchar" instead of
* "*nextpath".
*
* 20-Nov-79 Steven Shafer (sas) at Carnegie-Mellon University
* Created for VAX. If you're thinking of using this, you probably
* should look at openp() and fopenp() (or the "want..." routines)
* instead.
*
*/
#include "config.h"
int
searchp(const char *spath, char *file, char *fullname, int (*func)(char *))
{
const char *nextpath, *nextchar, *lastchar;
char *fname;
int failure;
nextpath = ((*file == '/') ? "" : spath);
do {
fname = fullname;
nextchar = nextpath;
while (*nextchar && (*nextchar != ':')) {
*fname++ = *nextchar++;
}
if (nextchar != nextpath && *file) {
*fname++ = '/';
}
lastchar = nextchar;
nextpath = ((*nextchar) ? nextchar + 1 : nextchar);
nextchar = file; /* append file */
while (*nextchar) {
*fname++ = *nextchar++;
}
*fname = '\0';
failure = (*func)(fullname);
}while (failure && (*lastchar));
return failure ? -1 : 0;
}

30
SETUP/decomment/Makefile Normal file
View File

@ -0,0 +1,30 @@
export MakeInc_cmd=${SRCROOT}/makedefs/MakeInc.cmd
export MakeInc_def=${SRCROOT}/makedefs/MakeInc.def
export MakeInc_rule=${SRCROOT}/makedefs/MakeInc.rule
export MakeInc_dir=${SRCROOT}/makedefs/MakeInc.dir
include $(MakeInc_cmd)
include $(MakeInc_def)
OBJS = decomment.o
CFLAGS = -isysroot $(HOST_SDKROOT) -mmacosx-version-min=$(HOST_OS_VERSION) -g -O0 -I$(SOURCE) -I.
WARNFLAGS = -Wall
LDFLAGS = -isysroot $(HOST_SDKROOT) -mmacosx-version-min=$(HOST_OS_VERSION)
decomment: $(OBJS)
@$(LOG_HOST_LD) "$@"
$(_v)$(HOST_CC) $(LDFLAGS) -o $@ $^
@$(LOG_HOST_CODESIGN) "$@"
$(_v)env CODESIGN_ALLOCATE=$(HOST_CODESIGN_ALLOCATE) $(HOST_CODESIGN) -s - $@
%.o: %.c
@$(LOG_HOST_CC) "$@"
$(_v)$(HOST_CC) $(WARNFLAGS) $(CFLAGS) -c -o $@ $<
do_build_setup:: decomment
include $(MakeInc_rule)
include $(MakeInc_dir)

190
SETUP/decomment/decomment.c Normal file
View File

@ -0,0 +1,190 @@
/*
* Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
* Source License Version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License."
*
* @APPLE_LICENSE_HEADER_END@
*/
/*
* decomment.c
*
* Removes all comments and (optionally) whitespace from an input file.
* Writes result on stdout.
*/
#include <stdio.h>
#include <ctype.h> /* for isspace */
#include <libc.h>
/*
* State of input scanner.
*/
typedef enum {
IS_NORMAL,
IS_SLASH, // encountered opening '/'
IS_IN_COMMENT, // within / * * / comment
IS_STAR, // encountered closing '*'
IS_IN_END_COMMENT // within / / comment
} input_state_t;
static void usage(char **argv);
int
main(int argc, char **argv)
{
FILE *fp;
char bufchar;
input_state_t input_state = IS_NORMAL;
int exit_code = 0;
int remove_whitespace = 0;
int arg;
if (argc < 2) {
usage(argv);
}
for (arg = 2; arg < argc; arg++) {
switch (argv[arg][0]) {
case 'r':
remove_whitespace++;
break;
default:
usage(argv);
}
}
fp = fopen(argv[1], "r");
if (!fp) {
fprintf(stderr, "Error opening %s\n", argv[1]);
perror("fopen");
exit(1);
}
for (;;) {
bufchar = getc_unlocked(fp);
if (bufchar == EOF) {
break;
}
switch (input_state) {
case IS_NORMAL:
if (bufchar == '/') {
/*
* Might be start of a comment.
*/
input_state = IS_SLASH;
} else {
if (!(remove_whitespace && isspace(bufchar))) {
putchar_unlocked(bufchar);
}
}
break;
case IS_SLASH:
switch (bufchar) {
case '*':
/*
* Start of normal comment.
*/
input_state = IS_IN_COMMENT;
break;
case '/':
/*
* Start of 'to-end-of-line' comment.
*/
input_state = IS_IN_END_COMMENT;
break;
default:
/*
* Not the start of comment. Emit the '/'
* we skipped last char in case we were
* entering a comment this time, then the
* current char.
*/
putchar_unlocked('/');
if (!(remove_whitespace && isspace(bufchar))) {
putchar_unlocked(bufchar);
}
input_state = IS_NORMAL;
break;
}
break;
case IS_IN_COMMENT:
if (bufchar == '*') {
/*
* Maybe ending comment...
*/
input_state = IS_STAR;
}
break;
case IS_STAR:
switch (bufchar) {
case '/':
/*
* End of normal comment.
*/
input_state = IS_NORMAL;
break;
case '*':
/*
* Still could be one char away from end
* of comment.
*/
break;
default:
/*
* Still inside comment, no end in sight.
*/
input_state = IS_IN_COMMENT;
break;
}
break;
case IS_IN_END_COMMENT:
if (bufchar == '\n') {
/*
* End of comment. Emit the newline if
* appropriate.
*/
if (!remove_whitespace) {
putchar_unlocked(bufchar);
}
input_state = IS_NORMAL;
}
break;
} /* switch input_state */
} /* main read loop */
/*
* Done.
*/
return exit_code;
}
static void
usage(char **argv)
{
printf("usage: %s infile [r(emove whitespace)]\n", argv[0]);
exit(1);
}

View File

@ -0,0 +1,30 @@
export MakeInc_cmd=${SRCROOT}/makedefs/MakeInc.cmd
export MakeInc_def=${SRCROOT}/makedefs/MakeInc.def
export MakeInc_rule=${SRCROOT}/makedefs/MakeInc.rule
export MakeInc_dir=${SRCROOT}/makedefs/MakeInc.dir
include $(MakeInc_cmd)
include $(MakeInc_def)
OBJS = installfile.o
CFLAGS = -isysroot $(HOST_SDKROOT) -mmacosx-version-min=$(HOST_OS_VERSION) -g -O0 -I$(SOURCE) -I.
WARNFLAGS = -Wall
LDFLAGS = -isysroot $(HOST_SDKROOT) -mmacosx-version-min=$(HOST_OS_VERSION)
installfile: $(OBJS)
@$(LOG_HOST_LD) "$@"
$(_v)$(HOST_CC) $(LDFLAGS) -o $@ $^
@$(LOG_HOST_CODESIGN) "$@"
$(_v)env CODESIGN_ALLOCATE=$(HOST_CODESIGN_ALLOCATE) $(HOST_CODESIGN) -s - $@
%.o: %.c
@$(LOG_HOST_CC) "$@"
$(_v)$(HOST_CC) $(WARNFLAGS) $(CFLAGS) -c -o $@ $<
do_build_setup:: installfile
include $(MakeInc_rule)
include $(MakeInc_dir)

View File

@ -0,0 +1,150 @@
/*
* Copyright (c) 2012 Apple, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <errno.h>
#include <err.h>
#include <sysexits.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <sys/param.h>
#include <sys/time.h>
#include <copyfile.h>
void usage(void);
int
main(int argc, char * argv[])
{
struct stat sb;
void *mset;
mode_t mode;
bool gotmode = false;
int ch;
int ret;
int srcfd, dstfd;
const char *src = NULL;
const char *dst = NULL;
char dsttmpname[MAXPATHLEN];
while ((ch = getopt(argc, argv, "cSm:")) != -1) {
switch (ch) {
case 'c':
case 'S':
/* ignored for compatibility */
break;
case 'm':
gotmode = true;
mset = setmode(optarg);
if (!mset) {
errx(EX_USAGE, "Unrecognized mode %s", optarg);
}
mode = getmode(mset, 0);
free(mset);
break;
case '?':
default:
usage();
}
}
argc -= optind;
argv += optind;
if (argc < 2) {
usage();
}
src = argv[0];
dst = argv[1];
srcfd = open(src, O_RDONLY, 0);
if (srcfd < 0) {
err(EX_NOINPUT, "open(%s)", src);
}
ret = fstat(srcfd, &sb);
if (ret < 0) {
err(EX_NOINPUT, "fstat(%s)", src);
}
if (!S_ISREG(sb.st_mode)) {
err(EX_USAGE, "%s is not a regular file", src);
}
snprintf(dsttmpname, sizeof(dsttmpname), "%s.XXXXXX", dst);
dstfd = mkstemp(dsttmpname);
if (dstfd < 0) {
err(EX_UNAVAILABLE, "mkstemp(%s)", dsttmpname);
}
ret = fcopyfile(srcfd, dstfd, NULL,
COPYFILE_DATA);
if (ret < 0) {
err(EX_UNAVAILABLE, "fcopyfile(%s, %s)", src, dsttmpname);
}
ret = futimes(dstfd, NULL);
if (ret < 0) {
err(EX_UNAVAILABLE, "futimes(%s)", dsttmpname);
}
if (gotmode) {
ret = fchmod(dstfd, mode);
if (ret < 0) {
err(EX_NOINPUT, "fchmod(%s, %ho)", dsttmpname, mode);
}
}
ret = rename(dsttmpname, dst);
if (ret < 0) {
err(EX_NOINPUT, "rename(%s, %s)", dsttmpname, dst);
}
ret = close(dstfd);
if (ret < 0) {
err(EX_NOINPUT, "close(dst)");
}
ret = close(srcfd);
if (ret < 0) {
err(EX_NOINPUT, "close(src)");
}
return 0;
}
void
usage(void)
{
fprintf(stderr, "Usage: %s [-c] [-S] [-m <mode>] <src> <dst>\n",
getprogname());
exit(EX_USAGE);
}

View File

@ -0,0 +1,30 @@
export MakeInc_cmd=${SRCROOT}/makedefs/MakeInc.cmd
export MakeInc_def=${SRCROOT}/makedefs/MakeInc.def
export MakeInc_rule=${SRCROOT}/makedefs/MakeInc.rule
export MakeInc_dir=${SRCROOT}/makedefs/MakeInc.dir
include $(MakeInc_cmd)
include $(MakeInc_def)
OBJS = json_compilation_db.o
CFLAGS = -isysroot $(HOST_SDKROOT) -mmacosx-version-min=$(HOST_OS_VERSION) -g -O0 -I$(SOURCE) -I.
WARNFLAGS = -Wall
LDFLAGS = -isysroot $(HOST_SDKROOT) -mmacosx-version-min=$(HOST_OS_VERSION)
json_compilation_db: $(OBJS)
@$(LOG_HOST_LD) "$@"
$(_v)$(HOST_CC) $(LDFLAGS) -o $@ $^
@$(LOG_HOST_CODESIGN) "$@"
$(_v)env CODESIGN_ALLOCATE=$(HOST_CODESIGN_ALLOCATE) $(HOST_CODESIGN) -s - $@
%.o: %.c
@$(LOG_HOST_CC) "$@"
$(_v)$(HOST_CC) $(WARNFLAGS) $(CFLAGS) -c -o $@ $<
do_build_setup:: json_compilation_db
include $(MakeInc_rule)
include $(MakeInc_dir)

Some files were not shown because too many files have changed in this diff Show More