mirror of https://gogs.blitter.com/RLabs/xs
				
				
				
			Updated imports and vendor/ for local fork of schwanenlied.me crypto (chacha20, newhope, kyber)
Signed-off-by: Russ Magee <rmagee@gmail.com>
This commit is contained in:
		
							parent
							
								
									d75b419c7a
								
							
						
					
					
						commit
						eb9ce0e0e2
					
				
							
								
								
									
										10
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										10
									
								
								go.mod
								
								
								
								
							| 
						 | 
				
			
			@ -6,26 +6,24 @@ require (
 | 
			
		|||
	blitter.com/go/cryptmt v1.0.0
 | 
			
		||||
	blitter.com/go/goutmp v1.0.1
 | 
			
		||||
	blitter.com/go/herradurakex v1.0.0
 | 
			
		||||
	blitter.com/go/kyber v0.0.0-20200130200857-6f2021cb88d9
 | 
			
		||||
	blitter.com/go/mtwist v1.0.1 // indirect
 | 
			
		||||
	blitter.com/go/newhope v0.0.0-20200130200750-192fc08a8aae
 | 
			
		||||
	blitter.com/go/wanderer v0.8.1
 | 
			
		||||
	git.schwanenlied.me/yawning/chacha20.git v0.0.0-20170904085104-e3b1f968fc63 // indirect
 | 
			
		||||
	git.schwanenlied.me/yawning/kyber.git v0.0.0-20180530164001-a270899bd22c
 | 
			
		||||
	git.schwanenlied.me/yawning/newhope.git v0.0.0-20170622154529-9598792ba8f2
 | 
			
		||||
	github.com/jameskeane/bcrypt v0.0.0-20120420032655-c3cd44c1e20f
 | 
			
		||||
	github.com/klauspost/cpuid v1.2.2 // indirect
 | 
			
		||||
	github.com/klauspost/reedsolomon v1.9.3 // indirect
 | 
			
		||||
	github.com/kr/pty v1.1.4
 | 
			
		||||
	github.com/mattn/go-isatty v0.0.7
 | 
			
		||||
	github.com/pkg/errors v0.8.1 // indirect
 | 
			
		||||
	github.com/stretchr/testify v1.4.0 // indirect
 | 
			
		||||
	github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
 | 
			
		||||
	github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b // indirect
 | 
			
		||||
	github.com/tjfoc/gmsm v1.0.1 // indirect
 | 
			
		||||
	github.com/xtaci/kcp-go v5.4.19+incompatible
 | 
			
		||||
	github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae // indirect
 | 
			
		||||
	golang.org/x/crypto v0.0.0-20190417174047-f416ebab96af
 | 
			
		||||
	golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d
 | 
			
		||||
	golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 // indirect
 | 
			
		||||
	golang.org/x/sys v0.0.0-20190416152802-12500544f89f
 | 
			
		||||
	golang.org/x/sys v0.0.0-20190902133755-9109b7679e13
 | 
			
		||||
	gopkg.in/hlandau/easymetric.v1 v1.0.0 // indirect
 | 
			
		||||
	gopkg.in/hlandau/measurable.v1 v1.0.1 // indirect
 | 
			
		||||
	gopkg.in/hlandau/passlib.v1 v1.0.10
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										13
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										13
									
								
								go.sum
								
								
								
								
							| 
						 | 
				
			
			@ -1,11 +1,17 @@
 | 
			
		|||
blitter.com/go/chacha20 v0.0.0-20200130200441-214e4085f54c h1:LcnFFg6MCIJHf26P7eOUST45fNLHJI5erq0gWZaDLCo=
 | 
			
		||||
blitter.com/go/chacha20 v0.0.0-20200130200441-214e4085f54c/go.mod h1:EMJtRcf22WCtHGiXCw+NB/Sb/PYcXtUgUql6LDEwyXo=
 | 
			
		||||
blitter.com/go/cryptmt v1.0.0 h1:n+cNP/ReZrNe/w5FbD8DSfv0Wpj48nxhmMoLEk4hPXs=
 | 
			
		||||
blitter.com/go/cryptmt v1.0.0/go.mod h1:tdME2J3O4agaDAYIYNQzzuB28yVGnPSMmV3a/ucSU84=
 | 
			
		||||
blitter.com/go/goutmp v1.0.1 h1:jBqtp6pDwSbF4QEC3DjNfyaS8Nv5dFCOyaTfSbbb7TU=
 | 
			
		||||
blitter.com/go/goutmp v1.0.1/go.mod h1:gtlbjC8xGzMk/Cf0BpnVltSa3awOqJ+B5WAxVptTMxk=
 | 
			
		||||
blitter.com/go/herradurakex v1.0.0 h1:6XaxY+JLT1HUWPF0gYJnjX3pVjrw4YhYZEzZ1U0wkyc=
 | 
			
		||||
blitter.com/go/herradurakex v1.0.0/go.mod h1:m3+vYZX+2dDjdo+n/HDnXEYJX9pwmNeQLgAfJM8mtxw=
 | 
			
		||||
blitter.com/go/kyber v0.0.0-20200130200857-6f2021cb88d9 h1:D45AnrNphtvczBXRp5JQicZRTgaK/Is5bgPDDvRKhTc=
 | 
			
		||||
blitter.com/go/kyber v0.0.0-20200130200857-6f2021cb88d9/go.mod h1:SK6QfGG72lIfKW1Td0wH7f0wwN5nSIhV3K+wvzGNjrw=
 | 
			
		||||
blitter.com/go/mtwist v1.0.1 h1:PxmoWexfMpLmc8neHP/PcRc3s17ct7iz4d5W/qJVt04=
 | 
			
		||||
blitter.com/go/mtwist v1.0.1/go.mod h1:aU82Nx8+b1v8oZRNqImfEDzDTPim81rY0ACKAIclV18=
 | 
			
		||||
blitter.com/go/newhope v0.0.0-20200130200750-192fc08a8aae h1:YBBaCcdYRrI1btsmcMTv1VMPmaSXXz0RwKOTgMJYSRU=
 | 
			
		||||
blitter.com/go/newhope v0.0.0-20200130200750-192fc08a8aae/go.mod h1:ywoxfDBqInPsqtnxYsmS4SYMJ5D/kNcrFgpvI+Xcun0=
 | 
			
		||||
blitter.com/go/wanderer v0.8.1 h1:oQw8yASM7iI+S8GIgf3cUFdkJ8Sy/UQxRDJqhTswgwM=
 | 
			
		||||
blitter.com/go/wanderer v0.8.1/go.mod h1:FX1pAnZ5woEavy5CUIZco0/Gc2Msb3U0zsmi+6Hs4Rw=
 | 
			
		||||
git.schwanenlied.me/yawning/chacha20.git v0.0.0-20170904085104-e3b1f968fc63 h1:bwZNsbw3qFbg6ox55HrA37nPmh+/wtJxZ7uWeiAdUUc=
 | 
			
		||||
| 
						 | 
				
			
			@ -46,13 +52,20 @@ github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62
 | 
			
		|||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190417174047-f416ebab96af h1:6qGQw30u837TXZbCmLFR9AVA+RjJU1LIbvk0oIkDZGY=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190417174047-f416ebab96af/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 | 
			
		||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 | 
			
		||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
 | 
			
		||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190416152802-12500544f89f h1:1ZH9RnjNgLzh6YrsRp/c6ddZ8Lq0fq9xztNOoWJ2sz4=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190416152802-12500544f89f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190902133755-9109b7679e13 h1:tdsQdquKbTNMsSZLqnLELJGzCANp9oXhu6zFBW6ODx4=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 | 
			
		||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,661 @@
 | 
			
		|||
                    GNU AFFERO GENERAL PUBLIC LICENSE
 | 
			
		||||
                       Version 3, 19 November 2007
 | 
			
		||||
 | 
			
		||||
 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 | 
			
		||||
 Everyone is permitted to copy and distribute verbatim copies
 | 
			
		||||
 of this license document, but changing it is not allowed.
 | 
			
		||||
 | 
			
		||||
                            Preamble
 | 
			
		||||
 | 
			
		||||
  The GNU Affero General Public License is a free, copyleft license for
 | 
			
		||||
software and other kinds of works, specifically designed to ensure
 | 
			
		||||
cooperation with the community in the case of network server software.
 | 
			
		||||
 | 
			
		||||
  The licenses for most software and other practical works are designed
 | 
			
		||||
to take away your freedom to share and change the works.  By contrast,
 | 
			
		||||
our General Public Licenses are intended to guarantee your freedom to
 | 
			
		||||
share and change all versions of a program--to make sure it remains free
 | 
			
		||||
software for all its users.
 | 
			
		||||
 | 
			
		||||
  When we speak of free software, we are referring to freedom, not
 | 
			
		||||
price.  Our General Public Licenses are designed to make sure that you
 | 
			
		||||
have the freedom to distribute copies of free software (and charge for
 | 
			
		||||
them if you wish), that you receive source code or can get it if you
 | 
			
		||||
want it, that you can change the software or use pieces of it in new
 | 
			
		||||
free programs, and that you know you can do these things.
 | 
			
		||||
 | 
			
		||||
  Developers that use our General Public Licenses protect your rights
 | 
			
		||||
with two steps: (1) assert copyright on the software, and (2) offer
 | 
			
		||||
you this License which gives you legal permission to copy, distribute
 | 
			
		||||
and/or modify the software.
 | 
			
		||||
 | 
			
		||||
  A secondary benefit of defending all users' freedom is that
 | 
			
		||||
improvements made in alternate versions of the program, if they
 | 
			
		||||
receive widespread use, become available for other developers to
 | 
			
		||||
incorporate.  Many developers of free software are heartened and
 | 
			
		||||
encouraged by the resulting cooperation.  However, in the case of
 | 
			
		||||
software used on network servers, this result may fail to come about.
 | 
			
		||||
The GNU General Public License permits making a modified version and
 | 
			
		||||
letting the public access it on a server without ever releasing its
 | 
			
		||||
source code to the public.
 | 
			
		||||
 | 
			
		||||
  The GNU Affero General Public License is designed specifically to
 | 
			
		||||
ensure that, in such cases, the modified source code becomes available
 | 
			
		||||
to the community.  It requires the operator of a network server to
 | 
			
		||||
provide the source code of the modified version running there to the
 | 
			
		||||
users of that server.  Therefore, public use of a modified version, on
 | 
			
		||||
a publicly accessible server, gives the public access to the source
 | 
			
		||||
code of the modified version.
 | 
			
		||||
 | 
			
		||||
  An older license, called the Affero General Public License and
 | 
			
		||||
published by Affero, was designed to accomplish similar goals.  This is
 | 
			
		||||
a different license, not a version of the Affero GPL, but Affero has
 | 
			
		||||
released a new version of the Affero GPL which permits relicensing under
 | 
			
		||||
this license.
 | 
			
		||||
 | 
			
		||||
  The precise terms and conditions for copying, distribution and
 | 
			
		||||
modification follow.
 | 
			
		||||
 | 
			
		||||
                       TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
  0. Definitions.
 | 
			
		||||
 | 
			
		||||
  "This License" refers to version 3 of the GNU Affero General Public License.
 | 
			
		||||
 | 
			
		||||
  "Copyright" also means copyright-like laws that apply to other kinds of
 | 
			
		||||
works, such as semiconductor masks.
 | 
			
		||||
 | 
			
		||||
  "The Program" refers to any copyrightable work licensed under this
 | 
			
		||||
License.  Each licensee is addressed as "you".  "Licensees" and
 | 
			
		||||
"recipients" may be individuals or organizations.
 | 
			
		||||
 | 
			
		||||
  To "modify" a work means to copy from or adapt all or part of the work
 | 
			
		||||
in a fashion requiring copyright permission, other than the making of an
 | 
			
		||||
exact copy.  The resulting work is called a "modified version" of the
 | 
			
		||||
earlier work or a work "based on" the earlier work.
 | 
			
		||||
 | 
			
		||||
  A "covered work" means either the unmodified Program or a work based
 | 
			
		||||
on the Program.
 | 
			
		||||
 | 
			
		||||
  To "propagate" a work means to do anything with it that, without
 | 
			
		||||
permission, would make you directly or secondarily liable for
 | 
			
		||||
infringement under applicable copyright law, except executing it on a
 | 
			
		||||
computer or modifying a private copy.  Propagation includes copying,
 | 
			
		||||
distribution (with or without modification), making available to the
 | 
			
		||||
public, and in some countries other activities as well.
 | 
			
		||||
 | 
			
		||||
  To "convey" a work means any kind of propagation that enables other
 | 
			
		||||
parties to make or receive copies.  Mere interaction with a user through
 | 
			
		||||
a computer network, with no transfer of a copy, is not conveying.
 | 
			
		||||
 | 
			
		||||
  An interactive user interface displays "Appropriate Legal Notices"
 | 
			
		||||
to the extent that it includes a convenient and prominently visible
 | 
			
		||||
feature that (1) displays an appropriate copyright notice, and (2)
 | 
			
		||||
tells the user that there is no warranty for the work (except to the
 | 
			
		||||
extent that warranties are provided), that licensees may convey the
 | 
			
		||||
work under this License, and how to view a copy of this License.  If
 | 
			
		||||
the interface presents a list of user commands or options, such as a
 | 
			
		||||
menu, a prominent item in the list meets this criterion.
 | 
			
		||||
 | 
			
		||||
  1. Source Code.
 | 
			
		||||
 | 
			
		||||
  The "source code" for a work means the preferred form of the work
 | 
			
		||||
for making modifications to it.  "Object code" means any non-source
 | 
			
		||||
form of a work.
 | 
			
		||||
 | 
			
		||||
  A "Standard Interface" means an interface that either is an official
 | 
			
		||||
standard defined by a recognized standards body, or, in the case of
 | 
			
		||||
interfaces specified for a particular programming language, one that
 | 
			
		||||
is widely used among developers working in that language.
 | 
			
		||||
 | 
			
		||||
  The "System Libraries" of an executable work include anything, other
 | 
			
		||||
than the work as a whole, that (a) is included in the normal form of
 | 
			
		||||
packaging a Major Component, but which is not part of that Major
 | 
			
		||||
Component, and (b) serves only to enable use of the work with that
 | 
			
		||||
Major Component, or to implement a Standard Interface for which an
 | 
			
		||||
implementation is available to the public in source code form.  A
 | 
			
		||||
"Major Component", in this context, means a major essential component
 | 
			
		||||
(kernel, window system, and so on) of the specific operating system
 | 
			
		||||
(if any) on which the executable work runs, or a compiler used to
 | 
			
		||||
produce the work, or an object code interpreter used to run it.
 | 
			
		||||
 | 
			
		||||
  The "Corresponding Source" for a work in object code form means all
 | 
			
		||||
the source code needed to generate, install, and (for an executable
 | 
			
		||||
work) run the object code and to modify the work, including scripts to
 | 
			
		||||
control those activities.  However, it does not include the work's
 | 
			
		||||
System Libraries, or general-purpose tools or generally available free
 | 
			
		||||
programs which are used unmodified in performing those activities but
 | 
			
		||||
which are not part of the work.  For example, Corresponding Source
 | 
			
		||||
includes interface definition files associated with source files for
 | 
			
		||||
the work, and the source code for shared libraries and dynamically
 | 
			
		||||
linked subprograms that the work is specifically designed to require,
 | 
			
		||||
such as by intimate data communication or control flow between those
 | 
			
		||||
subprograms and other parts of the work.
 | 
			
		||||
 | 
			
		||||
  The Corresponding Source need not include anything that users
 | 
			
		||||
can regenerate automatically from other parts of the Corresponding
 | 
			
		||||
Source.
 | 
			
		||||
 | 
			
		||||
  The Corresponding Source for a work in source code form is that
 | 
			
		||||
same work.
 | 
			
		||||
 | 
			
		||||
  2. Basic Permissions.
 | 
			
		||||
 | 
			
		||||
  All rights granted under this License are granted for the term of
 | 
			
		||||
copyright on the Program, and are irrevocable provided the stated
 | 
			
		||||
conditions are met.  This License explicitly affirms your unlimited
 | 
			
		||||
permission to run the unmodified Program.  The output from running a
 | 
			
		||||
covered work is covered by this License only if the output, given its
 | 
			
		||||
content, constitutes a covered work.  This License acknowledges your
 | 
			
		||||
rights of fair use or other equivalent, as provided by copyright law.
 | 
			
		||||
 | 
			
		||||
  You may make, run and propagate covered works that you do not
 | 
			
		||||
convey, without conditions so long as your license otherwise remains
 | 
			
		||||
in force.  You may convey covered works to others for the sole purpose
 | 
			
		||||
of having them make modifications exclusively for you, or provide you
 | 
			
		||||
with facilities for running those works, provided that you comply with
 | 
			
		||||
the terms of this License in conveying all material for which you do
 | 
			
		||||
not control copyright.  Those thus making or running the covered works
 | 
			
		||||
for you must do so exclusively on your behalf, under your direction
 | 
			
		||||
and control, on terms that prohibit them from making any copies of
 | 
			
		||||
your copyrighted material outside their relationship with you.
 | 
			
		||||
 | 
			
		||||
  Conveying under any other circumstances is permitted solely under
 | 
			
		||||
the conditions stated below.  Sublicensing is not allowed; section 10
 | 
			
		||||
makes it unnecessary.
 | 
			
		||||
 | 
			
		||||
  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
 | 
			
		||||
 | 
			
		||||
  No covered work shall be deemed part of an effective technological
 | 
			
		||||
measure under any applicable law fulfilling obligations under article
 | 
			
		||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
 | 
			
		||||
similar laws prohibiting or restricting circumvention of such
 | 
			
		||||
measures.
 | 
			
		||||
 | 
			
		||||
  When you convey a covered work, you waive any legal power to forbid
 | 
			
		||||
circumvention of technological measures to the extent such circumvention
 | 
			
		||||
is effected by exercising rights under this License with respect to
 | 
			
		||||
the covered work, and you disclaim any intention to limit operation or
 | 
			
		||||
modification of the work as a means of enforcing, against the work's
 | 
			
		||||
users, your or third parties' legal rights to forbid circumvention of
 | 
			
		||||
technological measures.
 | 
			
		||||
 | 
			
		||||
  4. Conveying Verbatim Copies.
 | 
			
		||||
 | 
			
		||||
  You may convey verbatim copies of the Program's source code as you
 | 
			
		||||
receive it, in any medium, provided that you conspicuously and
 | 
			
		||||
appropriately publish on each copy an appropriate copyright notice;
 | 
			
		||||
keep intact all notices stating that this License and any
 | 
			
		||||
non-permissive terms added in accord with section 7 apply to the code;
 | 
			
		||||
keep intact all notices of the absence of any warranty; and give all
 | 
			
		||||
recipients a copy of this License along with the Program.
 | 
			
		||||
 | 
			
		||||
  You may charge any price or no price for each copy that you convey,
 | 
			
		||||
and you may offer support or warranty protection for a fee.
 | 
			
		||||
 | 
			
		||||
  5. Conveying Modified Source Versions.
 | 
			
		||||
 | 
			
		||||
  You may convey a work based on the Program, or the modifications to
 | 
			
		||||
produce it from the Program, in the form of source code under the
 | 
			
		||||
terms of section 4, provided that you also meet all of these conditions:
 | 
			
		||||
 | 
			
		||||
    a) The work must carry prominent notices stating that you modified
 | 
			
		||||
    it, and giving a relevant date.
 | 
			
		||||
 | 
			
		||||
    b) The work must carry prominent notices stating that it is
 | 
			
		||||
    released under this License and any conditions added under section
 | 
			
		||||
    7.  This requirement modifies the requirement in section 4 to
 | 
			
		||||
    "keep intact all notices".
 | 
			
		||||
 | 
			
		||||
    c) You must license the entire work, as a whole, under this
 | 
			
		||||
    License to anyone who comes into possession of a copy.  This
 | 
			
		||||
    License will therefore apply, along with any applicable section 7
 | 
			
		||||
    additional terms, to the whole of the work, and all its parts,
 | 
			
		||||
    regardless of how they are packaged.  This License gives no
 | 
			
		||||
    permission to license the work in any other way, but it does not
 | 
			
		||||
    invalidate such permission if you have separately received it.
 | 
			
		||||
 | 
			
		||||
    d) If the work has interactive user interfaces, each must display
 | 
			
		||||
    Appropriate Legal Notices; however, if the Program has interactive
 | 
			
		||||
    interfaces that do not display Appropriate Legal Notices, your
 | 
			
		||||
    work need not make them do so.
 | 
			
		||||
 | 
			
		||||
  A compilation of a covered work with other separate and independent
 | 
			
		||||
works, which are not by their nature extensions of the covered work,
 | 
			
		||||
and which are not combined with it such as to form a larger program,
 | 
			
		||||
in or on a volume of a storage or distribution medium, is called an
 | 
			
		||||
"aggregate" if the compilation and its resulting copyright are not
 | 
			
		||||
used to limit the access or legal rights of the compilation's users
 | 
			
		||||
beyond what the individual works permit.  Inclusion of a covered work
 | 
			
		||||
in an aggregate does not cause this License to apply to the other
 | 
			
		||||
parts of the aggregate.
 | 
			
		||||
 | 
			
		||||
  6. Conveying Non-Source Forms.
 | 
			
		||||
 | 
			
		||||
  You may convey a covered work in object code form under the terms
 | 
			
		||||
of sections 4 and 5, provided that you also convey the
 | 
			
		||||
machine-readable Corresponding Source under the terms of this License,
 | 
			
		||||
in one of these ways:
 | 
			
		||||
 | 
			
		||||
    a) Convey the object code in, or embodied in, a physical product
 | 
			
		||||
    (including a physical distribution medium), accompanied by the
 | 
			
		||||
    Corresponding Source fixed on a durable physical medium
 | 
			
		||||
    customarily used for software interchange.
 | 
			
		||||
 | 
			
		||||
    b) Convey the object code in, or embodied in, a physical product
 | 
			
		||||
    (including a physical distribution medium), accompanied by a
 | 
			
		||||
    written offer, valid for at least three years and valid for as
 | 
			
		||||
    long as you offer spare parts or customer support for that product
 | 
			
		||||
    model, to give anyone who possesses the object code either (1) a
 | 
			
		||||
    copy of the Corresponding Source for all the software in the
 | 
			
		||||
    product that is covered by this License, on a durable physical
 | 
			
		||||
    medium customarily used for software interchange, for a price no
 | 
			
		||||
    more than your reasonable cost of physically performing this
 | 
			
		||||
    conveying of source, or (2) access to copy the
 | 
			
		||||
    Corresponding Source from a network server at no charge.
 | 
			
		||||
 | 
			
		||||
    c) Convey individual copies of the object code with a copy of the
 | 
			
		||||
    written offer to provide the Corresponding Source.  This
 | 
			
		||||
    alternative is allowed only occasionally and noncommercially, and
 | 
			
		||||
    only if you received the object code with such an offer, in accord
 | 
			
		||||
    with subsection 6b.
 | 
			
		||||
 | 
			
		||||
    d) Convey the object code by offering access from a designated
 | 
			
		||||
    place (gratis or for a charge), and offer equivalent access to the
 | 
			
		||||
    Corresponding Source in the same way through the same place at no
 | 
			
		||||
    further charge.  You need not require recipients to copy the
 | 
			
		||||
    Corresponding Source along with the object code.  If the place to
 | 
			
		||||
    copy the object code is a network server, the Corresponding Source
 | 
			
		||||
    may be on a different server (operated by you or a third party)
 | 
			
		||||
    that supports equivalent copying facilities, provided you maintain
 | 
			
		||||
    clear directions next to the object code saying where to find the
 | 
			
		||||
    Corresponding Source.  Regardless of what server hosts the
 | 
			
		||||
    Corresponding Source, you remain obligated to ensure that it is
 | 
			
		||||
    available for as long as needed to satisfy these requirements.
 | 
			
		||||
 | 
			
		||||
    e) Convey the object code using peer-to-peer transmission, provided
 | 
			
		||||
    you inform other peers where the object code and Corresponding
 | 
			
		||||
    Source of the work are being offered to the general public at no
 | 
			
		||||
    charge under subsection 6d.
 | 
			
		||||
 | 
			
		||||
  A separable portion of the object code, whose source code is excluded
 | 
			
		||||
from the Corresponding Source as a System Library, need not be
 | 
			
		||||
included in conveying the object code work.
 | 
			
		||||
 | 
			
		||||
  A "User Product" is either (1) a "consumer product", which means any
 | 
			
		||||
tangible personal property which is normally used for personal, family,
 | 
			
		||||
or household purposes, or (2) anything designed or sold for incorporation
 | 
			
		||||
into a dwelling.  In determining whether a product is a consumer product,
 | 
			
		||||
doubtful cases shall be resolved in favor of coverage.  For a particular
 | 
			
		||||
product received by a particular user, "normally used" refers to a
 | 
			
		||||
typical or common use of that class of product, regardless of the status
 | 
			
		||||
of the particular user or of the way in which the particular user
 | 
			
		||||
actually uses, or expects or is expected to use, the product.  A product
 | 
			
		||||
is a consumer product regardless of whether the product has substantial
 | 
			
		||||
commercial, industrial or non-consumer uses, unless such uses represent
 | 
			
		||||
the only significant mode of use of the product.
 | 
			
		||||
 | 
			
		||||
  "Installation Information" for a User Product means any methods,
 | 
			
		||||
procedures, authorization keys, or other information required to install
 | 
			
		||||
and execute modified versions of a covered work in that User Product from
 | 
			
		||||
a modified version of its Corresponding Source.  The information must
 | 
			
		||||
suffice to ensure that the continued functioning of the modified object
 | 
			
		||||
code is in no case prevented or interfered with solely because
 | 
			
		||||
modification has been made.
 | 
			
		||||
 | 
			
		||||
  If you convey an object code work under this section in, or with, or
 | 
			
		||||
specifically for use in, a User Product, and the conveying occurs as
 | 
			
		||||
part of a transaction in which the right of possession and use of the
 | 
			
		||||
User Product is transferred to the recipient in perpetuity or for a
 | 
			
		||||
fixed term (regardless of how the transaction is characterized), the
 | 
			
		||||
Corresponding Source conveyed under this section must be accompanied
 | 
			
		||||
by the Installation Information.  But this requirement does not apply
 | 
			
		||||
if neither you nor any third party retains the ability to install
 | 
			
		||||
modified object code on the User Product (for example, the work has
 | 
			
		||||
been installed in ROM).
 | 
			
		||||
 | 
			
		||||
  The requirement to provide Installation Information does not include a
 | 
			
		||||
requirement to continue to provide support service, warranty, or updates
 | 
			
		||||
for a work that has been modified or installed by the recipient, or for
 | 
			
		||||
the User Product in which it has been modified or installed.  Access to a
 | 
			
		||||
network may be denied when the modification itself materially and
 | 
			
		||||
adversely affects the operation of the network or violates the rules and
 | 
			
		||||
protocols for communication across the network.
 | 
			
		||||
 | 
			
		||||
  Corresponding Source conveyed, and Installation Information provided,
 | 
			
		||||
in accord with this section must be in a format that is publicly
 | 
			
		||||
documented (and with an implementation available to the public in
 | 
			
		||||
source code form), and must require no special password or key for
 | 
			
		||||
unpacking, reading or copying.
 | 
			
		||||
 | 
			
		||||
  7. Additional Terms.
 | 
			
		||||
 | 
			
		||||
  "Additional permissions" are terms that supplement the terms of this
 | 
			
		||||
License by making exceptions from one or more of its conditions.
 | 
			
		||||
Additional permissions that are applicable to the entire Program shall
 | 
			
		||||
be treated as though they were included in this License, to the extent
 | 
			
		||||
that they are valid under applicable law.  If additional permissions
 | 
			
		||||
apply only to part of the Program, that part may be used separately
 | 
			
		||||
under those permissions, but the entire Program remains governed by
 | 
			
		||||
this License without regard to the additional permissions.
 | 
			
		||||
 | 
			
		||||
  When you convey a copy of a covered work, you may at your option
 | 
			
		||||
remove any additional permissions from that copy, or from any part of
 | 
			
		||||
it.  (Additional permissions may be written to require their own
 | 
			
		||||
removal in certain cases when you modify the work.)  You may place
 | 
			
		||||
additional permissions on material, added by you to a covered work,
 | 
			
		||||
for which you have or can give appropriate copyright permission.
 | 
			
		||||
 | 
			
		||||
  Notwithstanding any other provision of this License, for material you
 | 
			
		||||
add to a covered work, you may (if authorized by the copyright holders of
 | 
			
		||||
that material) supplement the terms of this License with terms:
 | 
			
		||||
 | 
			
		||||
    a) Disclaiming warranty or limiting liability differently from the
 | 
			
		||||
    terms of sections 15 and 16 of this License; or
 | 
			
		||||
 | 
			
		||||
    b) Requiring preservation of specified reasonable legal notices or
 | 
			
		||||
    author attributions in that material or in the Appropriate Legal
 | 
			
		||||
    Notices displayed by works containing it; or
 | 
			
		||||
 | 
			
		||||
    c) Prohibiting misrepresentation of the origin of that material, or
 | 
			
		||||
    requiring that modified versions of such material be marked in
 | 
			
		||||
    reasonable ways as different from the original version; or
 | 
			
		||||
 | 
			
		||||
    d) Limiting the use for publicity purposes of names of licensors or
 | 
			
		||||
    authors of the material; or
 | 
			
		||||
 | 
			
		||||
    e) Declining to grant rights under trademark law for use of some
 | 
			
		||||
    trade names, trademarks, or service marks; or
 | 
			
		||||
 | 
			
		||||
    f) Requiring indemnification of licensors and authors of that
 | 
			
		||||
    material by anyone who conveys the material (or modified versions of
 | 
			
		||||
    it) with contractual assumptions of liability to the recipient, for
 | 
			
		||||
    any liability that these contractual assumptions directly impose on
 | 
			
		||||
    those licensors and authors.
 | 
			
		||||
 | 
			
		||||
  All other non-permissive additional terms are considered "further
 | 
			
		||||
restrictions" within the meaning of section 10.  If the Program as you
 | 
			
		||||
received it, or any part of it, contains a notice stating that it is
 | 
			
		||||
governed by this License along with a term that is a further
 | 
			
		||||
restriction, you may remove that term.  If a license document contains
 | 
			
		||||
a further restriction but permits relicensing or conveying under this
 | 
			
		||||
License, you may add to a covered work material governed by the terms
 | 
			
		||||
of that license document, provided that the further restriction does
 | 
			
		||||
not survive such relicensing or conveying.
 | 
			
		||||
 | 
			
		||||
  If you add terms to a covered work in accord with this section, you
 | 
			
		||||
must place, in the relevant source files, a statement of the
 | 
			
		||||
additional terms that apply to those files, or a notice indicating
 | 
			
		||||
where to find the applicable terms.
 | 
			
		||||
 | 
			
		||||
  Additional terms, permissive or non-permissive, may be stated in the
 | 
			
		||||
form of a separately written license, or stated as exceptions;
 | 
			
		||||
the above requirements apply either way.
 | 
			
		||||
 | 
			
		||||
  8. Termination.
 | 
			
		||||
 | 
			
		||||
  You may not propagate or modify a covered work except as expressly
 | 
			
		||||
provided under this License.  Any attempt otherwise to propagate or
 | 
			
		||||
modify it is void, and will automatically terminate your rights under
 | 
			
		||||
this License (including any patent licenses granted under the third
 | 
			
		||||
paragraph of section 11).
 | 
			
		||||
 | 
			
		||||
  However, if you cease all violation of this License, then your
 | 
			
		||||
license from a particular copyright holder is reinstated (a)
 | 
			
		||||
provisionally, unless and until the copyright holder explicitly and
 | 
			
		||||
finally terminates your license, and (b) permanently, if the copyright
 | 
			
		||||
holder fails to notify you of the violation by some reasonable means
 | 
			
		||||
prior to 60 days after the cessation.
 | 
			
		||||
 | 
			
		||||
  Moreover, your license from a particular copyright holder is
 | 
			
		||||
reinstated permanently if the copyright holder notifies you of the
 | 
			
		||||
violation by some reasonable means, this is the first time you have
 | 
			
		||||
received notice of violation of this License (for any work) from that
 | 
			
		||||
copyright holder, and you cure the violation prior to 30 days after
 | 
			
		||||
your receipt of the notice.
 | 
			
		||||
 | 
			
		||||
  Termination of your rights under this section does not terminate the
 | 
			
		||||
licenses of parties who have received copies or rights from you under
 | 
			
		||||
this License.  If your rights have been terminated and not permanently
 | 
			
		||||
reinstated, you do not qualify to receive new licenses for the same
 | 
			
		||||
material under section 10.
 | 
			
		||||
 | 
			
		||||
  9. Acceptance Not Required for Having Copies.
 | 
			
		||||
 | 
			
		||||
  You are not required to accept this License in order to receive or
 | 
			
		||||
run a copy of the Program.  Ancillary propagation of a covered work
 | 
			
		||||
occurring solely as a consequence of using peer-to-peer transmission
 | 
			
		||||
to receive a copy likewise does not require acceptance.  However,
 | 
			
		||||
nothing other than this License grants you permission to propagate or
 | 
			
		||||
modify any covered work.  These actions infringe copyright if you do
 | 
			
		||||
not accept this License.  Therefore, by modifying or propagating a
 | 
			
		||||
covered work, you indicate your acceptance of this License to do so.
 | 
			
		||||
 | 
			
		||||
  10. Automatic Licensing of Downstream Recipients.
 | 
			
		||||
 | 
			
		||||
  Each time you convey a covered work, the recipient automatically
 | 
			
		||||
receives a license from the original licensors, to run, modify and
 | 
			
		||||
propagate that work, subject to this License.  You are not responsible
 | 
			
		||||
for enforcing compliance by third parties with this License.
 | 
			
		||||
 | 
			
		||||
  An "entity transaction" is a transaction transferring control of an
 | 
			
		||||
organization, or substantially all assets of one, or subdividing an
 | 
			
		||||
organization, or merging organizations.  If propagation of a covered
 | 
			
		||||
work results from an entity transaction, each party to that
 | 
			
		||||
transaction who receives a copy of the work also receives whatever
 | 
			
		||||
licenses to the work the party's predecessor in interest had or could
 | 
			
		||||
give under the previous paragraph, plus a right to possession of the
 | 
			
		||||
Corresponding Source of the work from the predecessor in interest, if
 | 
			
		||||
the predecessor has it or can get it with reasonable efforts.
 | 
			
		||||
 | 
			
		||||
  You may not impose any further restrictions on the exercise of the
 | 
			
		||||
rights granted or affirmed under this License.  For example, you may
 | 
			
		||||
not impose a license fee, royalty, or other charge for exercise of
 | 
			
		||||
rights granted under this License, and you may not initiate litigation
 | 
			
		||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
 | 
			
		||||
any patent claim is infringed by making, using, selling, offering for
 | 
			
		||||
sale, or importing the Program or any portion of it.
 | 
			
		||||
 | 
			
		||||
  11. Patents.
 | 
			
		||||
 | 
			
		||||
  A "contributor" is a copyright holder who authorizes use under this
 | 
			
		||||
License of the Program or a work on which the Program is based.  The
 | 
			
		||||
work thus licensed is called the contributor's "contributor version".
 | 
			
		||||
 | 
			
		||||
  A contributor's "essential patent claims" are all patent claims
 | 
			
		||||
owned or controlled by the contributor, whether already acquired or
 | 
			
		||||
hereafter acquired, that would be infringed by some manner, permitted
 | 
			
		||||
by this License, of making, using, or selling its contributor version,
 | 
			
		||||
but do not include claims that would be infringed only as a
 | 
			
		||||
consequence of further modification of the contributor version.  For
 | 
			
		||||
purposes of this definition, "control" includes the right to grant
 | 
			
		||||
patent sublicenses in a manner consistent with the requirements of
 | 
			
		||||
this License.
 | 
			
		||||
 | 
			
		||||
  Each contributor grants you a non-exclusive, worldwide, royalty-free
 | 
			
		||||
patent license under the contributor's essential patent claims, to
 | 
			
		||||
make, use, sell, offer for sale, import and otherwise run, modify and
 | 
			
		||||
propagate the contents of its contributor version.
 | 
			
		||||
 | 
			
		||||
  In the following three paragraphs, a "patent license" is any express
 | 
			
		||||
agreement or commitment, however denominated, not to enforce a patent
 | 
			
		||||
(such as an express permission to practice a patent or covenant not to
 | 
			
		||||
sue for patent infringement).  To "grant" such a patent license to a
 | 
			
		||||
party means to make such an agreement or commitment not to enforce a
 | 
			
		||||
patent against the party.
 | 
			
		||||
 | 
			
		||||
  If you convey a covered work, knowingly relying on a patent license,
 | 
			
		||||
and the Corresponding Source of the work is not available for anyone
 | 
			
		||||
to copy, free of charge and under the terms of this License, through a
 | 
			
		||||
publicly available network server or other readily accessible means,
 | 
			
		||||
then you must either (1) cause the Corresponding Source to be so
 | 
			
		||||
available, or (2) arrange to deprive yourself of the benefit of the
 | 
			
		||||
patent license for this particular work, or (3) arrange, in a manner
 | 
			
		||||
consistent with the requirements of this License, to extend the patent
 | 
			
		||||
license to downstream recipients.  "Knowingly relying" means you have
 | 
			
		||||
actual knowledge that, but for the patent license, your conveying the
 | 
			
		||||
covered work in a country, or your recipient's use of the covered work
 | 
			
		||||
in a country, would infringe one or more identifiable patents in that
 | 
			
		||||
country that you have reason to believe are valid.
 | 
			
		||||
 | 
			
		||||
  If, pursuant to or in connection with a single transaction or
 | 
			
		||||
arrangement, you convey, or propagate by procuring conveyance of, a
 | 
			
		||||
covered work, and grant a patent license to some of the parties
 | 
			
		||||
receiving the covered work authorizing them to use, propagate, modify
 | 
			
		||||
or convey a specific copy of the covered work, then the patent license
 | 
			
		||||
you grant is automatically extended to all recipients of the covered
 | 
			
		||||
work and works based on it.
 | 
			
		||||
 | 
			
		||||
  A patent license is "discriminatory" if it does not include within
 | 
			
		||||
the scope of its coverage, prohibits the exercise of, or is
 | 
			
		||||
conditioned on the non-exercise of one or more of the rights that are
 | 
			
		||||
specifically granted under this License.  You may not convey a covered
 | 
			
		||||
work if you are a party to an arrangement with a third party that is
 | 
			
		||||
in the business of distributing software, under which you make payment
 | 
			
		||||
to the third party based on the extent of your activity of conveying
 | 
			
		||||
the work, and under which the third party grants, to any of the
 | 
			
		||||
parties who would receive the covered work from you, a discriminatory
 | 
			
		||||
patent license (a) in connection with copies of the covered work
 | 
			
		||||
conveyed by you (or copies made from those copies), or (b) primarily
 | 
			
		||||
for and in connection with specific products or compilations that
 | 
			
		||||
contain the covered work, unless you entered into that arrangement,
 | 
			
		||||
or that patent license was granted, prior to 28 March 2007.
 | 
			
		||||
 | 
			
		||||
  Nothing in this License shall be construed as excluding or limiting
 | 
			
		||||
any implied license or other defenses to infringement that may
 | 
			
		||||
otherwise be available to you under applicable patent law.
 | 
			
		||||
 | 
			
		||||
  12. No Surrender of Others' Freedom.
 | 
			
		||||
 | 
			
		||||
  If conditions are imposed on you (whether by court order, agreement or
 | 
			
		||||
otherwise) that contradict the conditions of this License, they do not
 | 
			
		||||
excuse you from the conditions of this License.  If you cannot convey a
 | 
			
		||||
covered work so as to satisfy simultaneously your obligations under this
 | 
			
		||||
License and any other pertinent obligations, then as a consequence you may
 | 
			
		||||
not convey it at all.  For example, if you agree to terms that obligate you
 | 
			
		||||
to collect a royalty for further conveying from those to whom you convey
 | 
			
		||||
the Program, the only way you could satisfy both those terms and this
 | 
			
		||||
License would be to refrain entirely from conveying the Program.
 | 
			
		||||
 | 
			
		||||
  13. Remote Network Interaction; Use with the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
  Notwithstanding any other provision of this License, if you modify the
 | 
			
		||||
Program, your modified version must prominently offer all users
 | 
			
		||||
interacting with it remotely through a computer network (if your version
 | 
			
		||||
supports such interaction) an opportunity to receive the Corresponding
 | 
			
		||||
Source of your version by providing access to the Corresponding Source
 | 
			
		||||
from a network server at no charge, through some standard or customary
 | 
			
		||||
means of facilitating copying of software.  This Corresponding Source
 | 
			
		||||
shall include the Corresponding Source for any work covered by version 3
 | 
			
		||||
of the GNU General Public License that is incorporated pursuant to the
 | 
			
		||||
following paragraph.
 | 
			
		||||
 | 
			
		||||
  Notwithstanding any other provision of this License, you have
 | 
			
		||||
permission to link or combine any covered work with a work licensed
 | 
			
		||||
under version 3 of the GNU General Public License into a single
 | 
			
		||||
combined work, and to convey the resulting work.  The terms of this
 | 
			
		||||
License will continue to apply to the part which is the covered work,
 | 
			
		||||
but the work with which it is combined will remain governed by version
 | 
			
		||||
3 of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
  14. Revised Versions of this License.
 | 
			
		||||
 | 
			
		||||
  The Free Software Foundation may publish revised and/or new versions of
 | 
			
		||||
the GNU Affero General Public License from time to time.  Such new versions
 | 
			
		||||
will be similar in spirit to the present version, but may differ in detail to
 | 
			
		||||
address new problems or concerns.
 | 
			
		||||
 | 
			
		||||
  Each version is given a distinguishing version number.  If the
 | 
			
		||||
Program specifies that a certain numbered version of the GNU Affero General
 | 
			
		||||
Public License "or any later version" applies to it, you have the
 | 
			
		||||
option of following the terms and conditions either of that numbered
 | 
			
		||||
version or of any later version published by the Free Software
 | 
			
		||||
Foundation.  If the Program does not specify a version number of the
 | 
			
		||||
GNU Affero General Public License, you may choose any version ever published
 | 
			
		||||
by the Free Software Foundation.
 | 
			
		||||
 | 
			
		||||
  If the Program specifies that a proxy can decide which future
 | 
			
		||||
versions of the GNU Affero General Public License can be used, that proxy's
 | 
			
		||||
public statement of acceptance of a version permanently authorizes you
 | 
			
		||||
to choose that version for the Program.
 | 
			
		||||
 | 
			
		||||
  Later license versions may give you additional or different
 | 
			
		||||
permissions.  However, no additional obligations are imposed on any
 | 
			
		||||
author or copyright holder as a result of your choosing to follow a
 | 
			
		||||
later version.
 | 
			
		||||
 | 
			
		||||
  15. Disclaimer of Warranty.
 | 
			
		||||
 | 
			
		||||
  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
 | 
			
		||||
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
 | 
			
		||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
 | 
			
		||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | 
			
		||||
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
 | 
			
		||||
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
 | 
			
		||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
 | 
			
		||||
 | 
			
		||||
  16. Limitation of Liability.
 | 
			
		||||
 | 
			
		||||
  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
 | 
			
		||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
 | 
			
		||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
 | 
			
		||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
 | 
			
		||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
 | 
			
		||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
 | 
			
		||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
 | 
			
		||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
 | 
			
		||||
SUCH DAMAGES.
 | 
			
		||||
 | 
			
		||||
  17. Interpretation of Sections 15 and 16.
 | 
			
		||||
 | 
			
		||||
  If the disclaimer of warranty and limitation of liability provided
 | 
			
		||||
above cannot be given local legal effect according to their terms,
 | 
			
		||||
reviewing courts shall apply local law that most closely approximates
 | 
			
		||||
an absolute waiver of all civil liability in connection with the
 | 
			
		||||
Program, unless a warranty or assumption of liability accompanies a
 | 
			
		||||
copy of the Program in return for a fee.
 | 
			
		||||
 | 
			
		||||
                     END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
            How to Apply These Terms to Your New Programs
 | 
			
		||||
 | 
			
		||||
  If you develop a new program, and you want it to be of the greatest
 | 
			
		||||
possible use to the public, the best way to achieve this is to make it
 | 
			
		||||
free software which everyone can redistribute and change under these terms.
 | 
			
		||||
 | 
			
		||||
  To do so, attach the following notices to the program.  It is safest
 | 
			
		||||
to attach them to the start of each source file to most effectively
 | 
			
		||||
state the exclusion of warranty; and each file should have at least
 | 
			
		||||
the "copyright" line and a pointer to where the full notice is found.
 | 
			
		||||
 | 
			
		||||
    <one line to give the program's name and a brief idea of what it does.>
 | 
			
		||||
    Copyright (C) <year>  <name of author>
 | 
			
		||||
 | 
			
		||||
    This program is free software: you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU Affero General Public License as published by
 | 
			
		||||
    the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
    (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
    This program is distributed in the hope that it will be useful,
 | 
			
		||||
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU Affero General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
Also add information on how to contact you by electronic and paper mail.
 | 
			
		||||
 | 
			
		||||
  If your software can interact with users remotely through a computer
 | 
			
		||||
network, you should also make sure that it provides a way for users to
 | 
			
		||||
get its source.  For example, if your program is a web application, its
 | 
			
		||||
interface could display a "Source" link that leads users to an archive
 | 
			
		||||
of the code.  There are many ways you could offer source, and different
 | 
			
		||||
solutions will be better for different programs; see section 13 for the
 | 
			
		||||
specific requirements.
 | 
			
		||||
 | 
			
		||||
  You should also get your employer (if you work as a programmer) or school,
 | 
			
		||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
 | 
			
		||||
For more information on this, and how to apply and follow the GNU AGPL, see
 | 
			
		||||
<http://www.gnu.org/licenses/>.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
### chacha20 - ChaCha20
 | 
			
		||||
#### Yawning Angel (yawning at schwanenlied dot me)
 | 
			
		||||
 | 
			
		||||
Yet another Go ChaCha20 implementation.  Everything else I found  was slow,
 | 
			
		||||
Yet another Go ChaCha20 implementation.  Everything else I found was slow,
 | 
			
		||||
didn't support all the variants I need to use, or relied on cgo to go fast.
 | 
			
		||||
 | 
			
		||||
Features:
 | 
			
		||||
| 
						 | 
				
			
			@ -9,6 +9,5 @@ Features:
 | 
			
		|||
 * 20 round, 256 bit key only.  Everything else is pointless and stupid.
 | 
			
		||||
 * IETF 96 bit nonce variant.
 | 
			
		||||
 * XChaCha 24 byte nonce variant.
 | 
			
		||||
 * SSE2 and AVX2 support on amd64 targets.
 | 
			
		||||
 * SSSE3 and AVX2 support on amd64 targets.
 | 
			
		||||
 * Incremental encrypt/decrypt support, unlike golang.org/x/crypto/salsa20.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,18 +1,30 @@
 | 
			
		|||
// chacha20.go - A ChaCha stream cipher implementation.
 | 
			
		||||
// Copryright (C) 2019 Yawning Angel
 | 
			
		||||
//
 | 
			
		||||
// To the extent possible under law, Yawning Angel has waived all copyright
 | 
			
		||||
// and related or neighboring rights to chacha20, using the Creative
 | 
			
		||||
// Commons "CC0" public domain dedication. See LICENSE or
 | 
			
		||||
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
 | 
			
		||||
// This program is free software: you can redistribute it and/or modify
 | 
			
		||||
// it under the terms of the GNU Affero General Public License as
 | 
			
		||||
// published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
// License, or (at your option) any later version.
 | 
			
		||||
//
 | 
			
		||||
// This program is distributed in the hope that it will be useful,
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
// GNU Affero General Public License for more details.
 | 
			
		||||
//
 | 
			
		||||
// You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
package chacha20
 | 
			
		||||
// Package chacha20 implements the ChaCha20 stream cipher.
 | 
			
		||||
package chacha20 // import "blitter.com/go/chacha20"
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"crypto/cipher"
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"math"
 | 
			
		||||
	"runtime"
 | 
			
		||||
 | 
			
		||||
	"blitter.com/go/chacha20/internal/api"
 | 
			
		||||
	"blitter.com/go/chacha20/internal/hardware"
 | 
			
		||||
	"blitter.com/go/chacha20/internal/ref"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
| 
						 | 
				
			
			@ -30,41 +42,29 @@ const (
 | 
			
		|||
 | 
			
		||||
	// HNonceSize is the HChaCha20 nonce size in bytes.
 | 
			
		||||
	HNonceSize = 16
 | 
			
		||||
 | 
			
		||||
	// BlockSize is the ChaCha20 block size in bytes.
 | 
			
		||||
	BlockSize = 64
 | 
			
		||||
 | 
			
		||||
	stateSize    = 16
 | 
			
		||||
	chachaRounds = 20
 | 
			
		||||
 | 
			
		||||
	// The constant "expand 32-byte k" as little endian uint32s.
 | 
			
		||||
	sigma0 = uint32(0x61707865)
 | 
			
		||||
	sigma1 = uint32(0x3320646e)
 | 
			
		||||
	sigma2 = uint32(0x79622d32)
 | 
			
		||||
	sigma3 = uint32(0x6b206574)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// ErrInvalidKey is the error returned when the key is invalid.
 | 
			
		||||
	ErrInvalidKey = errors.New("key length must be KeySize bytes")
 | 
			
		||||
	ErrInvalidKey = errors.New("chacha20: key length must be KeySize bytes")
 | 
			
		||||
 | 
			
		||||
	// ErrInvalidNonce is the error returned when the nonce is invalid.
 | 
			
		||||
	ErrInvalidNonce = errors.New("nonce length must be NonceSize/INonceSize/XNonceSize bytes")
 | 
			
		||||
	ErrInvalidNonce = errors.New("chacha20: nonce length must be NonceSize/INonceSize/XNonceSize bytes")
 | 
			
		||||
 | 
			
		||||
	// ErrInvalidCounter is the error returned when the counter is invalid.
 | 
			
		||||
	ErrInvalidCounter = errors.New("block counter is invalid (out of range)")
 | 
			
		||||
	ErrInvalidCounter = errors.New("chacha20: block counter is invalid (out of range)")
 | 
			
		||||
 | 
			
		||||
	useUnsafe    = false
 | 
			
		||||
	usingVectors = false
 | 
			
		||||
	blocksFn     = blocksRef
 | 
			
		||||
	supportedImpls []api.Implementation
 | 
			
		||||
	activeImpl     api.Implementation
 | 
			
		||||
 | 
			
		||||
	_ cipher.Stream = (*Cipher)(nil)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// A Cipher is an instance of ChaCha20/XChaCha20 using a particular key and
 | 
			
		||||
// nonce.
 | 
			
		||||
// Cipher is an instance of ChaCha20/XChaCha20 using a particular key and nonce.
 | 
			
		||||
type Cipher struct {
 | 
			
		||||
	state [stateSize]uint32
 | 
			
		||||
	state [api.StateSize]uint32
 | 
			
		||||
	buf   [api.BlockSize]byte
 | 
			
		||||
 | 
			
		||||
	buf  [BlockSize]byte
 | 
			
		||||
	off  int
 | 
			
		||||
	ietf bool
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -80,6 +80,99 @@ func (c *Cipher) Reset() {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Seek sets the block counter to a given offset.
 | 
			
		||||
func (c *Cipher) Seek(blockCounter uint64) error {
 | 
			
		||||
	if c.ietf {
 | 
			
		||||
		if blockCounter > math.MaxUint32 {
 | 
			
		||||
			return ErrInvalidCounter
 | 
			
		||||
		}
 | 
			
		||||
		c.state[12] = uint32(blockCounter)
 | 
			
		||||
	} else {
 | 
			
		||||
		c.state[12] = uint32(blockCounter)
 | 
			
		||||
		c.state[13] = uint32(blockCounter >> 32)
 | 
			
		||||
	}
 | 
			
		||||
	c.off = api.BlockSize
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ReKey reinitializes the ChaCha20/XChaCha20 instance with the provided key
 | 
			
		||||
// and nonce.
 | 
			
		||||
func (c *Cipher) ReKey(key, nonce []byte) error {
 | 
			
		||||
	c.Reset()
 | 
			
		||||
	return c.doReKey(key, nonce)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Cipher) doReKey(key, nonce []byte) error {
 | 
			
		||||
	if len(key) != KeySize {
 | 
			
		||||
		return ErrInvalidKey
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var subKey []byte
 | 
			
		||||
	switch len(nonce) {
 | 
			
		||||
	case NonceSize, INonceSize:
 | 
			
		||||
	case XNonceSize:
 | 
			
		||||
		subKey = c.buf[:KeySize]
 | 
			
		||||
		activeImpl.HChaCha(key, nonce, subKey)
 | 
			
		||||
		key = subKey
 | 
			
		||||
		nonce = nonce[16:24]
 | 
			
		||||
	default:
 | 
			
		||||
		return ErrInvalidNonce
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	_ = key[31] // Force bounds check elimination.
 | 
			
		||||
 | 
			
		||||
	c.state[0] = api.Sigma0
 | 
			
		||||
	c.state[1] = api.Sigma1
 | 
			
		||||
	c.state[2] = api.Sigma2
 | 
			
		||||
	c.state[3] = api.Sigma3
 | 
			
		||||
	c.state[4] = binary.LittleEndian.Uint32(key[0:4])
 | 
			
		||||
	c.state[5] = binary.LittleEndian.Uint32(key[4:8])
 | 
			
		||||
	c.state[6] = binary.LittleEndian.Uint32(key[8:12])
 | 
			
		||||
	c.state[7] = binary.LittleEndian.Uint32(key[12:16])
 | 
			
		||||
	c.state[8] = binary.LittleEndian.Uint32(key[16:20])
 | 
			
		||||
	c.state[9] = binary.LittleEndian.Uint32(key[20:24])
 | 
			
		||||
	c.state[10] = binary.LittleEndian.Uint32(key[24:28])
 | 
			
		||||
	c.state[11] = binary.LittleEndian.Uint32(key[28:32])
 | 
			
		||||
	c.state[12] = 0
 | 
			
		||||
	if len(nonce) == INonceSize {
 | 
			
		||||
		_ = nonce[11] // Force bounds check elimination.
 | 
			
		||||
		c.state[13] = binary.LittleEndian.Uint32(nonce[0:4])
 | 
			
		||||
		c.state[14] = binary.LittleEndian.Uint32(nonce[4:8])
 | 
			
		||||
		c.state[15] = binary.LittleEndian.Uint32(nonce[8:12])
 | 
			
		||||
		c.ietf = true
 | 
			
		||||
	} else {
 | 
			
		||||
		_ = nonce[7] // Force bounds check elimination.
 | 
			
		||||
		c.state[13] = 0
 | 
			
		||||
		c.state[14] = binary.LittleEndian.Uint32(nonce[0:4])
 | 
			
		||||
		c.state[15] = binary.LittleEndian.Uint32(nonce[4:8])
 | 
			
		||||
		c.ietf = false
 | 
			
		||||
	}
 | 
			
		||||
	c.off = api.BlockSize
 | 
			
		||||
 | 
			
		||||
	if subKey != nil {
 | 
			
		||||
		for i := range subKey {
 | 
			
		||||
			subKey[i] = 0
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// New returns a new ChaCha20/XChaCha20 instance.
 | 
			
		||||
func New(key, nonce []byte) (*Cipher, error) {
 | 
			
		||||
	var c Cipher
 | 
			
		||||
	if err := c.doReKey(key, nonce); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &c, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HChaCha is the HChaCha20 hash function used to make XChaCha.
 | 
			
		||||
func HChaCha(key, nonce []byte, dst *[32]byte) {
 | 
			
		||||
	activeImpl.HChaCha(key, nonce, dst[:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// XORKeyStream sets dst to the result of XORing src with the key stream.  Dst
 | 
			
		||||
// and src may be the same slice but otherwise should not overlap.
 | 
			
		||||
func (c *Cipher) XORKeyStream(dst, src []byte) {
 | 
			
		||||
| 
						 | 
				
			
			@ -89,11 +182,11 @@ func (c *Cipher) XORKeyStream(dst, src []byte) {
 | 
			
		|||
 | 
			
		||||
	for remaining := len(src); remaining > 0; {
 | 
			
		||||
		// Process multiple blocks at once.
 | 
			
		||||
		if c.off == BlockSize {
 | 
			
		||||
			nrBlocks := remaining / BlockSize
 | 
			
		||||
			directBytes := nrBlocks * BlockSize
 | 
			
		||||
		if c.off == api.BlockSize {
 | 
			
		||||
			nrBlocks := remaining / api.BlockSize
 | 
			
		||||
			directBytes := nrBlocks * api.BlockSize
 | 
			
		||||
			if nrBlocks > 0 {
 | 
			
		||||
				blocksFn(&c.state, src, dst, nrBlocks, c.ietf)
 | 
			
		||||
				c.doBlocks(dst, src, nrBlocks)
 | 
			
		||||
				remaining -= directBytes
 | 
			
		||||
				if remaining == 0 {
 | 
			
		||||
					return
 | 
			
		||||
| 
						 | 
				
			
			@ -104,37 +197,54 @@ func (c *Cipher) XORKeyStream(dst, src []byte) {
 | 
			
		|||
 | 
			
		||||
			// If there's a partial block, generate 1 block of keystream into
 | 
			
		||||
			// the internal buffer.
 | 
			
		||||
			blocksFn(&c.state, nil, c.buf[:], 1, c.ietf)
 | 
			
		||||
			c.doBlocks(c.buf[:], nil, 1)
 | 
			
		||||
			c.off = 0
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Process partial blocks from the buffered keystream.
 | 
			
		||||
		toXor := BlockSize - c.off
 | 
			
		||||
		toXor := api.BlockSize - c.off
 | 
			
		||||
		if remaining < toXor {
 | 
			
		||||
			toXor = remaining
 | 
			
		||||
		}
 | 
			
		||||
		if toXor > 0 {
 | 
			
		||||
			for i, v := range src[:toXor] {
 | 
			
		||||
				dst[i] = v ^ c.buf[c.off+i]
 | 
			
		||||
			}
 | 
			
		||||
			// The inliner doesn't want to inline this function, but my
 | 
			
		||||
			// attempts to force BCE don't seem to work with manual
 | 
			
		||||
			// inlining.
 | 
			
		||||
			//
 | 
			
		||||
			// Taking the extra function call overhead here appears to be
 | 
			
		||||
			// worth it.
 | 
			
		||||
			c.xorBufBytes(dst, src, toXor)
 | 
			
		||||
 | 
			
		||||
			dst = dst[toXor:]
 | 
			
		||||
			src = src[toXor:]
 | 
			
		||||
 | 
			
		||||
			remaining -= toXor
 | 
			
		||||
			c.off += toXor
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Cipher) xorBufBytes(dst, src []byte, n int) {
 | 
			
		||||
	// Force bounds check elimination.
 | 
			
		||||
	buf := c.buf[c.off:]
 | 
			
		||||
	_ = buf[n-1]
 | 
			
		||||
	_ = dst[n-1]
 | 
			
		||||
	_ = src[n-1]
 | 
			
		||||
 | 
			
		||||
	for i := 0; i < n; i++ {
 | 
			
		||||
		dst[i] = buf[i] ^ src[i]
 | 
			
		||||
	}
 | 
			
		||||
	c.off += n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// KeyStream sets dst to the raw keystream.
 | 
			
		||||
func (c *Cipher) KeyStream(dst []byte) {
 | 
			
		||||
	for remaining := len(dst); remaining > 0; {
 | 
			
		||||
		// Process multiple blocks at once.
 | 
			
		||||
		if c.off == BlockSize {
 | 
			
		||||
			nrBlocks := remaining / BlockSize
 | 
			
		||||
			directBytes := nrBlocks * BlockSize
 | 
			
		||||
		if c.off == api.BlockSize {
 | 
			
		||||
			nrBlocks := remaining / api.BlockSize
 | 
			
		||||
			directBytes := nrBlocks * api.BlockSize
 | 
			
		||||
			if nrBlocks > 0 {
 | 
			
		||||
				blocksFn(&c.state, nil, dst, nrBlocks, c.ietf)
 | 
			
		||||
				c.doBlocks(dst, nil, nrBlocks)
 | 
			
		||||
				remaining -= directBytes
 | 
			
		||||
				if remaining == 0 {
 | 
			
		||||
					return
 | 
			
		||||
| 
						 | 
				
			
			@ -144,12 +254,12 @@ func (c *Cipher) KeyStream(dst []byte) {
 | 
			
		|||
 | 
			
		||||
			// If there's a partial block, generate 1 block of keystream into
 | 
			
		||||
			// the internal buffer.
 | 
			
		||||
			blocksFn(&c.state, nil, c.buf[:], 1, c.ietf)
 | 
			
		||||
			c.doBlocks(c.buf[:], nil, 1)
 | 
			
		||||
			c.off = 0
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Process partial blocks from the buffered keystream.
 | 
			
		||||
		toCopy := BlockSize - c.off
 | 
			
		||||
		toCopy := api.BlockSize - c.off
 | 
			
		||||
		if remaining < toCopy {
 | 
			
		||||
			toCopy = remaining
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -162,112 +272,19 @@ func (c *Cipher) KeyStream(dst []byte) {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ReKey reinitializes the ChaCha20/XChaCha20 instance with the provided key
 | 
			
		||||
// and nonce.
 | 
			
		||||
func (c *Cipher) ReKey(key, nonce []byte) error {
 | 
			
		||||
	if len(key) != KeySize {
 | 
			
		||||
		return ErrInvalidKey
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch len(nonce) {
 | 
			
		||||
	case NonceSize:
 | 
			
		||||
	case INonceSize:
 | 
			
		||||
	case XNonceSize:
 | 
			
		||||
		var subkey [KeySize]byte
 | 
			
		||||
		var subnonce [HNonceSize]byte
 | 
			
		||||
		copy(subnonce[:], nonce[0:16])
 | 
			
		||||
		HChaCha(key, &subnonce, &subkey)
 | 
			
		||||
		key = subkey[:]
 | 
			
		||||
		nonce = nonce[16:24]
 | 
			
		||||
		defer func() {
 | 
			
		||||
			for i := range subkey {
 | 
			
		||||
				subkey[i] = 0
 | 
			
		||||
			}
 | 
			
		||||
		}()
 | 
			
		||||
	default:
 | 
			
		||||
		return ErrInvalidNonce
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.Reset()
 | 
			
		||||
	c.state[0] = sigma0
 | 
			
		||||
	c.state[1] = sigma1
 | 
			
		||||
	c.state[2] = sigma2
 | 
			
		||||
	c.state[3] = sigma3
 | 
			
		||||
	c.state[4] = binary.LittleEndian.Uint32(key[0:4])
 | 
			
		||||
	c.state[5] = binary.LittleEndian.Uint32(key[4:8])
 | 
			
		||||
	c.state[6] = binary.LittleEndian.Uint32(key[8:12])
 | 
			
		||||
	c.state[7] = binary.LittleEndian.Uint32(key[12:16])
 | 
			
		||||
	c.state[8] = binary.LittleEndian.Uint32(key[16:20])
 | 
			
		||||
	c.state[9] = binary.LittleEndian.Uint32(key[20:24])
 | 
			
		||||
	c.state[10] = binary.LittleEndian.Uint32(key[24:28])
 | 
			
		||||
	c.state[11] = binary.LittleEndian.Uint32(key[28:32])
 | 
			
		||||
	c.state[12] = 0
 | 
			
		||||
	if len(nonce) == INonceSize {
 | 
			
		||||
		c.state[13] = binary.LittleEndian.Uint32(nonce[0:4])
 | 
			
		||||
		c.state[14] = binary.LittleEndian.Uint32(nonce[4:8])
 | 
			
		||||
		c.state[15] = binary.LittleEndian.Uint32(nonce[8:12])
 | 
			
		||||
		c.ietf = true
 | 
			
		||||
	} else {
 | 
			
		||||
		c.state[13] = 0
 | 
			
		||||
		c.state[14] = binary.LittleEndian.Uint32(nonce[0:4])
 | 
			
		||||
		c.state[15] = binary.LittleEndian.Uint32(nonce[4:8])
 | 
			
		||||
		c.ietf = false
 | 
			
		||||
	}
 | 
			
		||||
	c.off = BlockSize
 | 
			
		||||
	return nil
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Seek sets the block counter to a given offset.
 | 
			
		||||
func (c *Cipher) Seek(blockCounter uint64) error {
 | 
			
		||||
func (c *Cipher) doBlocks(dst, src []byte, nrBlocks int) {
 | 
			
		||||
	if c.ietf {
 | 
			
		||||
		if blockCounter > math.MaxUint32 {
 | 
			
		||||
			return ErrInvalidCounter
 | 
			
		||||
		ctr := uint64(c.state[12])
 | 
			
		||||
		if ctr+uint64(nrBlocks) > math.MaxUint32 {
 | 
			
		||||
			panic("chacha20: will exceed key stream per nonce limit")
 | 
			
		||||
		}
 | 
			
		||||
		c.state[12] = uint32(blockCounter)
 | 
			
		||||
	} else {
 | 
			
		||||
		c.state[12] = uint32(blockCounter)
 | 
			
		||||
		c.state[13] = uint32(blockCounter >> 32)
 | 
			
		||||
	}
 | 
			
		||||
	c.off = BlockSize
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewCipher returns a new ChaCha20/XChaCha20 instance.
 | 
			
		||||
func NewCipher(key, nonce []byte) (*Cipher, error) {
 | 
			
		||||
	c := new(Cipher)
 | 
			
		||||
	if err := c.ReKey(key, nonce); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return c, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// HChaCha is the HChaCha20 hash function used to make XChaCha.
 | 
			
		||||
func HChaCha(key []byte, nonce *[HNonceSize]byte, out *[32]byte) {
 | 
			
		||||
	var x [stateSize]uint32 // Last 4 slots unused, sigma hardcoded.
 | 
			
		||||
	x[0] = binary.LittleEndian.Uint32(key[0:4])
 | 
			
		||||
	x[1] = binary.LittleEndian.Uint32(key[4:8])
 | 
			
		||||
	x[2] = binary.LittleEndian.Uint32(key[8:12])
 | 
			
		||||
	x[3] = binary.LittleEndian.Uint32(key[12:16])
 | 
			
		||||
	x[4] = binary.LittleEndian.Uint32(key[16:20])
 | 
			
		||||
	x[5] = binary.LittleEndian.Uint32(key[20:24])
 | 
			
		||||
	x[6] = binary.LittleEndian.Uint32(key[24:28])
 | 
			
		||||
	x[7] = binary.LittleEndian.Uint32(key[28:32])
 | 
			
		||||
	x[8] = binary.LittleEndian.Uint32(nonce[0:4])
 | 
			
		||||
	x[9] = binary.LittleEndian.Uint32(nonce[4:8])
 | 
			
		||||
	x[10] = binary.LittleEndian.Uint32(nonce[8:12])
 | 
			
		||||
	x[11] = binary.LittleEndian.Uint32(nonce[12:16])
 | 
			
		||||
	hChaChaRef(&x, out)
 | 
			
		||||
	activeImpl.Blocks(&c.state, dst, src, nrBlocks)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	switch runtime.GOARCH {
 | 
			
		||||
	case "386", "amd64":
 | 
			
		||||
		// Abuse unsafe to skip calling binary.LittleEndian.PutUint32
 | 
			
		||||
		// in the critical path.  This is a big boost on systems that are
 | 
			
		||||
		// little endian and not overly picky about alignment.
 | 
			
		||||
		useUnsafe = true
 | 
			
		||||
	}
 | 
			
		||||
	supportedImpls = hardware.Register(supportedImpls)
 | 
			
		||||
	supportedImpls = ref.Register(supportedImpls)
 | 
			
		||||
	activeImpl = supportedImpls[0]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ cipher.Stream = (*Cipher)(nil)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
module blitter.com/go/chacha20
 | 
			
		||||
 | 
			
		||||
go 1.12
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	github.com/stretchr/testify v1.4.0
 | 
			
		||||
	golang.org/x/sys v0.0.0-20190902133755-9109b7679e13
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
 | 
			
		||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
			
		||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 | 
			
		||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
			
		||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 | 
			
		||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
 | 
			
		||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190902133755-9109b7679e13 h1:tdsQdquKbTNMsSZLqnLELJGzCANp9oXhu6zFBW6ODx4=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
			
		||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 | 
			
		||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,59 @@
 | 
			
		|||
// Copryright (C) 2019 Yawning Angel
 | 
			
		||||
//
 | 
			
		||||
// This program is free software: you can redistribute it and/or modify
 | 
			
		||||
// it under the terms of the GNU Affero General Public License as
 | 
			
		||||
// published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
// License, or (at your option) any later version.
 | 
			
		||||
//
 | 
			
		||||
// This program is distributed in the hope that it will be useful,
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
// GNU Affero General Public License for more details.
 | 
			
		||||
//
 | 
			
		||||
// You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
// Package api provides the ChaCha20 implementation abstract interface.
 | 
			
		||||
package api
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// BlockSize is the size of a ChaCha20 block in bytes.
 | 
			
		||||
	BlockSize = 64
 | 
			
		||||
 | 
			
		||||
	// StateSize is the size of the ChaCha20 state as 32 bit unsigned words.
 | 
			
		||||
	StateSize = 16
 | 
			
		||||
 | 
			
		||||
	// HashSize is the size of the HChaCha output in bytes.
 | 
			
		||||
	HashSize = 32
 | 
			
		||||
 | 
			
		||||
	// HNonceSize is the HChaCha20 nonce size in bytes.
 | 
			
		||||
	HNonceSize = 16
 | 
			
		||||
 | 
			
		||||
	// Sigma0 is the first word of the ChaCha constant.
 | 
			
		||||
	Sigma0 = uint32(0x61707865)
 | 
			
		||||
 | 
			
		||||
	// Sigma1 is the second word of the ChaCha constant.
 | 
			
		||||
	Sigma1 = uint32(0x3320646e)
 | 
			
		||||
 | 
			
		||||
	// Sigma2 is the third word of the ChaCha constant.
 | 
			
		||||
	Sigma2 = uint32(0x79622d32)
 | 
			
		||||
 | 
			
		||||
	// Sigma3 is the fourth word of the ChaCha constant.
 | 
			
		||||
	Sigma3 = uint32(0x6b206574)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Implementation is a ChaCha20 implementation
 | 
			
		||||
type Implementation interface {
 | 
			
		||||
	// Name returns the name of the implementation.
 | 
			
		||||
	Name() string
 | 
			
		||||
 | 
			
		||||
	// Blocks calculates the ChaCha20 blocks.  If src is not nil, dst will
 | 
			
		||||
	// be set to the XOR of src with the key stream, otherwise dst will be
 | 
			
		||||
	// set to the key stream.
 | 
			
		||||
	Blocks(x *[StateSize]uint32, dst, src []byte, nrBlocks int)
 | 
			
		||||
 | 
			
		||||
	// HChaCha calculates the HChaCha20 hash.
 | 
			
		||||
	//
 | 
			
		||||
	// Note: `dst` is guaranteed to be HashSize bytes.
 | 
			
		||||
	HChaCha(key, nonce []byte, dst []byte)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
// Copryright (C) 2019 Yawning Angel
 | 
			
		||||
//
 | 
			
		||||
// This program is free software: you can redistribute it and/or modify
 | 
			
		||||
// it under the terms of the GNU Affero General Public License as
 | 
			
		||||
// published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
// License, or (at your option) any later version.
 | 
			
		||||
//
 | 
			
		||||
// This program is distributed in the hope that it will be useful,
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
// GNU Affero General Public License for more details.
 | 
			
		||||
//
 | 
			
		||||
// You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
// Package hardware provides the hardware accelerated ChaCha20 implementations.
 | 
			
		||||
package hardware
 | 
			
		||||
 | 
			
		||||
import "blitter.com/go/chacha20/internal/api"
 | 
			
		||||
 | 
			
		||||
var hardwareImpls []api.Implementation
 | 
			
		||||
 | 
			
		||||
// Register appends the implementation(s) to the provided slice, and returns the
 | 
			
		||||
// new slice.
 | 
			
		||||
func Register(impls []api.Implementation) []api.Implementation {
 | 
			
		||||
	return append(impls, hardwareImpls...)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,88 @@
 | 
			
		|||
// Copryright (C) 2019 Yawning Angel
 | 
			
		||||
//
 | 
			
		||||
// This program is free software: you can redistribute it and/or modify
 | 
			
		||||
// it under the terms of the GNU Affero General Public License as
 | 
			
		||||
// published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
// License, or (at your option) any later version.
 | 
			
		||||
//
 | 
			
		||||
// This program is distributed in the hope that it will be useful,
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
// GNU Affero General Public License for more details.
 | 
			
		||||
//
 | 
			
		||||
// You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
// +build amd64,!noasm
 | 
			
		||||
 | 
			
		||||
package hardware
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"golang.org/x/sys/cpu"
 | 
			
		||||
 | 
			
		||||
	"blitter.com/go/chacha20/internal/api"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//go:noescape
 | 
			
		||||
func blocksAVX2(s *[api.StateSize]uint32, in, out []byte)
 | 
			
		||||
 | 
			
		||||
//go:noescape
 | 
			
		||||
func hChaChaAVX2(key, nonce []byte, dst *byte)
 | 
			
		||||
 | 
			
		||||
//go:noescape
 | 
			
		||||
func blocksSSSE3(s *[api.StateSize]uint32, in, out []byte)
 | 
			
		||||
 | 
			
		||||
//go:noescape
 | 
			
		||||
func hChaChaSSSE3(key, nonce []byte, dst *byte)
 | 
			
		||||
 | 
			
		||||
type implAmd64 struct {
 | 
			
		||||
	name string
 | 
			
		||||
 | 
			
		||||
	blocksFn  func(*[api.StateSize]uint32, []byte, []byte, int)
 | 
			
		||||
	hChaChaFn func([]byte, []byte, *byte)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (impl *implAmd64) Name() string {
 | 
			
		||||
	return impl.name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (impl *implAmd64) Blocks(x *[api.StateSize]uint32, dst, src []byte, nrBlocks int) {
 | 
			
		||||
	impl.blocksFn(x, dst, src, nrBlocks)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (impl *implAmd64) HChaCha(key, nonce []byte, dst []byte) {
 | 
			
		||||
	impl.hChaChaFn(key, nonce, &dst[0])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func blockWrapper(fn func(*[api.StateSize]uint32, []byte, []byte)) func(*[api.StateSize]uint32, []byte, []byte, int) {
 | 
			
		||||
	return func(x *[api.StateSize]uint32, dst, src []byte, nrBlocks int) {
 | 
			
		||||
		sz := nrBlocks * api.BlockSize
 | 
			
		||||
		if src != nil {
 | 
			
		||||
			fn(x, src[:sz], dst[:sz])
 | 
			
		||||
		} else {
 | 
			
		||||
			// Sub-optimal, but the compiler special cases this to an assembly
 | 
			
		||||
			// optimized runtime.memclrNoHeapPointers, so it's not terrible.
 | 
			
		||||
			for i := range dst[:sz] {
 | 
			
		||||
				dst[i] = 0
 | 
			
		||||
			}
 | 
			
		||||
			fn(x, dst[:sz], dst[:sz])
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	if cpu.X86.HasAVX2 {
 | 
			
		||||
		hardwareImpls = append(hardwareImpls, &implAmd64{
 | 
			
		||||
			name:      "amd64_avx2",
 | 
			
		||||
			blocksFn:  blockWrapper(blocksAVX2),
 | 
			
		||||
			hChaChaFn: hChaChaAVX2,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
	if cpu.X86.HasSSE3 {
 | 
			
		||||
		hardwareImpls = append(hardwareImpls, &implAmd64{
 | 
			
		||||
			name:      "amd64_ssse3",
 | 
			
		||||
			blocksFn:  blockWrapper(blocksSSSE3),
 | 
			
		||||
			hChaChaFn: hChaChaSSSE3,
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1,374 @@
 | 
			
		|||
// Copryright (C) 2019 Yawning Angel
 | 
			
		||||
//
 | 
			
		||||
// This program is free software: you can redistribute it and/or modify
 | 
			
		||||
// it under the terms of the GNU Affero General Public License as
 | 
			
		||||
// published by the Free Software Foundation, either version 3 of the
 | 
			
		||||
// License, or (at your option) any later version.
 | 
			
		||||
//
 | 
			
		||||
// This program is distributed in the hope that it will be useful,
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
// GNU Affero General Public License for more details.
 | 
			
		||||
//
 | 
			
		||||
// You should have received a copy of the GNU Affero General Public License
 | 
			
		||||
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
// Package ref provides the portable ChaCha20 implementation.
 | 
			
		||||
package ref
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"math/bits"
 | 
			
		||||
 | 
			
		||||
	"blitter.com/go/chacha20/internal/api"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const rounds = 20
 | 
			
		||||
 | 
			
		||||
// Impl is the reference implementation (exposed for testing).
 | 
			
		||||
var Impl = &implRef{}
 | 
			
		||||
 | 
			
		||||
type implRef struct{}
 | 
			
		||||
 | 
			
		||||
func (impl *implRef) Name() string {
 | 
			
		||||
	return "ref"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (impl *implRef) Blocks(x *[api.StateSize]uint32, dst, src []byte, nrBlocks int) {
 | 
			
		||||
	for n := 0; n < nrBlocks; n++ {
 | 
			
		||||
		x0, x1, x2, x3 := api.Sigma0, api.Sigma1, api.Sigma2, api.Sigma3
 | 
			
		||||
		x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 := x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15]
 | 
			
		||||
 | 
			
		||||
		for i := rounds; i > 0; i -= 2 {
 | 
			
		||||
			// quarterround(x, 0, 4, 8, 12)
 | 
			
		||||
			x0 += x4
 | 
			
		||||
			x12 ^= x0
 | 
			
		||||
			x12 = bits.RotateLeft32(x12, 16)
 | 
			
		||||
			x8 += x12
 | 
			
		||||
			x4 ^= x8
 | 
			
		||||
			x4 = bits.RotateLeft32(x4, 12)
 | 
			
		||||
			x0 += x4
 | 
			
		||||
			x12 ^= x0
 | 
			
		||||
			x12 = bits.RotateLeft32(x12, 8)
 | 
			
		||||
			x8 += x12
 | 
			
		||||
			x4 ^= x8
 | 
			
		||||
			x4 = bits.RotateLeft32(x4, 7)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 1, 5, 9, 13)
 | 
			
		||||
			x1 += x5
 | 
			
		||||
			x13 ^= x1
 | 
			
		||||
			x13 = bits.RotateLeft32(x13, 16)
 | 
			
		||||
			x9 += x13
 | 
			
		||||
			x5 ^= x9
 | 
			
		||||
			x5 = bits.RotateLeft32(x5, 12)
 | 
			
		||||
			x1 += x5
 | 
			
		||||
			x13 ^= x1
 | 
			
		||||
			x13 = bits.RotateLeft32(x13, 8)
 | 
			
		||||
			x9 += x13
 | 
			
		||||
			x5 ^= x9
 | 
			
		||||
			x5 = bits.RotateLeft32(x5, 7)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 2, 6, 10, 14)
 | 
			
		||||
			x2 += x6
 | 
			
		||||
			x14 ^= x2
 | 
			
		||||
			x14 = bits.RotateLeft32(x14, 16)
 | 
			
		||||
			x10 += x14
 | 
			
		||||
			x6 ^= x10
 | 
			
		||||
			x6 = bits.RotateLeft32(x6, 12)
 | 
			
		||||
			x2 += x6
 | 
			
		||||
			x14 ^= x2
 | 
			
		||||
			x14 = bits.RotateLeft32(x14, 8)
 | 
			
		||||
			x10 += x14
 | 
			
		||||
			x6 ^= x10
 | 
			
		||||
			x6 = bits.RotateLeft32(x6, 7)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 3, 7, 11, 15)
 | 
			
		||||
			x3 += x7
 | 
			
		||||
			x15 ^= x3
 | 
			
		||||
			x15 = bits.RotateLeft32(x15, 16)
 | 
			
		||||
			x11 += x15
 | 
			
		||||
			x7 ^= x11
 | 
			
		||||
			x7 = bits.RotateLeft32(x7, 12)
 | 
			
		||||
			x3 += x7
 | 
			
		||||
			x15 ^= x3
 | 
			
		||||
			x15 = bits.RotateLeft32(x15, 8)
 | 
			
		||||
			x11 += x15
 | 
			
		||||
			x7 ^= x11
 | 
			
		||||
			x7 = bits.RotateLeft32(x7, 7)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 0, 5, 10, 15)
 | 
			
		||||
			x0 += x5
 | 
			
		||||
			x15 ^= x0
 | 
			
		||||
			x15 = bits.RotateLeft32(x15, 16)
 | 
			
		||||
			x10 += x15
 | 
			
		||||
			x5 ^= x10
 | 
			
		||||
			x5 = bits.RotateLeft32(x5, 12)
 | 
			
		||||
			x0 += x5
 | 
			
		||||
			x15 ^= x0
 | 
			
		||||
			x15 = bits.RotateLeft32(x15, 8)
 | 
			
		||||
			x10 += x15
 | 
			
		||||
			x5 ^= x10
 | 
			
		||||
			x5 = bits.RotateLeft32(x5, 7)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 1, 6, 11, 12)
 | 
			
		||||
			x1 += x6
 | 
			
		||||
			x12 ^= x1
 | 
			
		||||
			x12 = bits.RotateLeft32(x12, 16)
 | 
			
		||||
			x11 += x12
 | 
			
		||||
			x6 ^= x11
 | 
			
		||||
			x6 = bits.RotateLeft32(x6, 12)
 | 
			
		||||
			x1 += x6
 | 
			
		||||
			x12 ^= x1
 | 
			
		||||
			x12 = bits.RotateLeft32(x12, 8)
 | 
			
		||||
			x11 += x12
 | 
			
		||||
			x6 ^= x11
 | 
			
		||||
			x6 = bits.RotateLeft32(x6, 7)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 2, 7, 8, 13)
 | 
			
		||||
			x2 += x7
 | 
			
		||||
			x13 ^= x2
 | 
			
		||||
			x13 = bits.RotateLeft32(x13, 16)
 | 
			
		||||
			x8 += x13
 | 
			
		||||
			x7 ^= x8
 | 
			
		||||
			x7 = bits.RotateLeft32(x7, 12)
 | 
			
		||||
			x2 += x7
 | 
			
		||||
			x13 ^= x2
 | 
			
		||||
			x13 = bits.RotateLeft32(x13, 8)
 | 
			
		||||
			x8 += x13
 | 
			
		||||
			x7 ^= x8
 | 
			
		||||
			x7 = bits.RotateLeft32(x7, 7)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 3, 4, 9, 14)
 | 
			
		||||
			x3 += x4
 | 
			
		||||
			x14 ^= x3
 | 
			
		||||
			x14 = bits.RotateLeft32(x14, 16)
 | 
			
		||||
			x9 += x14
 | 
			
		||||
			x4 ^= x9
 | 
			
		||||
			x4 = bits.RotateLeft32(x4, 12)
 | 
			
		||||
			x3 += x4
 | 
			
		||||
			x14 ^= x3
 | 
			
		||||
			x14 = bits.RotateLeft32(x14, 8)
 | 
			
		||||
			x9 += x14
 | 
			
		||||
			x4 ^= x9
 | 
			
		||||
			x4 = bits.RotateLeft32(x4, 7)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		x0 += api.Sigma0
 | 
			
		||||
		x1 += api.Sigma1
 | 
			
		||||
		x2 += api.Sigma2
 | 
			
		||||
		x3 += api.Sigma3
 | 
			
		||||
		x4 += x[4]
 | 
			
		||||
		x5 += x[5]
 | 
			
		||||
		x6 += x[6]
 | 
			
		||||
		x7 += x[7]
 | 
			
		||||
		x8 += x[8]
 | 
			
		||||
		x9 += x[9]
 | 
			
		||||
		x10 += x[10]
 | 
			
		||||
		x11 += x[11]
 | 
			
		||||
		x12 += x[12]
 | 
			
		||||
		x13 += x[13]
 | 
			
		||||
		x14 += x[14]
 | 
			
		||||
		x15 += x[15]
 | 
			
		||||
 | 
			
		||||
		_ = dst[api.BlockSize-1] // Force bounds check elimination.
 | 
			
		||||
 | 
			
		||||
		if src != nil {
 | 
			
		||||
			_ = src[api.BlockSize-1] // Force bounds check elimination.
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[0:4], binary.LittleEndian.Uint32(src[0:4])^x0)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[4:8], binary.LittleEndian.Uint32(src[4:8])^x1)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[8:12], binary.LittleEndian.Uint32(src[8:12])^x2)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[12:16], binary.LittleEndian.Uint32(src[12:16])^x3)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[16:20], binary.LittleEndian.Uint32(src[16:20])^x4)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[20:24], binary.LittleEndian.Uint32(src[20:24])^x5)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[24:28], binary.LittleEndian.Uint32(src[24:28])^x6)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[28:32], binary.LittleEndian.Uint32(src[28:32])^x7)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[32:36], binary.LittleEndian.Uint32(src[32:36])^x8)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[36:40], binary.LittleEndian.Uint32(src[36:40])^x9)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[40:44], binary.LittleEndian.Uint32(src[40:44])^x10)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[44:48], binary.LittleEndian.Uint32(src[44:48])^x11)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[48:52], binary.LittleEndian.Uint32(src[48:52])^x12)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[52:56], binary.LittleEndian.Uint32(src[52:56])^x13)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[56:60], binary.LittleEndian.Uint32(src[56:60])^x14)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[60:64], binary.LittleEndian.Uint32(src[60:64])^x15)
 | 
			
		||||
			src = src[api.BlockSize:]
 | 
			
		||||
		} else {
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[0:4], x0)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[4:8], x1)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[8:12], x2)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[12:16], x3)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[16:20], x4)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[20:24], x5)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[24:28], x6)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[28:32], x7)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[32:36], x8)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[36:40], x9)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[40:44], x10)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[44:48], x11)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[48:52], x12)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[52:56], x13)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[56:60], x14)
 | 
			
		||||
			binary.LittleEndian.PutUint32(dst[60:64], x15)
 | 
			
		||||
		}
 | 
			
		||||
		dst = dst[api.BlockSize:]
 | 
			
		||||
 | 
			
		||||
		// Stoping at 2^70 bytes per nonce is the user's responsibility.
 | 
			
		||||
		ctr := uint64(x[13])<<32 | uint64(x[12])
 | 
			
		||||
		ctr++
 | 
			
		||||
		x[12] = uint32(ctr)
 | 
			
		||||
		x[13] = uint32(ctr >> 32)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (impl *implRef) HChaCha(key, nonce []byte, dst []byte) {
 | 
			
		||||
	// Force bounds check elimination.
 | 
			
		||||
	_ = key[31]
 | 
			
		||||
	_ = nonce[api.HNonceSize-1]
 | 
			
		||||
 | 
			
		||||
	x0, x1, x2, x3 := api.Sigma0, api.Sigma1, api.Sigma2, api.Sigma3
 | 
			
		||||
	x4 := binary.LittleEndian.Uint32(key[0:4])
 | 
			
		||||
	x5 := binary.LittleEndian.Uint32(key[4:8])
 | 
			
		||||
	x6 := binary.LittleEndian.Uint32(key[8:12])
 | 
			
		||||
	x7 := binary.LittleEndian.Uint32(key[12:16])
 | 
			
		||||
	x8 := binary.LittleEndian.Uint32(key[16:20])
 | 
			
		||||
	x9 := binary.LittleEndian.Uint32(key[20:24])
 | 
			
		||||
	x10 := binary.LittleEndian.Uint32(key[24:28])
 | 
			
		||||
	x11 := binary.LittleEndian.Uint32(key[28:32])
 | 
			
		||||
	x12 := binary.LittleEndian.Uint32(nonce[0:4])
 | 
			
		||||
	x13 := binary.LittleEndian.Uint32(nonce[4:8])
 | 
			
		||||
	x14 := binary.LittleEndian.Uint32(nonce[8:12])
 | 
			
		||||
	x15 := binary.LittleEndian.Uint32(nonce[12:16])
 | 
			
		||||
 | 
			
		||||
	// Yes, this could be carved out into a function for code reuse (TM)
 | 
			
		||||
	// however the go inliner won't inline it.
 | 
			
		||||
	for i := rounds; i > 0; i -= 2 {
 | 
			
		||||
		// quarterround(x, 0, 4, 8, 12)
 | 
			
		||||
		x0 += x4
 | 
			
		||||
		x12 ^= x0
 | 
			
		||||
		x12 = bits.RotateLeft32(x12, 16)
 | 
			
		||||
		x8 += x12
 | 
			
		||||
		x4 ^= x8
 | 
			
		||||
		x4 = bits.RotateLeft32(x4, 12)
 | 
			
		||||
		x0 += x4
 | 
			
		||||
		x12 ^= x0
 | 
			
		||||
		x12 = bits.RotateLeft32(x12, 8)
 | 
			
		||||
		x8 += x12
 | 
			
		||||
		x4 ^= x8
 | 
			
		||||
		x4 = bits.RotateLeft32(x4, 7)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 1, 5, 9, 13)
 | 
			
		||||
		x1 += x5
 | 
			
		||||
		x13 ^= x1
 | 
			
		||||
		x13 = bits.RotateLeft32(x13, 16)
 | 
			
		||||
		x9 += x13
 | 
			
		||||
		x5 ^= x9
 | 
			
		||||
		x5 = bits.RotateLeft32(x5, 12)
 | 
			
		||||
		x1 += x5
 | 
			
		||||
		x13 ^= x1
 | 
			
		||||
		x13 = bits.RotateLeft32(x13, 8)
 | 
			
		||||
		x9 += x13
 | 
			
		||||
		x5 ^= x9
 | 
			
		||||
		x5 = bits.RotateLeft32(x5, 7)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 2, 6, 10, 14)
 | 
			
		||||
		x2 += x6
 | 
			
		||||
		x14 ^= x2
 | 
			
		||||
		x14 = bits.RotateLeft32(x14, 16)
 | 
			
		||||
		x10 += x14
 | 
			
		||||
		x6 ^= x10
 | 
			
		||||
		x6 = bits.RotateLeft32(x6, 12)
 | 
			
		||||
		x2 += x6
 | 
			
		||||
		x14 ^= x2
 | 
			
		||||
		x14 = bits.RotateLeft32(x14, 8)
 | 
			
		||||
		x10 += x14
 | 
			
		||||
		x6 ^= x10
 | 
			
		||||
		x6 = bits.RotateLeft32(x6, 7)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 3, 7, 11, 15)
 | 
			
		||||
		x3 += x7
 | 
			
		||||
		x15 ^= x3
 | 
			
		||||
		x15 = bits.RotateLeft32(x15, 16)
 | 
			
		||||
		x11 += x15
 | 
			
		||||
		x7 ^= x11
 | 
			
		||||
		x7 = bits.RotateLeft32(x7, 12)
 | 
			
		||||
		x3 += x7
 | 
			
		||||
		x15 ^= x3
 | 
			
		||||
		x15 = bits.RotateLeft32(x15, 8)
 | 
			
		||||
		x11 += x15
 | 
			
		||||
		x7 ^= x11
 | 
			
		||||
		x7 = bits.RotateLeft32(x7, 7)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 0, 5, 10, 15)
 | 
			
		||||
		x0 += x5
 | 
			
		||||
		x15 ^= x0
 | 
			
		||||
		x15 = bits.RotateLeft32(x15, 16)
 | 
			
		||||
		x10 += x15
 | 
			
		||||
		x5 ^= x10
 | 
			
		||||
		x5 = bits.RotateLeft32(x5, 12)
 | 
			
		||||
		x0 += x5
 | 
			
		||||
		x15 ^= x0
 | 
			
		||||
		x15 = bits.RotateLeft32(x15, 8)
 | 
			
		||||
		x10 += x15
 | 
			
		||||
		x5 ^= x10
 | 
			
		||||
		x5 = bits.RotateLeft32(x5, 7)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 1, 6, 11, 12)
 | 
			
		||||
		x1 += x6
 | 
			
		||||
		x12 ^= x1
 | 
			
		||||
		x12 = bits.RotateLeft32(x12, 16)
 | 
			
		||||
		x11 += x12
 | 
			
		||||
		x6 ^= x11
 | 
			
		||||
		x6 = bits.RotateLeft32(x6, 12)
 | 
			
		||||
		x1 += x6
 | 
			
		||||
		x12 ^= x1
 | 
			
		||||
		x12 = bits.RotateLeft32(x12, 8)
 | 
			
		||||
		x11 += x12
 | 
			
		||||
		x6 ^= x11
 | 
			
		||||
		x6 = bits.RotateLeft32(x6, 7)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 2, 7, 8, 13)
 | 
			
		||||
		x2 += x7
 | 
			
		||||
		x13 ^= x2
 | 
			
		||||
		x13 = bits.RotateLeft32(x13, 16)
 | 
			
		||||
		x8 += x13
 | 
			
		||||
		x7 ^= x8
 | 
			
		||||
		x7 = bits.RotateLeft32(x7, 12)
 | 
			
		||||
		x2 += x7
 | 
			
		||||
		x13 ^= x2
 | 
			
		||||
		x13 = bits.RotateLeft32(x13, 8)
 | 
			
		||||
		x8 += x13
 | 
			
		||||
		x7 ^= x8
 | 
			
		||||
		x7 = bits.RotateLeft32(x7, 7)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 3, 4, 9, 14)
 | 
			
		||||
		x3 += x4
 | 
			
		||||
		x14 ^= x3
 | 
			
		||||
		x14 = bits.RotateLeft32(x14, 16)
 | 
			
		||||
		x9 += x14
 | 
			
		||||
		x4 ^= x9
 | 
			
		||||
		x4 = bits.RotateLeft32(x4, 12)
 | 
			
		||||
		x3 += x4
 | 
			
		||||
		x14 ^= x3
 | 
			
		||||
		x14 = bits.RotateLeft32(x14, 8)
 | 
			
		||||
		x9 += x14
 | 
			
		||||
		x4 ^= x9
 | 
			
		||||
		x4 = bits.RotateLeft32(x4, 7)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// HChaCha returns x0...x3 | x12...x15, which corresponds to the
 | 
			
		||||
	// indexes of the ChaCha constant and the indexes of the IV.
 | 
			
		||||
	_ = dst[api.HashSize-1] // Force bounds check elimination.
 | 
			
		||||
	binary.LittleEndian.PutUint32(dst[0:4], x0)
 | 
			
		||||
	binary.LittleEndian.PutUint32(dst[4:8], x1)
 | 
			
		||||
	binary.LittleEndian.PutUint32(dst[8:12], x2)
 | 
			
		||||
	binary.LittleEndian.PutUint32(dst[12:16], x3)
 | 
			
		||||
	binary.LittleEndian.PutUint32(dst[16:20], x12)
 | 
			
		||||
	binary.LittleEndian.PutUint32(dst[20:24], x13)
 | 
			
		||||
	binary.LittleEndian.PutUint32(dst[24:28], x14)
 | 
			
		||||
	binary.LittleEndian.PutUint32(dst[28:32], x15)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Register appends the implementation to the provided slice, and returns the
 | 
			
		||||
// new slice.
 | 
			
		||||
func Register(impls []api.Implementation) []api.Implementation {
 | 
			
		||||
	return append(impls, Impl)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
module blitter.com/go/kyber
 | 
			
		||||
 | 
			
		||||
go 1.12
 | 
			
		||||
 | 
			
		||||
require golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 | 
			
		||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		||||
| 
						 | 
				
			
			@ -7,7 +7,7 @@
 | 
			
		|||
 | 
			
		||||
package newhope
 | 
			
		||||
 | 
			
		||||
import "git.schwanenlied.me/yawning/chacha20.git"
 | 
			
		||||
import "blitter.com/go/chacha20"
 | 
			
		||||
 | 
			
		||||
func abs(v int32) int32 {
 | 
			
		||||
	mask := v >> 31
 | 
			
		||||
| 
						 | 
				
			
			@ -73,7 +73,7 @@ func (c *poly) helpRec(v *poly, seed *[SeedBytes]byte, nonce byte) {
 | 
			
		|||
 | 
			
		||||
	n[7] = nonce
 | 
			
		||||
 | 
			
		||||
	stream, err := chacha20.NewCipher(seed[:], n[:])
 | 
			
		||||
	stream, err := chacha20.New(seed[:], n[:])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
module blitter.com/go/newhope
 | 
			
		||||
 | 
			
		||||
go 1.12
 | 
			
		||||
 | 
			
		||||
require (
 | 
			
		||||
	blitter.com/go/chacha20 v0.0.0-20200130200441-214e4085f54c
 | 
			
		||||
	golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
blitter.com/go/chacha20 v0.0.0-20200130200441-214e4085f54c h1:LcnFFg6MCIJHf26P7eOUST45fNLHJI5erq0gWZaDLCo=
 | 
			
		||||
blitter.com/go/chacha20 v0.0.0-20200130200441-214e4085f54c/go.mod h1:EMJtRcf22WCtHGiXCw+NB/Sb/PYcXtUgUql6LDEwyXo=
 | 
			
		||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
			
		||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
			
		||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 | 
			
		||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 | 
			
		||||
gitlab.com/yawning/chacha20.git v0.0.0-20190902183103-644b09ac4e6e h1:QhupcTDYYRrhIY0f5Ad5v/nU8lJWjzzN6qQu1ndOm0c=
 | 
			
		||||
gitlab.com/yawning/chacha20.git v0.0.0-20190902183103-644b09ac4e6e/go.mod h1:3x6b94nWCP/a2XB/joOPMiGYUBvqbLfeY/BkHLeDs6s=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 | 
			
		||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190902133755-9109b7679e13 h1:tdsQdquKbTNMsSZLqnLELJGzCANp9oXhu6zFBW6ODx4=
 | 
			
		||||
golang.org/x/sys v0.0.0-20190902133755-9109b7679e13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
			
		||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
			
		||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
			
		||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
			
		||||
| 
						 | 
				
			
			@ -10,7 +10,7 @@ package newhope
 | 
			
		|||
import (
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
 | 
			
		||||
	"git.schwanenlied.me/yawning/chacha20.git"
 | 
			
		||||
	"blitter.com/go/chacha20"
 | 
			
		||||
	"golang.org/x/crypto/sha3"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -115,8 +115,8 @@ func (p *poly) uniform(seed *[SeedBytes]byte, torSampling bool) {
 | 
			
		|||
 | 
			
		||||
		// h and buf are left unscrubbed because the output is public.
 | 
			
		||||
		h := sha3.NewShake128()
 | 
			
		||||
		h.Write(seed[:])
 | 
			
		||||
		h.Read(buf[:])
 | 
			
		||||
		_, _ = h.Write(seed[:])
 | 
			
		||||
		_, _ = h.Read(buf[:])
 | 
			
		||||
 | 
			
		||||
		for ctr, pos := 0, 0; ctr < paramN; {
 | 
			
		||||
			val := binary.LittleEndian.Uint16(buf[pos:])
 | 
			
		||||
| 
						 | 
				
			
			@ -128,7 +128,7 @@ func (p *poly) uniform(seed *[SeedBytes]byte, torSampling bool) {
 | 
			
		|||
			pos += 2
 | 
			
		||||
			if pos > shake128Rate*nBlocks-2 {
 | 
			
		||||
				nBlocks = 1
 | 
			
		||||
				h.Read(buf[:shake128Rate])
 | 
			
		||||
				_, _ = h.Read(buf[:shake128Rate])
 | 
			
		||||
				pos = 0
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -140,10 +140,10 @@ func (p *poly) uniform(seed *[SeedBytes]byte, torSampling bool) {
 | 
			
		|||
 | 
			
		||||
		// h and buf are left unscrubbed because the output is public.
 | 
			
		||||
		h := sha3.NewShake128()
 | 
			
		||||
		h.Write(seed[:])
 | 
			
		||||
		_, _ = h.Write(seed[:])
 | 
			
		||||
 | 
			
		||||
		for {
 | 
			
		||||
			h.Read(buf[:])
 | 
			
		||||
			_, _ = h.Read(buf[:])
 | 
			
		||||
			if !p.discardTo(buf[:]) {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -159,7 +159,7 @@ func (p *poly) getNoise(seed *[SeedBytes]byte, nonce byte) {
 | 
			
		|||
	var n [8]byte
 | 
			
		||||
 | 
			
		||||
	n[0] = nonce
 | 
			
		||||
	stream, err := chacha20.NewCipher(seed[:], n[:])
 | 
			
		||||
	stream, err := chacha20.New(seed[:], n[:])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,95 +0,0 @@
 | 
			
		|||
// chacha20_amd64.go - AMD64 optimized chacha20.
 | 
			
		||||
//
 | 
			
		||||
// To the extent possible under law, Yawning Angel has waived all copyright
 | 
			
		||||
// and related or neighboring rights to chacha20, using the Creative
 | 
			
		||||
// Commons "CC0" public domain dedication. See LICENSE or
 | 
			
		||||
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
 | 
			
		||||
 | 
			
		||||
// +build amd64,!gccgo,!appengine
 | 
			
		||||
 | 
			
		||||
package chacha20
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"math"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var usingAVX2 = false
 | 
			
		||||
 | 
			
		||||
func blocksAmd64SSE2(x *uint32, inp, outp *byte, nrBlocks uint)
 | 
			
		||||
 | 
			
		||||
func blocksAmd64AVX2(x *uint32, inp, outp *byte, nrBlocks uint)
 | 
			
		||||
 | 
			
		||||
func cpuidAmd64(cpuidParams *uint32)
 | 
			
		||||
 | 
			
		||||
func xgetbv0Amd64(xcrVec *uint32)
 | 
			
		||||
 | 
			
		||||
func blocksAmd64(x *[stateSize]uint32, in []byte, out []byte, nrBlocks int, isIetf bool) {
 | 
			
		||||
	// Probably unneeded, but stating this explicitly simplifies the assembly.
 | 
			
		||||
	if nrBlocks == 0 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if isIetf {
 | 
			
		||||
		var totalBlocks uint64
 | 
			
		||||
		totalBlocks = uint64(x[12]) + uint64(nrBlocks)
 | 
			
		||||
		if totalBlocks > math.MaxUint32 {
 | 
			
		||||
			panic("chacha20: Exceeded keystream per nonce limit")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if in == nil {
 | 
			
		||||
		for i := range out {
 | 
			
		||||
			out[i] = 0
 | 
			
		||||
		}
 | 
			
		||||
		in = out
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Pointless to call the AVX2 code for just a single block, since half of
 | 
			
		||||
	// the output gets discarded...
 | 
			
		||||
	if usingAVX2 && nrBlocks > 1 {
 | 
			
		||||
		blocksAmd64AVX2(&x[0], &in[0], &out[0], uint(nrBlocks))
 | 
			
		||||
	} else {
 | 
			
		||||
		blocksAmd64SSE2(&x[0], &in[0], &out[0], uint(nrBlocks))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func supportsAVX2() bool {
 | 
			
		||||
	// https://software.intel.com/en-us/articles/how-to-detect-new-instruction-support-in-the-4th-generation-intel-core-processor-family
 | 
			
		||||
	const (
 | 
			
		||||
		osXsaveBit = 1 << 27
 | 
			
		||||
		avx2Bit    = 1 << 5
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	// Check to see if CPUID actually supports the leaf that indicates AVX2.
 | 
			
		||||
	// CPUID.(EAX=0H, ECX=0H) >= 7
 | 
			
		||||
	regs := [4]uint32{0x00}
 | 
			
		||||
	cpuidAmd64(®s[0])
 | 
			
		||||
	if regs[0] < 7 {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check to see if the OS knows how to save/restore XMM/YMM state.
 | 
			
		||||
	// CPUID.(EAX=01H, ECX=0H):ECX.OSXSAVE[bit 27]==1
 | 
			
		||||
	regs = [4]uint32{0x01}
 | 
			
		||||
	cpuidAmd64(®s[0])
 | 
			
		||||
	if regs[2]&osXsaveBit == 0 {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	xcrRegs := [2]uint32{}
 | 
			
		||||
	xgetbv0Amd64(&xcrRegs[0])
 | 
			
		||||
	if xcrRegs[0]&6 != 6 {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check for AVX2 support.
 | 
			
		||||
	// CPUID.(EAX=07H, ECX=0H):EBX.AVX2[bit 5]==1
 | 
			
		||||
	regs = [4]uint32{0x07}
 | 
			
		||||
	cpuidAmd64(®s[0])
 | 
			
		||||
	return regs[1]&avx2Bit != 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	blocksFn = blocksAmd64
 | 
			
		||||
	usingVectors = true
 | 
			
		||||
	usingAVX2 = supportsAVX2()
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,394 +0,0 @@
 | 
			
		|||
// chacha20_ref.go - Reference ChaCha20.
 | 
			
		||||
//
 | 
			
		||||
// To the extent possible under law, Yawning Angel has waived all copyright
 | 
			
		||||
// and related or neighboring rights to chacha20, using the Creative
 | 
			
		||||
// Commons "CC0" public domain dedication. See LICENSE or
 | 
			
		||||
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
 | 
			
		||||
 | 
			
		||||
// +build !go1.9
 | 
			
		||||
 | 
			
		||||
package chacha20
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"math"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func blocksRef(x *[stateSize]uint32, in []byte, out []byte, nrBlocks int, isIetf bool) {
 | 
			
		||||
	if isIetf {
 | 
			
		||||
		var totalBlocks uint64
 | 
			
		||||
		totalBlocks = uint64(x[12]) + uint64(nrBlocks)
 | 
			
		||||
		if totalBlocks > math.MaxUint32 {
 | 
			
		||||
			panic("chacha20: Exceeded keystream per nonce limit")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// This routine ignores x[0]...x[4] in favor the const values since it's
 | 
			
		||||
	// ever so slightly faster.
 | 
			
		||||
 | 
			
		||||
	for n := 0; n < nrBlocks; n++ {
 | 
			
		||||
		x0, x1, x2, x3 := sigma0, sigma1, sigma2, sigma3
 | 
			
		||||
		x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 := x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15]
 | 
			
		||||
 | 
			
		||||
		for i := chachaRounds; i > 0; i -= 2 {
 | 
			
		||||
			// quarterround(x, 0, 4, 8, 12)
 | 
			
		||||
			x0 += x4
 | 
			
		||||
			x12 ^= x0
 | 
			
		||||
			x12 = (x12 << 16) | (x12 >> 16)
 | 
			
		||||
			x8 += x12
 | 
			
		||||
			x4 ^= x8
 | 
			
		||||
			x4 = (x4 << 12) | (x4 >> 20)
 | 
			
		||||
			x0 += x4
 | 
			
		||||
			x12 ^= x0
 | 
			
		||||
			x12 = (x12 << 8) | (x12 >> 24)
 | 
			
		||||
			x8 += x12
 | 
			
		||||
			x4 ^= x8
 | 
			
		||||
			x4 = (x4 << 7) | (x4 >> 25)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 1, 5, 9, 13)
 | 
			
		||||
			x1 += x5
 | 
			
		||||
			x13 ^= x1
 | 
			
		||||
			x13 = (x13 << 16) | (x13 >> 16)
 | 
			
		||||
			x9 += x13
 | 
			
		||||
			x5 ^= x9
 | 
			
		||||
			x5 = (x5 << 12) | (x5 >> 20)
 | 
			
		||||
			x1 += x5
 | 
			
		||||
			x13 ^= x1
 | 
			
		||||
			x13 = (x13 << 8) | (x13 >> 24)
 | 
			
		||||
			x9 += x13
 | 
			
		||||
			x5 ^= x9
 | 
			
		||||
			x5 = (x5 << 7) | (x5 >> 25)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 2, 6, 10, 14)
 | 
			
		||||
			x2 += x6
 | 
			
		||||
			x14 ^= x2
 | 
			
		||||
			x14 = (x14 << 16) | (x14 >> 16)
 | 
			
		||||
			x10 += x14
 | 
			
		||||
			x6 ^= x10
 | 
			
		||||
			x6 = (x6 << 12) | (x6 >> 20)
 | 
			
		||||
			x2 += x6
 | 
			
		||||
			x14 ^= x2
 | 
			
		||||
			x14 = (x14 << 8) | (x14 >> 24)
 | 
			
		||||
			x10 += x14
 | 
			
		||||
			x6 ^= x10
 | 
			
		||||
			x6 = (x6 << 7) | (x6 >> 25)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 3, 7, 11, 15)
 | 
			
		||||
			x3 += x7
 | 
			
		||||
			x15 ^= x3
 | 
			
		||||
			x15 = (x15 << 16) | (x15 >> 16)
 | 
			
		||||
			x11 += x15
 | 
			
		||||
			x7 ^= x11
 | 
			
		||||
			x7 = (x7 << 12) | (x7 >> 20)
 | 
			
		||||
			x3 += x7
 | 
			
		||||
			x15 ^= x3
 | 
			
		||||
			x15 = (x15 << 8) | (x15 >> 24)
 | 
			
		||||
			x11 += x15
 | 
			
		||||
			x7 ^= x11
 | 
			
		||||
			x7 = (x7 << 7) | (x7 >> 25)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 0, 5, 10, 15)
 | 
			
		||||
			x0 += x5
 | 
			
		||||
			x15 ^= x0
 | 
			
		||||
			x15 = (x15 << 16) | (x15 >> 16)
 | 
			
		||||
			x10 += x15
 | 
			
		||||
			x5 ^= x10
 | 
			
		||||
			x5 = (x5 << 12) | (x5 >> 20)
 | 
			
		||||
			x0 += x5
 | 
			
		||||
			x15 ^= x0
 | 
			
		||||
			x15 = (x15 << 8) | (x15 >> 24)
 | 
			
		||||
			x10 += x15
 | 
			
		||||
			x5 ^= x10
 | 
			
		||||
			x5 = (x5 << 7) | (x5 >> 25)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 1, 6, 11, 12)
 | 
			
		||||
			x1 += x6
 | 
			
		||||
			x12 ^= x1
 | 
			
		||||
			x12 = (x12 << 16) | (x12 >> 16)
 | 
			
		||||
			x11 += x12
 | 
			
		||||
			x6 ^= x11
 | 
			
		||||
			x6 = (x6 << 12) | (x6 >> 20)
 | 
			
		||||
			x1 += x6
 | 
			
		||||
			x12 ^= x1
 | 
			
		||||
			x12 = (x12 << 8) | (x12 >> 24)
 | 
			
		||||
			x11 += x12
 | 
			
		||||
			x6 ^= x11
 | 
			
		||||
			x6 = (x6 << 7) | (x6 >> 25)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 2, 7, 8, 13)
 | 
			
		||||
			x2 += x7
 | 
			
		||||
			x13 ^= x2
 | 
			
		||||
			x13 = (x13 << 16) | (x13 >> 16)
 | 
			
		||||
			x8 += x13
 | 
			
		||||
			x7 ^= x8
 | 
			
		||||
			x7 = (x7 << 12) | (x7 >> 20)
 | 
			
		||||
			x2 += x7
 | 
			
		||||
			x13 ^= x2
 | 
			
		||||
			x13 = (x13 << 8) | (x13 >> 24)
 | 
			
		||||
			x8 += x13
 | 
			
		||||
			x7 ^= x8
 | 
			
		||||
			x7 = (x7 << 7) | (x7 >> 25)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 3, 4, 9, 14)
 | 
			
		||||
			x3 += x4
 | 
			
		||||
			x14 ^= x3
 | 
			
		||||
			x14 = (x14 << 16) | (x14 >> 16)
 | 
			
		||||
			x9 += x14
 | 
			
		||||
			x4 ^= x9
 | 
			
		||||
			x4 = (x4 << 12) | (x4 >> 20)
 | 
			
		||||
			x3 += x4
 | 
			
		||||
			x14 ^= x3
 | 
			
		||||
			x14 = (x14 << 8) | (x14 >> 24)
 | 
			
		||||
			x9 += x14
 | 
			
		||||
			x4 ^= x9
 | 
			
		||||
			x4 = (x4 << 7) | (x4 >> 25)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// On amd64 at least, this is a rather big boost.
 | 
			
		||||
		if useUnsafe {
 | 
			
		||||
			if in != nil {
 | 
			
		||||
				inArr := (*[16]uint32)(unsafe.Pointer(&in[n*BlockSize]))
 | 
			
		||||
				outArr := (*[16]uint32)(unsafe.Pointer(&out[n*BlockSize]))
 | 
			
		||||
				outArr[0] = inArr[0] ^ (x0 + sigma0)
 | 
			
		||||
				outArr[1] = inArr[1] ^ (x1 + sigma1)
 | 
			
		||||
				outArr[2] = inArr[2] ^ (x2 + sigma2)
 | 
			
		||||
				outArr[3] = inArr[3] ^ (x3 + sigma3)
 | 
			
		||||
				outArr[4] = inArr[4] ^ (x4 + x[4])
 | 
			
		||||
				outArr[5] = inArr[5] ^ (x5 + x[5])
 | 
			
		||||
				outArr[6] = inArr[6] ^ (x6 + x[6])
 | 
			
		||||
				outArr[7] = inArr[7] ^ (x7 + x[7])
 | 
			
		||||
				outArr[8] = inArr[8] ^ (x8 + x[8])
 | 
			
		||||
				outArr[9] = inArr[9] ^ (x9 + x[9])
 | 
			
		||||
				outArr[10] = inArr[10] ^ (x10 + x[10])
 | 
			
		||||
				outArr[11] = inArr[11] ^ (x11 + x[11])
 | 
			
		||||
				outArr[12] = inArr[12] ^ (x12 + x[12])
 | 
			
		||||
				outArr[13] = inArr[13] ^ (x13 + x[13])
 | 
			
		||||
				outArr[14] = inArr[14] ^ (x14 + x[14])
 | 
			
		||||
				outArr[15] = inArr[15] ^ (x15 + x[15])
 | 
			
		||||
			} else {
 | 
			
		||||
				outArr := (*[16]uint32)(unsafe.Pointer(&out[n*BlockSize]))
 | 
			
		||||
				outArr[0] = x0 + sigma0
 | 
			
		||||
				outArr[1] = x1 + sigma1
 | 
			
		||||
				outArr[2] = x2 + sigma2
 | 
			
		||||
				outArr[3] = x3 + sigma3
 | 
			
		||||
				outArr[4] = x4 + x[4]
 | 
			
		||||
				outArr[5] = x5 + x[5]
 | 
			
		||||
				outArr[6] = x6 + x[6]
 | 
			
		||||
				outArr[7] = x7 + x[7]
 | 
			
		||||
				outArr[8] = x8 + x[8]
 | 
			
		||||
				outArr[9] = x9 + x[9]
 | 
			
		||||
				outArr[10] = x10 + x[10]
 | 
			
		||||
				outArr[11] = x11 + x[11]
 | 
			
		||||
				outArr[12] = x12 + x[12]
 | 
			
		||||
				outArr[13] = x13 + x[13]
 | 
			
		||||
				outArr[14] = x14 + x[14]
 | 
			
		||||
				outArr[15] = x15 + x[15]
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			// Slow path, either the architecture cares about alignment, or is not little endian.
 | 
			
		||||
			x0 += sigma0
 | 
			
		||||
			x1 += sigma1
 | 
			
		||||
			x2 += sigma2
 | 
			
		||||
			x3 += sigma3
 | 
			
		||||
			x4 += x[4]
 | 
			
		||||
			x5 += x[5]
 | 
			
		||||
			x6 += x[6]
 | 
			
		||||
			x7 += x[7]
 | 
			
		||||
			x8 += x[8]
 | 
			
		||||
			x9 += x[9]
 | 
			
		||||
			x10 += x[10]
 | 
			
		||||
			x11 += x[11]
 | 
			
		||||
			x12 += x[12]
 | 
			
		||||
			x13 += x[13]
 | 
			
		||||
			x14 += x[14]
 | 
			
		||||
			x15 += x[15]
 | 
			
		||||
			if in != nil {
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[0:4], binary.LittleEndian.Uint32(in[0:4])^x0)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[4:8], binary.LittleEndian.Uint32(in[4:8])^x1)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[8:12], binary.LittleEndian.Uint32(in[8:12])^x2)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[12:16], binary.LittleEndian.Uint32(in[12:16])^x3)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[16:20], binary.LittleEndian.Uint32(in[16:20])^x4)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[20:24], binary.LittleEndian.Uint32(in[20:24])^x5)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[24:28], binary.LittleEndian.Uint32(in[24:28])^x6)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[28:32], binary.LittleEndian.Uint32(in[28:32])^x7)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[32:36], binary.LittleEndian.Uint32(in[32:36])^x8)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[36:40], binary.LittleEndian.Uint32(in[36:40])^x9)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[40:44], binary.LittleEndian.Uint32(in[40:44])^x10)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[44:48], binary.LittleEndian.Uint32(in[44:48])^x11)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[48:52], binary.LittleEndian.Uint32(in[48:52])^x12)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[52:56], binary.LittleEndian.Uint32(in[52:56])^x13)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[56:60], binary.LittleEndian.Uint32(in[56:60])^x14)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[60:64], binary.LittleEndian.Uint32(in[60:64])^x15)
 | 
			
		||||
				in = in[BlockSize:]
 | 
			
		||||
			} else {
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[0:4], x0)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[4:8], x1)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[8:12], x2)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[12:16], x3)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[16:20], x4)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[20:24], x5)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[24:28], x6)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[28:32], x7)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[32:36], x8)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[36:40], x9)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[40:44], x10)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[44:48], x11)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[48:52], x12)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[52:56], x13)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[56:60], x14)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[60:64], x15)
 | 
			
		||||
			}
 | 
			
		||||
			out = out[BlockSize:]
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Stoping at 2^70 bytes per nonce is the user's responsibility.
 | 
			
		||||
		ctr := uint64(x[13])<<32 | uint64(x[12])
 | 
			
		||||
		ctr++
 | 
			
		||||
		x[12] = uint32(ctr)
 | 
			
		||||
		x[13] = uint32(ctr >> 32)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func hChaChaRef(x *[stateSize]uint32, out *[32]byte) {
 | 
			
		||||
	x0, x1, x2, x3 := sigma0, sigma1, sigma2, sigma3
 | 
			
		||||
	x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 := x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11]
 | 
			
		||||
 | 
			
		||||
	for i := chachaRounds; i > 0; i -= 2 {
 | 
			
		||||
		// quarterround(x, 0, 4, 8, 12)
 | 
			
		||||
		x0 += x4
 | 
			
		||||
		x12 ^= x0
 | 
			
		||||
		x12 = (x12 << 16) | (x12 >> 16)
 | 
			
		||||
		x8 += x12
 | 
			
		||||
		x4 ^= x8
 | 
			
		||||
		x4 = (x4 << 12) | (x4 >> 20)
 | 
			
		||||
		x0 += x4
 | 
			
		||||
		x12 ^= x0
 | 
			
		||||
		x12 = (x12 << 8) | (x12 >> 24)
 | 
			
		||||
		x8 += x12
 | 
			
		||||
		x4 ^= x8
 | 
			
		||||
		x4 = (x4 << 7) | (x4 >> 25)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 1, 5, 9, 13)
 | 
			
		||||
		x1 += x5
 | 
			
		||||
		x13 ^= x1
 | 
			
		||||
		x13 = (x13 << 16) | (x13 >> 16)
 | 
			
		||||
		x9 += x13
 | 
			
		||||
		x5 ^= x9
 | 
			
		||||
		x5 = (x5 << 12) | (x5 >> 20)
 | 
			
		||||
		x1 += x5
 | 
			
		||||
		x13 ^= x1
 | 
			
		||||
		x13 = (x13 << 8) | (x13 >> 24)
 | 
			
		||||
		x9 += x13
 | 
			
		||||
		x5 ^= x9
 | 
			
		||||
		x5 = (x5 << 7) | (x5 >> 25)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 2, 6, 10, 14)
 | 
			
		||||
		x2 += x6
 | 
			
		||||
		x14 ^= x2
 | 
			
		||||
		x14 = (x14 << 16) | (x14 >> 16)
 | 
			
		||||
		x10 += x14
 | 
			
		||||
		x6 ^= x10
 | 
			
		||||
		x6 = (x6 << 12) | (x6 >> 20)
 | 
			
		||||
		x2 += x6
 | 
			
		||||
		x14 ^= x2
 | 
			
		||||
		x14 = (x14 << 8) | (x14 >> 24)
 | 
			
		||||
		x10 += x14
 | 
			
		||||
		x6 ^= x10
 | 
			
		||||
		x6 = (x6 << 7) | (x6 >> 25)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 3, 7, 11, 15)
 | 
			
		||||
		x3 += x7
 | 
			
		||||
		x15 ^= x3
 | 
			
		||||
		x15 = (x15 << 16) | (x15 >> 16)
 | 
			
		||||
		x11 += x15
 | 
			
		||||
		x7 ^= x11
 | 
			
		||||
		x7 = (x7 << 12) | (x7 >> 20)
 | 
			
		||||
		x3 += x7
 | 
			
		||||
		x15 ^= x3
 | 
			
		||||
		x15 = (x15 << 8) | (x15 >> 24)
 | 
			
		||||
		x11 += x15
 | 
			
		||||
		x7 ^= x11
 | 
			
		||||
		x7 = (x7 << 7) | (x7 >> 25)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 0, 5, 10, 15)
 | 
			
		||||
		x0 += x5
 | 
			
		||||
		x15 ^= x0
 | 
			
		||||
		x15 = (x15 << 16) | (x15 >> 16)
 | 
			
		||||
		x10 += x15
 | 
			
		||||
		x5 ^= x10
 | 
			
		||||
		x5 = (x5 << 12) | (x5 >> 20)
 | 
			
		||||
		x0 += x5
 | 
			
		||||
		x15 ^= x0
 | 
			
		||||
		x15 = (x15 << 8) | (x15 >> 24)
 | 
			
		||||
		x10 += x15
 | 
			
		||||
		x5 ^= x10
 | 
			
		||||
		x5 = (x5 << 7) | (x5 >> 25)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 1, 6, 11, 12)
 | 
			
		||||
		x1 += x6
 | 
			
		||||
		x12 ^= x1
 | 
			
		||||
		x12 = (x12 << 16) | (x12 >> 16)
 | 
			
		||||
		x11 += x12
 | 
			
		||||
		x6 ^= x11
 | 
			
		||||
		x6 = (x6 << 12) | (x6 >> 20)
 | 
			
		||||
		x1 += x6
 | 
			
		||||
		x12 ^= x1
 | 
			
		||||
		x12 = (x12 << 8) | (x12 >> 24)
 | 
			
		||||
		x11 += x12
 | 
			
		||||
		x6 ^= x11
 | 
			
		||||
		x6 = (x6 << 7) | (x6 >> 25)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 2, 7, 8, 13)
 | 
			
		||||
		x2 += x7
 | 
			
		||||
		x13 ^= x2
 | 
			
		||||
		x13 = (x13 << 16) | (x13 >> 16)
 | 
			
		||||
		x8 += x13
 | 
			
		||||
		x7 ^= x8
 | 
			
		||||
		x7 = (x7 << 12) | (x7 >> 20)
 | 
			
		||||
		x2 += x7
 | 
			
		||||
		x13 ^= x2
 | 
			
		||||
		x13 = (x13 << 8) | (x13 >> 24)
 | 
			
		||||
		x8 += x13
 | 
			
		||||
		x7 ^= x8
 | 
			
		||||
		x7 = (x7 << 7) | (x7 >> 25)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 3, 4, 9, 14)
 | 
			
		||||
		x3 += x4
 | 
			
		||||
		x14 ^= x3
 | 
			
		||||
		x14 = (x14 << 16) | (x14 >> 16)
 | 
			
		||||
		x9 += x14
 | 
			
		||||
		x4 ^= x9
 | 
			
		||||
		x4 = (x4 << 12) | (x4 >> 20)
 | 
			
		||||
		x3 += x4
 | 
			
		||||
		x14 ^= x3
 | 
			
		||||
		x14 = (x14 << 8) | (x14 >> 24)
 | 
			
		||||
		x9 += x14
 | 
			
		||||
		x4 ^= x9
 | 
			
		||||
		x4 = (x4 << 7) | (x4 >> 25)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// HChaCha returns x0...x3 | x12...x15, which corresponds to the
 | 
			
		||||
	// indexes of the ChaCha constant and the indexes of the IV.
 | 
			
		||||
	if useUnsafe {
 | 
			
		||||
		outArr := (*[16]uint32)(unsafe.Pointer(&out[0]))
 | 
			
		||||
		outArr[0] = x0
 | 
			
		||||
		outArr[1] = x1
 | 
			
		||||
		outArr[2] = x2
 | 
			
		||||
		outArr[3] = x3
 | 
			
		||||
		outArr[4] = x12
 | 
			
		||||
		outArr[5] = x13
 | 
			
		||||
		outArr[6] = x14
 | 
			
		||||
		outArr[7] = x15
 | 
			
		||||
	} else {
 | 
			
		||||
		binary.LittleEndian.PutUint32(out[0:4], x0)
 | 
			
		||||
		binary.LittleEndian.PutUint32(out[4:8], x1)
 | 
			
		||||
		binary.LittleEndian.PutUint32(out[8:12], x2)
 | 
			
		||||
		binary.LittleEndian.PutUint32(out[12:16], x3)
 | 
			
		||||
		binary.LittleEndian.PutUint32(out[16:20], x12)
 | 
			
		||||
		binary.LittleEndian.PutUint32(out[20:24], x13)
 | 
			
		||||
		binary.LittleEndian.PutUint32(out[24:28], x14)
 | 
			
		||||
		binary.LittleEndian.PutUint32(out[28:32], x15)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,395 +0,0 @@
 | 
			
		|||
// chacha20_ref.go - Reference ChaCha20.
 | 
			
		||||
//
 | 
			
		||||
// To the extent possible under law, Yawning Angel has waived all copyright
 | 
			
		||||
// and related or neighboring rights to chacha20, using the Creative
 | 
			
		||||
// Commons "CC0" public domain dedication. See LICENSE or
 | 
			
		||||
// <http://creativecommons.org/publicdomain/zero/1.0/> for full details.
 | 
			
		||||
 | 
			
		||||
// +build go1.9
 | 
			
		||||
 | 
			
		||||
package chacha20
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"math"
 | 
			
		||||
	"math/bits"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func blocksRef(x *[stateSize]uint32, in []byte, out []byte, nrBlocks int, isIetf bool) {
 | 
			
		||||
	if isIetf {
 | 
			
		||||
		var totalBlocks uint64
 | 
			
		||||
		totalBlocks = uint64(x[12]) + uint64(nrBlocks)
 | 
			
		||||
		if totalBlocks > math.MaxUint32 {
 | 
			
		||||
			panic("chacha20: Exceeded keystream per nonce limit")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// This routine ignores x[0]...x[4] in favor the const values since it's
 | 
			
		||||
	// ever so slightly faster.
 | 
			
		||||
 | 
			
		||||
	for n := 0; n < nrBlocks; n++ {
 | 
			
		||||
		x0, x1, x2, x3 := sigma0, sigma1, sigma2, sigma3
 | 
			
		||||
		x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 := x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11], x[12], x[13], x[14], x[15]
 | 
			
		||||
 | 
			
		||||
		for i := chachaRounds; i > 0; i -= 2 {
 | 
			
		||||
			// quarterround(x, 0, 4, 8, 12)
 | 
			
		||||
			x0 += x4
 | 
			
		||||
			x12 ^= x0
 | 
			
		||||
			x12 = bits.RotateLeft32(x12, 16)
 | 
			
		||||
			x8 += x12
 | 
			
		||||
			x4 ^= x8
 | 
			
		||||
			x4 = bits.RotateLeft32(x4, 12)
 | 
			
		||||
			x0 += x4
 | 
			
		||||
			x12 ^= x0
 | 
			
		||||
			x12 = bits.RotateLeft32(x12, 8)
 | 
			
		||||
			x8 += x12
 | 
			
		||||
			x4 ^= x8
 | 
			
		||||
			x4 = bits.RotateLeft32(x4, 7)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 1, 5, 9, 13)
 | 
			
		||||
			x1 += x5
 | 
			
		||||
			x13 ^= x1
 | 
			
		||||
			x13 = bits.RotateLeft32(x13, 16)
 | 
			
		||||
			x9 += x13
 | 
			
		||||
			x5 ^= x9
 | 
			
		||||
			x5 = bits.RotateLeft32(x5, 12)
 | 
			
		||||
			x1 += x5
 | 
			
		||||
			x13 ^= x1
 | 
			
		||||
			x13 = bits.RotateLeft32(x13, 8)
 | 
			
		||||
			x9 += x13
 | 
			
		||||
			x5 ^= x9
 | 
			
		||||
			x5 = bits.RotateLeft32(x5, 7)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 2, 6, 10, 14)
 | 
			
		||||
			x2 += x6
 | 
			
		||||
			x14 ^= x2
 | 
			
		||||
			x14 = bits.RotateLeft32(x14, 16)
 | 
			
		||||
			x10 += x14
 | 
			
		||||
			x6 ^= x10
 | 
			
		||||
			x6 = bits.RotateLeft32(x6, 12)
 | 
			
		||||
			x2 += x6
 | 
			
		||||
			x14 ^= x2
 | 
			
		||||
			x14 = bits.RotateLeft32(x14, 8)
 | 
			
		||||
			x10 += x14
 | 
			
		||||
			x6 ^= x10
 | 
			
		||||
			x6 = bits.RotateLeft32(x6, 7)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 3, 7, 11, 15)
 | 
			
		||||
			x3 += x7
 | 
			
		||||
			x15 ^= x3
 | 
			
		||||
			x15 = bits.RotateLeft32(x15, 16)
 | 
			
		||||
			x11 += x15
 | 
			
		||||
			x7 ^= x11
 | 
			
		||||
			x7 = bits.RotateLeft32(x7, 12)
 | 
			
		||||
			x3 += x7
 | 
			
		||||
			x15 ^= x3
 | 
			
		||||
			x15 = bits.RotateLeft32(x15, 8)
 | 
			
		||||
			x11 += x15
 | 
			
		||||
			x7 ^= x11
 | 
			
		||||
			x7 = bits.RotateLeft32(x7, 7)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 0, 5, 10, 15)
 | 
			
		||||
			x0 += x5
 | 
			
		||||
			x15 ^= x0
 | 
			
		||||
			x15 = bits.RotateLeft32(x15, 16)
 | 
			
		||||
			x10 += x15
 | 
			
		||||
			x5 ^= x10
 | 
			
		||||
			x5 = bits.RotateLeft32(x5, 12)
 | 
			
		||||
			x0 += x5
 | 
			
		||||
			x15 ^= x0
 | 
			
		||||
			x15 = bits.RotateLeft32(x15, 8)
 | 
			
		||||
			x10 += x15
 | 
			
		||||
			x5 ^= x10
 | 
			
		||||
			x5 = bits.RotateLeft32(x5, 7)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 1, 6, 11, 12)
 | 
			
		||||
			x1 += x6
 | 
			
		||||
			x12 ^= x1
 | 
			
		||||
			x12 = bits.RotateLeft32(x12, 16)
 | 
			
		||||
			x11 += x12
 | 
			
		||||
			x6 ^= x11
 | 
			
		||||
			x6 = bits.RotateLeft32(x6, 12)
 | 
			
		||||
			x1 += x6
 | 
			
		||||
			x12 ^= x1
 | 
			
		||||
			x12 = bits.RotateLeft32(x12, 8)
 | 
			
		||||
			x11 += x12
 | 
			
		||||
			x6 ^= x11
 | 
			
		||||
			x6 = bits.RotateLeft32(x6, 7)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 2, 7, 8, 13)
 | 
			
		||||
			x2 += x7
 | 
			
		||||
			x13 ^= x2
 | 
			
		||||
			x13 = bits.RotateLeft32(x13, 16)
 | 
			
		||||
			x8 += x13
 | 
			
		||||
			x7 ^= x8
 | 
			
		||||
			x7 = bits.RotateLeft32(x7, 12)
 | 
			
		||||
			x2 += x7
 | 
			
		||||
			x13 ^= x2
 | 
			
		||||
			x13 = bits.RotateLeft32(x13, 8)
 | 
			
		||||
			x8 += x13
 | 
			
		||||
			x7 ^= x8
 | 
			
		||||
			x7 = bits.RotateLeft32(x7, 7)
 | 
			
		||||
 | 
			
		||||
			// quarterround(x, 3, 4, 9, 14)
 | 
			
		||||
			x3 += x4
 | 
			
		||||
			x14 ^= x3
 | 
			
		||||
			x14 = bits.RotateLeft32(x14, 16)
 | 
			
		||||
			x9 += x14
 | 
			
		||||
			x4 ^= x9
 | 
			
		||||
			x4 = bits.RotateLeft32(x4, 12)
 | 
			
		||||
			x3 += x4
 | 
			
		||||
			x14 ^= x3
 | 
			
		||||
			x14 = bits.RotateLeft32(x14, 8)
 | 
			
		||||
			x9 += x14
 | 
			
		||||
			x4 ^= x9
 | 
			
		||||
			x4 = bits.RotateLeft32(x4, 7)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// On amd64 at least, this is a rather big boost.
 | 
			
		||||
		if useUnsafe {
 | 
			
		||||
			if in != nil {
 | 
			
		||||
				inArr := (*[16]uint32)(unsafe.Pointer(&in[n*BlockSize]))
 | 
			
		||||
				outArr := (*[16]uint32)(unsafe.Pointer(&out[n*BlockSize]))
 | 
			
		||||
				outArr[0] = inArr[0] ^ (x0 + sigma0)
 | 
			
		||||
				outArr[1] = inArr[1] ^ (x1 + sigma1)
 | 
			
		||||
				outArr[2] = inArr[2] ^ (x2 + sigma2)
 | 
			
		||||
				outArr[3] = inArr[3] ^ (x3 + sigma3)
 | 
			
		||||
				outArr[4] = inArr[4] ^ (x4 + x[4])
 | 
			
		||||
				outArr[5] = inArr[5] ^ (x5 + x[5])
 | 
			
		||||
				outArr[6] = inArr[6] ^ (x6 + x[6])
 | 
			
		||||
				outArr[7] = inArr[7] ^ (x7 + x[7])
 | 
			
		||||
				outArr[8] = inArr[8] ^ (x8 + x[8])
 | 
			
		||||
				outArr[9] = inArr[9] ^ (x9 + x[9])
 | 
			
		||||
				outArr[10] = inArr[10] ^ (x10 + x[10])
 | 
			
		||||
				outArr[11] = inArr[11] ^ (x11 + x[11])
 | 
			
		||||
				outArr[12] = inArr[12] ^ (x12 + x[12])
 | 
			
		||||
				outArr[13] = inArr[13] ^ (x13 + x[13])
 | 
			
		||||
				outArr[14] = inArr[14] ^ (x14 + x[14])
 | 
			
		||||
				outArr[15] = inArr[15] ^ (x15 + x[15])
 | 
			
		||||
			} else {
 | 
			
		||||
				outArr := (*[16]uint32)(unsafe.Pointer(&out[n*BlockSize]))
 | 
			
		||||
				outArr[0] = x0 + sigma0
 | 
			
		||||
				outArr[1] = x1 + sigma1
 | 
			
		||||
				outArr[2] = x2 + sigma2
 | 
			
		||||
				outArr[3] = x3 + sigma3
 | 
			
		||||
				outArr[4] = x4 + x[4]
 | 
			
		||||
				outArr[5] = x5 + x[5]
 | 
			
		||||
				outArr[6] = x6 + x[6]
 | 
			
		||||
				outArr[7] = x7 + x[7]
 | 
			
		||||
				outArr[8] = x8 + x[8]
 | 
			
		||||
				outArr[9] = x9 + x[9]
 | 
			
		||||
				outArr[10] = x10 + x[10]
 | 
			
		||||
				outArr[11] = x11 + x[11]
 | 
			
		||||
				outArr[12] = x12 + x[12]
 | 
			
		||||
				outArr[13] = x13 + x[13]
 | 
			
		||||
				outArr[14] = x14 + x[14]
 | 
			
		||||
				outArr[15] = x15 + x[15]
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			// Slow path, either the architecture cares about alignment, or is not little endian.
 | 
			
		||||
			x0 += sigma0
 | 
			
		||||
			x1 += sigma1
 | 
			
		||||
			x2 += sigma2
 | 
			
		||||
			x3 += sigma3
 | 
			
		||||
			x4 += x[4]
 | 
			
		||||
			x5 += x[5]
 | 
			
		||||
			x6 += x[6]
 | 
			
		||||
			x7 += x[7]
 | 
			
		||||
			x8 += x[8]
 | 
			
		||||
			x9 += x[9]
 | 
			
		||||
			x10 += x[10]
 | 
			
		||||
			x11 += x[11]
 | 
			
		||||
			x12 += x[12]
 | 
			
		||||
			x13 += x[13]
 | 
			
		||||
			x14 += x[14]
 | 
			
		||||
			x15 += x[15]
 | 
			
		||||
			if in != nil {
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[0:4], binary.LittleEndian.Uint32(in[0:4])^x0)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[4:8], binary.LittleEndian.Uint32(in[4:8])^x1)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[8:12], binary.LittleEndian.Uint32(in[8:12])^x2)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[12:16], binary.LittleEndian.Uint32(in[12:16])^x3)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[16:20], binary.LittleEndian.Uint32(in[16:20])^x4)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[20:24], binary.LittleEndian.Uint32(in[20:24])^x5)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[24:28], binary.LittleEndian.Uint32(in[24:28])^x6)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[28:32], binary.LittleEndian.Uint32(in[28:32])^x7)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[32:36], binary.LittleEndian.Uint32(in[32:36])^x8)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[36:40], binary.LittleEndian.Uint32(in[36:40])^x9)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[40:44], binary.LittleEndian.Uint32(in[40:44])^x10)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[44:48], binary.LittleEndian.Uint32(in[44:48])^x11)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[48:52], binary.LittleEndian.Uint32(in[48:52])^x12)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[52:56], binary.LittleEndian.Uint32(in[52:56])^x13)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[56:60], binary.LittleEndian.Uint32(in[56:60])^x14)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[60:64], binary.LittleEndian.Uint32(in[60:64])^x15)
 | 
			
		||||
				in = in[BlockSize:]
 | 
			
		||||
			} else {
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[0:4], x0)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[4:8], x1)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[8:12], x2)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[12:16], x3)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[16:20], x4)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[20:24], x5)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[24:28], x6)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[28:32], x7)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[32:36], x8)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[36:40], x9)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[40:44], x10)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[44:48], x11)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[48:52], x12)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[52:56], x13)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[56:60], x14)
 | 
			
		||||
				binary.LittleEndian.PutUint32(out[60:64], x15)
 | 
			
		||||
			}
 | 
			
		||||
			out = out[BlockSize:]
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Stoping at 2^70 bytes per nonce is the user's responsibility.
 | 
			
		||||
		ctr := uint64(x[13])<<32 | uint64(x[12])
 | 
			
		||||
		ctr++
 | 
			
		||||
		x[12] = uint32(ctr)
 | 
			
		||||
		x[13] = uint32(ctr >> 32)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func hChaChaRef(x *[stateSize]uint32, out *[32]byte) {
 | 
			
		||||
	x0, x1, x2, x3 := sigma0, sigma1, sigma2, sigma3
 | 
			
		||||
	x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15 := x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], x[10], x[11]
 | 
			
		||||
 | 
			
		||||
	for i := chachaRounds; i > 0; i -= 2 {
 | 
			
		||||
		// quarterround(x, 0, 4, 8, 12)
 | 
			
		||||
		x0 += x4
 | 
			
		||||
		x12 ^= x0
 | 
			
		||||
		x12 = bits.RotateLeft32(x12, 16)
 | 
			
		||||
		x8 += x12
 | 
			
		||||
		x4 ^= x8
 | 
			
		||||
		x4 = bits.RotateLeft32(x4, 12)
 | 
			
		||||
		x0 += x4
 | 
			
		||||
		x12 ^= x0
 | 
			
		||||
		x12 = bits.RotateLeft32(x12, 8)
 | 
			
		||||
		x8 += x12
 | 
			
		||||
		x4 ^= x8
 | 
			
		||||
		x4 = bits.RotateLeft32(x4, 7)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 1, 5, 9, 13)
 | 
			
		||||
		x1 += x5
 | 
			
		||||
		x13 ^= x1
 | 
			
		||||
		x13 = bits.RotateLeft32(x13, 16)
 | 
			
		||||
		x9 += x13
 | 
			
		||||
		x5 ^= x9
 | 
			
		||||
		x5 = bits.RotateLeft32(x5, 12)
 | 
			
		||||
		x1 += x5
 | 
			
		||||
		x13 ^= x1
 | 
			
		||||
		x13 = bits.RotateLeft32(x13, 8)
 | 
			
		||||
		x9 += x13
 | 
			
		||||
		x5 ^= x9
 | 
			
		||||
		x5 = bits.RotateLeft32(x5, 7)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 2, 6, 10, 14)
 | 
			
		||||
		x2 += x6
 | 
			
		||||
		x14 ^= x2
 | 
			
		||||
		x14 = bits.RotateLeft32(x14, 16)
 | 
			
		||||
		x10 += x14
 | 
			
		||||
		x6 ^= x10
 | 
			
		||||
		x6 = bits.RotateLeft32(x6, 12)
 | 
			
		||||
		x2 += x6
 | 
			
		||||
		x14 ^= x2
 | 
			
		||||
		x14 = bits.RotateLeft32(x14, 8)
 | 
			
		||||
		x10 += x14
 | 
			
		||||
		x6 ^= x10
 | 
			
		||||
		x6 = bits.RotateLeft32(x6, 7)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 3, 7, 11, 15)
 | 
			
		||||
		x3 += x7
 | 
			
		||||
		x15 ^= x3
 | 
			
		||||
		x15 = bits.RotateLeft32(x15, 16)
 | 
			
		||||
		x11 += x15
 | 
			
		||||
		x7 ^= x11
 | 
			
		||||
		x7 = bits.RotateLeft32(x7, 12)
 | 
			
		||||
		x3 += x7
 | 
			
		||||
		x15 ^= x3
 | 
			
		||||
		x15 = bits.RotateLeft32(x15, 8)
 | 
			
		||||
		x11 += x15
 | 
			
		||||
		x7 ^= x11
 | 
			
		||||
		x7 = bits.RotateLeft32(x7, 7)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 0, 5, 10, 15)
 | 
			
		||||
		x0 += x5
 | 
			
		||||
		x15 ^= x0
 | 
			
		||||
		x15 = bits.RotateLeft32(x15, 16)
 | 
			
		||||
		x10 += x15
 | 
			
		||||
		x5 ^= x10
 | 
			
		||||
		x5 = bits.RotateLeft32(x5, 12)
 | 
			
		||||
		x0 += x5
 | 
			
		||||
		x15 ^= x0
 | 
			
		||||
		x15 = bits.RotateLeft32(x15, 8)
 | 
			
		||||
		x10 += x15
 | 
			
		||||
		x5 ^= x10
 | 
			
		||||
		x5 = bits.RotateLeft32(x5, 7)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 1, 6, 11, 12)
 | 
			
		||||
		x1 += x6
 | 
			
		||||
		x12 ^= x1
 | 
			
		||||
		x12 = bits.RotateLeft32(x12, 16)
 | 
			
		||||
		x11 += x12
 | 
			
		||||
		x6 ^= x11
 | 
			
		||||
		x6 = bits.RotateLeft32(x6, 12)
 | 
			
		||||
		x1 += x6
 | 
			
		||||
		x12 ^= x1
 | 
			
		||||
		x12 = bits.RotateLeft32(x12, 8)
 | 
			
		||||
		x11 += x12
 | 
			
		||||
		x6 ^= x11
 | 
			
		||||
		x6 = bits.RotateLeft32(x6, 7)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 2, 7, 8, 13)
 | 
			
		||||
		x2 += x7
 | 
			
		||||
		x13 ^= x2
 | 
			
		||||
		x13 = bits.RotateLeft32(x13, 16)
 | 
			
		||||
		x8 += x13
 | 
			
		||||
		x7 ^= x8
 | 
			
		||||
		x7 = bits.RotateLeft32(x7, 12)
 | 
			
		||||
		x2 += x7
 | 
			
		||||
		x13 ^= x2
 | 
			
		||||
		x13 = bits.RotateLeft32(x13, 8)
 | 
			
		||||
		x8 += x13
 | 
			
		||||
		x7 ^= x8
 | 
			
		||||
		x7 = bits.RotateLeft32(x7, 7)
 | 
			
		||||
 | 
			
		||||
		// quarterround(x, 3, 4, 9, 14)
 | 
			
		||||
		x3 += x4
 | 
			
		||||
		x14 ^= x3
 | 
			
		||||
		x14 = bits.RotateLeft32(x14, 16)
 | 
			
		||||
		x9 += x14
 | 
			
		||||
		x4 ^= x9
 | 
			
		||||
		x4 = bits.RotateLeft32(x4, 12)
 | 
			
		||||
		x3 += x4
 | 
			
		||||
		x14 ^= x3
 | 
			
		||||
		x14 = bits.RotateLeft32(x14, 8)
 | 
			
		||||
		x9 += x14
 | 
			
		||||
		x4 ^= x9
 | 
			
		||||
		x4 = bits.RotateLeft32(x4, 7)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// HChaCha returns x0...x3 | x12...x15, which corresponds to the
 | 
			
		||||
	// indexes of the ChaCha constant and the indexes of the IV.
 | 
			
		||||
	if useUnsafe {
 | 
			
		||||
		outArr := (*[16]uint32)(unsafe.Pointer(&out[0]))
 | 
			
		||||
		outArr[0] = x0
 | 
			
		||||
		outArr[1] = x1
 | 
			
		||||
		outArr[2] = x2
 | 
			
		||||
		outArr[3] = x3
 | 
			
		||||
		outArr[4] = x12
 | 
			
		||||
		outArr[5] = x13
 | 
			
		||||
		outArr[6] = x14
 | 
			
		||||
		outArr[7] = x15
 | 
			
		||||
	} else {
 | 
			
		||||
		binary.LittleEndian.PutUint32(out[0:4], x0)
 | 
			
		||||
		binary.LittleEndian.PutUint32(out[4:8], x1)
 | 
			
		||||
		binary.LittleEndian.PutUint32(out[8:12], x2)
 | 
			
		||||
		binary.LittleEndian.PutUint32(out[12:16], x3)
 | 
			
		||||
		binary.LittleEndian.PutUint32(out[16:20], x12)
 | 
			
		||||
		binary.LittleEndian.PutUint32(out[20:24], x13)
 | 
			
		||||
		binary.LittleEndian.PutUint32(out[24:28], x14)
 | 
			
		||||
		binary.LittleEndian.PutUint32(out[28:32], x15)
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,122 +0,0 @@
 | 
			
		|||
Creative Commons Legal Code
 | 
			
		||||
 | 
			
		||||
CC0 1.0 Universal
 | 
			
		||||
 | 
			
		||||
    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
 | 
			
		||||
    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
 | 
			
		||||
    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
 | 
			
		||||
    INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
 | 
			
		||||
    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
 | 
			
		||||
    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
 | 
			
		||||
    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
 | 
			
		||||
    HEREUNDER.
 | 
			
		||||
 | 
			
		||||
Statement of Purpose
 | 
			
		||||
 | 
			
		||||
The laws of most jurisdictions throughout the world automatically confer
 | 
			
		||||
exclusive Copyright and Related Rights (defined below) upon the creator
 | 
			
		||||
and subsequent owner(s) (each and all, an "owner") of an original work of
 | 
			
		||||
authorship and/or a database (each, a "Work").
 | 
			
		||||
 | 
			
		||||
Certain owners wish to permanently relinquish those rights to a Work for
 | 
			
		||||
the purpose of contributing to a commons of creative, cultural and
 | 
			
		||||
scientific works ("Commons") that the public can reliably and without fear
 | 
			
		||||
of later claims of infringement build upon, modify, incorporate in other
 | 
			
		||||
works, reuse and redistribute as freely as possible in any form whatsoever
 | 
			
		||||
and for any purposes, including without limitation commercial purposes.
 | 
			
		||||
These owners may contribute to the Commons to promote the ideal of a free
 | 
			
		||||
culture and the further production of creative, cultural and scientific
 | 
			
		||||
works, or to gain reputation or greater distribution for their Work in
 | 
			
		||||
part through the use and efforts of others.
 | 
			
		||||
 | 
			
		||||
For these and/or other purposes and motivations, and without any
 | 
			
		||||
expectation of additional consideration or compensation, the person
 | 
			
		||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
 | 
			
		||||
is an owner of Copyright and Related Rights in the Work, voluntarily
 | 
			
		||||
elects to apply CC0 to the Work and publicly distribute the Work under its
 | 
			
		||||
terms, with knowledge of his or her Copyright and Related Rights in the
 | 
			
		||||
Work and the meaning and intended legal effect of CC0 on those rights.
 | 
			
		||||
 | 
			
		||||
1. Copyright and Related Rights. A Work made available under CC0 may be
 | 
			
		||||
protected by copyright and related or neighboring rights ("Copyright and
 | 
			
		||||
Related Rights"). Copyright and Related Rights include, but are not
 | 
			
		||||
limited to, the following:
 | 
			
		||||
 | 
			
		||||
  i. the right to reproduce, adapt, distribute, perform, display,
 | 
			
		||||
     communicate, and translate a Work;
 | 
			
		||||
 ii. moral rights retained by the original author(s) and/or performer(s);
 | 
			
		||||
iii. publicity and privacy rights pertaining to a person's image or
 | 
			
		||||
     likeness depicted in a Work;
 | 
			
		||||
 iv. rights protecting against unfair competition in regards to a Work,
 | 
			
		||||
     subject to the limitations in paragraph 4(a), below;
 | 
			
		||||
  v. rights protecting the extraction, dissemination, use and reuse of data
 | 
			
		||||
     in a Work;
 | 
			
		||||
 vi. database rights (such as those arising under Directive 96/9/EC of the
 | 
			
		||||
     European Parliament and of the Council of 11 March 1996 on the legal
 | 
			
		||||
     protection of databases, and under any national implementation
 | 
			
		||||
     thereof, including any amended or successor version of such
 | 
			
		||||
     directive); and
 | 
			
		||||
vii. other similar, equivalent or corresponding rights throughout the
 | 
			
		||||
     world based on applicable law or treaty, and any national
 | 
			
		||||
     implementations thereof.
 | 
			
		||||
 | 
			
		||||
2. Waiver. To the greatest extent permitted by, but not in contravention
 | 
			
		||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
 | 
			
		||||
irrevocably and unconditionally waives, abandons, and surrenders all of
 | 
			
		||||
Affirmer's Copyright and Related Rights and associated claims and causes
 | 
			
		||||
of action, whether now known or unknown (including existing as well as
 | 
			
		||||
future claims and causes of action), in the Work (i) in all territories
 | 
			
		||||
worldwide, (ii) for the maximum duration provided by applicable law or
 | 
			
		||||
treaty (including future time extensions), (iii) in any current or future
 | 
			
		||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
 | 
			
		||||
including without limitation commercial, advertising or promotional
 | 
			
		||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
 | 
			
		||||
member of the public at large and to the detriment of Affirmer's heirs and
 | 
			
		||||
successors, fully intending that such Waiver shall not be subject to
 | 
			
		||||
revocation, rescission, cancellation, termination, or any other legal or
 | 
			
		||||
equitable action to disrupt the quiet enjoyment of the Work by the public
 | 
			
		||||
as contemplated by Affirmer's express Statement of Purpose.
 | 
			
		||||
 | 
			
		||||
3. Public License Fallback. Should any part of the Waiver for any reason
 | 
			
		||||
be judged legally invalid or ineffective under applicable law, then the
 | 
			
		||||
Waiver shall be preserved to the maximum extent permitted taking into
 | 
			
		||||
account Affirmer's express Statement of Purpose. In addition, to the
 | 
			
		||||
extent the Waiver is so judged Affirmer hereby grants to each affected
 | 
			
		||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
 | 
			
		||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
 | 
			
		||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
 | 
			
		||||
maximum duration provided by applicable law or treaty (including future
 | 
			
		||||
time extensions), (iii) in any current or future medium and for any number
 | 
			
		||||
of copies, and (iv) for any purpose whatsoever, including without
 | 
			
		||||
limitation commercial, advertising or promotional purposes (the
 | 
			
		||||
"License"). The License shall be deemed effective as of the date CC0 was
 | 
			
		||||
applied by Affirmer to the Work. Should any part of the License for any
 | 
			
		||||
reason be judged legally invalid or ineffective under applicable law, such
 | 
			
		||||
partial invalidity or ineffectiveness shall not invalidate the remainder
 | 
			
		||||
of the License, and in such case Affirmer hereby affirms that he or she
 | 
			
		||||
will not (i) exercise any of his or her remaining Copyright and Related
 | 
			
		||||
Rights in the Work or (ii) assert any associated claims and causes of
 | 
			
		||||
action with respect to the Work, in either case contrary to Affirmer's
 | 
			
		||||
express Statement of Purpose.
 | 
			
		||||
 | 
			
		||||
4. Limitations and Disclaimers.
 | 
			
		||||
 | 
			
		||||
 a. No trademark or patent rights held by Affirmer are waived, abandoned,
 | 
			
		||||
    surrendered, licensed or otherwise affected by this document.
 | 
			
		||||
 b. Affirmer offers the Work as-is and makes no representations or
 | 
			
		||||
    warranties of any kind concerning the Work, express, implied,
 | 
			
		||||
    statutory or otherwise, including without limitation warranties of
 | 
			
		||||
    title, merchantability, fitness for a particular purpose, non
 | 
			
		||||
    infringement, or the absence of latent or other defects, accuracy, or
 | 
			
		||||
    the present or absence of errors, whether or not discoverable, all to
 | 
			
		||||
    the greatest extent permissible under applicable law.
 | 
			
		||||
 c. Affirmer disclaims responsibility for clearing rights of other persons
 | 
			
		||||
    that may apply to the Work or any use thereof, including without
 | 
			
		||||
    limitation any person's Copyright and Related Rights in the Work.
 | 
			
		||||
    Further, Affirmer disclaims responsibility for obtaining any necessary
 | 
			
		||||
    consents, permissions or other rights required for any use of the
 | 
			
		||||
    Work.
 | 
			
		||||
 d. Affirmer understands and acknowledges that Creative Commons is not a
 | 
			
		||||
    party to this document and has no duty or obligation with respect to
 | 
			
		||||
    this CC0 or use of the Work.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4,7 +4,10 @@
 | 
			
		|||
 | 
			
		||||
package blake2b
 | 
			
		||||
 | 
			
		||||
import "encoding/binary"
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"math/bits"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// the precomputed values for BLAKE2b
 | 
			
		||||
// there are 12 16-byte arrays - one for each round
 | 
			
		||||
| 
						 | 
				
			
			@ -51,118 +54,118 @@ func hashBlocksGeneric(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) {
 | 
			
		|||
			v0 += m[s[0]]
 | 
			
		||||
			v0 += v4
 | 
			
		||||
			v12 ^= v0
 | 
			
		||||
			v12 = v12<<(64-32) | v12>>32
 | 
			
		||||
			v12 = bits.RotateLeft64(v12, -32)
 | 
			
		||||
			v8 += v12
 | 
			
		||||
			v4 ^= v8
 | 
			
		||||
			v4 = v4<<(64-24) | v4>>24
 | 
			
		||||
			v4 = bits.RotateLeft64(v4, -24)
 | 
			
		||||
			v1 += m[s[1]]
 | 
			
		||||
			v1 += v5
 | 
			
		||||
			v13 ^= v1
 | 
			
		||||
			v13 = v13<<(64-32) | v13>>32
 | 
			
		||||
			v13 = bits.RotateLeft64(v13, -32)
 | 
			
		||||
			v9 += v13
 | 
			
		||||
			v5 ^= v9
 | 
			
		||||
			v5 = v5<<(64-24) | v5>>24
 | 
			
		||||
			v5 = bits.RotateLeft64(v5, -24)
 | 
			
		||||
			v2 += m[s[2]]
 | 
			
		||||
			v2 += v6
 | 
			
		||||
			v14 ^= v2
 | 
			
		||||
			v14 = v14<<(64-32) | v14>>32
 | 
			
		||||
			v14 = bits.RotateLeft64(v14, -32)
 | 
			
		||||
			v10 += v14
 | 
			
		||||
			v6 ^= v10
 | 
			
		||||
			v6 = v6<<(64-24) | v6>>24
 | 
			
		||||
			v6 = bits.RotateLeft64(v6, -24)
 | 
			
		||||
			v3 += m[s[3]]
 | 
			
		||||
			v3 += v7
 | 
			
		||||
			v15 ^= v3
 | 
			
		||||
			v15 = v15<<(64-32) | v15>>32
 | 
			
		||||
			v15 = bits.RotateLeft64(v15, -32)
 | 
			
		||||
			v11 += v15
 | 
			
		||||
			v7 ^= v11
 | 
			
		||||
			v7 = v7<<(64-24) | v7>>24
 | 
			
		||||
			v7 = bits.RotateLeft64(v7, -24)
 | 
			
		||||
 | 
			
		||||
			v0 += m[s[4]]
 | 
			
		||||
			v0 += v4
 | 
			
		||||
			v12 ^= v0
 | 
			
		||||
			v12 = v12<<(64-16) | v12>>16
 | 
			
		||||
			v12 = bits.RotateLeft64(v12, -16)
 | 
			
		||||
			v8 += v12
 | 
			
		||||
			v4 ^= v8
 | 
			
		||||
			v4 = v4<<(64-63) | v4>>63
 | 
			
		||||
			v4 = bits.RotateLeft64(v4, -63)
 | 
			
		||||
			v1 += m[s[5]]
 | 
			
		||||
			v1 += v5
 | 
			
		||||
			v13 ^= v1
 | 
			
		||||
			v13 = v13<<(64-16) | v13>>16
 | 
			
		||||
			v13 = bits.RotateLeft64(v13, -16)
 | 
			
		||||
			v9 += v13
 | 
			
		||||
			v5 ^= v9
 | 
			
		||||
			v5 = v5<<(64-63) | v5>>63
 | 
			
		||||
			v5 = bits.RotateLeft64(v5, -63)
 | 
			
		||||
			v2 += m[s[6]]
 | 
			
		||||
			v2 += v6
 | 
			
		||||
			v14 ^= v2
 | 
			
		||||
			v14 = v14<<(64-16) | v14>>16
 | 
			
		||||
			v14 = bits.RotateLeft64(v14, -16)
 | 
			
		||||
			v10 += v14
 | 
			
		||||
			v6 ^= v10
 | 
			
		||||
			v6 = v6<<(64-63) | v6>>63
 | 
			
		||||
			v6 = bits.RotateLeft64(v6, -63)
 | 
			
		||||
			v3 += m[s[7]]
 | 
			
		||||
			v3 += v7
 | 
			
		||||
			v15 ^= v3
 | 
			
		||||
			v15 = v15<<(64-16) | v15>>16
 | 
			
		||||
			v15 = bits.RotateLeft64(v15, -16)
 | 
			
		||||
			v11 += v15
 | 
			
		||||
			v7 ^= v11
 | 
			
		||||
			v7 = v7<<(64-63) | v7>>63
 | 
			
		||||
			v7 = bits.RotateLeft64(v7, -63)
 | 
			
		||||
 | 
			
		||||
			v0 += m[s[8]]
 | 
			
		||||
			v0 += v5
 | 
			
		||||
			v15 ^= v0
 | 
			
		||||
			v15 = v15<<(64-32) | v15>>32
 | 
			
		||||
			v15 = bits.RotateLeft64(v15, -32)
 | 
			
		||||
			v10 += v15
 | 
			
		||||
			v5 ^= v10
 | 
			
		||||
			v5 = v5<<(64-24) | v5>>24
 | 
			
		||||
			v5 = bits.RotateLeft64(v5, -24)
 | 
			
		||||
			v1 += m[s[9]]
 | 
			
		||||
			v1 += v6
 | 
			
		||||
			v12 ^= v1
 | 
			
		||||
			v12 = v12<<(64-32) | v12>>32
 | 
			
		||||
			v12 = bits.RotateLeft64(v12, -32)
 | 
			
		||||
			v11 += v12
 | 
			
		||||
			v6 ^= v11
 | 
			
		||||
			v6 = v6<<(64-24) | v6>>24
 | 
			
		||||
			v6 = bits.RotateLeft64(v6, -24)
 | 
			
		||||
			v2 += m[s[10]]
 | 
			
		||||
			v2 += v7
 | 
			
		||||
			v13 ^= v2
 | 
			
		||||
			v13 = v13<<(64-32) | v13>>32
 | 
			
		||||
			v13 = bits.RotateLeft64(v13, -32)
 | 
			
		||||
			v8 += v13
 | 
			
		||||
			v7 ^= v8
 | 
			
		||||
			v7 = v7<<(64-24) | v7>>24
 | 
			
		||||
			v7 = bits.RotateLeft64(v7, -24)
 | 
			
		||||
			v3 += m[s[11]]
 | 
			
		||||
			v3 += v4
 | 
			
		||||
			v14 ^= v3
 | 
			
		||||
			v14 = v14<<(64-32) | v14>>32
 | 
			
		||||
			v14 = bits.RotateLeft64(v14, -32)
 | 
			
		||||
			v9 += v14
 | 
			
		||||
			v4 ^= v9
 | 
			
		||||
			v4 = v4<<(64-24) | v4>>24
 | 
			
		||||
			v4 = bits.RotateLeft64(v4, -24)
 | 
			
		||||
 | 
			
		||||
			v0 += m[s[12]]
 | 
			
		||||
			v0 += v5
 | 
			
		||||
			v15 ^= v0
 | 
			
		||||
			v15 = v15<<(64-16) | v15>>16
 | 
			
		||||
			v15 = bits.RotateLeft64(v15, -16)
 | 
			
		||||
			v10 += v15
 | 
			
		||||
			v5 ^= v10
 | 
			
		||||
			v5 = v5<<(64-63) | v5>>63
 | 
			
		||||
			v5 = bits.RotateLeft64(v5, -63)
 | 
			
		||||
			v1 += m[s[13]]
 | 
			
		||||
			v1 += v6
 | 
			
		||||
			v12 ^= v1
 | 
			
		||||
			v12 = v12<<(64-16) | v12>>16
 | 
			
		||||
			v12 = bits.RotateLeft64(v12, -16)
 | 
			
		||||
			v11 += v12
 | 
			
		||||
			v6 ^= v11
 | 
			
		||||
			v6 = v6<<(64-63) | v6>>63
 | 
			
		||||
			v6 = bits.RotateLeft64(v6, -63)
 | 
			
		||||
			v2 += m[s[14]]
 | 
			
		||||
			v2 += v7
 | 
			
		||||
			v13 ^= v2
 | 
			
		||||
			v13 = v13<<(64-16) | v13>>16
 | 
			
		||||
			v13 = bits.RotateLeft64(v13, -16)
 | 
			
		||||
			v8 += v13
 | 
			
		||||
			v7 ^= v8
 | 
			
		||||
			v7 = v7<<(64-63) | v7>>63
 | 
			
		||||
			v7 = bits.RotateLeft64(v7, -63)
 | 
			
		||||
			v3 += m[s[15]]
 | 
			
		||||
			v3 += v4
 | 
			
		||||
			v14 ^= v3
 | 
			
		||||
			v14 = v14<<(64-16) | v14>>16
 | 
			
		||||
			v14 = bits.RotateLeft64(v14, -16)
 | 
			
		||||
			v9 += v14
 | 
			
		||||
			v4 ^= v9
 | 
			
		||||
			v4 = v4<<(64-63) | v4>>63
 | 
			
		||||
			v4 = bits.RotateLeft64(v4, -63)
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,7 @@ package scrypt // import "golang.org/x/crypto/scrypt"
 | 
			
		|||
import (
 | 
			
		||||
	"crypto/sha256"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"math/bits"
 | 
			
		||||
 | 
			
		||||
	"golang.org/x/crypto/pbkdf2"
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -52,77 +53,45 @@ func salsaXOR(tmp *[16]uint32, in, out []uint32) {
 | 
			
		|||
	x9, x10, x11, x12, x13, x14, x15 := w9, w10, w11, w12, w13, w14, w15
 | 
			
		||||
 | 
			
		||||
	for i := 0; i < 8; i += 2 {
 | 
			
		||||
		u := x0 + x12
 | 
			
		||||
		x4 ^= u<<7 | u>>(32-7)
 | 
			
		||||
		u = x4 + x0
 | 
			
		||||
		x8 ^= u<<9 | u>>(32-9)
 | 
			
		||||
		u = x8 + x4
 | 
			
		||||
		x12 ^= u<<13 | u>>(32-13)
 | 
			
		||||
		u = x12 + x8
 | 
			
		||||
		x0 ^= u<<18 | u>>(32-18)
 | 
			
		||||
		x4 ^= bits.RotateLeft32(x0+x12, 7)
 | 
			
		||||
		x8 ^= bits.RotateLeft32(x4+x0, 9)
 | 
			
		||||
		x12 ^= bits.RotateLeft32(x8+x4, 13)
 | 
			
		||||
		x0 ^= bits.RotateLeft32(x12+x8, 18)
 | 
			
		||||
 | 
			
		||||
		u = x5 + x1
 | 
			
		||||
		x9 ^= u<<7 | u>>(32-7)
 | 
			
		||||
		u = x9 + x5
 | 
			
		||||
		x13 ^= u<<9 | u>>(32-9)
 | 
			
		||||
		u = x13 + x9
 | 
			
		||||
		x1 ^= u<<13 | u>>(32-13)
 | 
			
		||||
		u = x1 + x13
 | 
			
		||||
		x5 ^= u<<18 | u>>(32-18)
 | 
			
		||||
		x9 ^= bits.RotateLeft32(x5+x1, 7)
 | 
			
		||||
		x13 ^= bits.RotateLeft32(x9+x5, 9)
 | 
			
		||||
		x1 ^= bits.RotateLeft32(x13+x9, 13)
 | 
			
		||||
		x5 ^= bits.RotateLeft32(x1+x13, 18)
 | 
			
		||||
 | 
			
		||||
		u = x10 + x6
 | 
			
		||||
		x14 ^= u<<7 | u>>(32-7)
 | 
			
		||||
		u = x14 + x10
 | 
			
		||||
		x2 ^= u<<9 | u>>(32-9)
 | 
			
		||||
		u = x2 + x14
 | 
			
		||||
		x6 ^= u<<13 | u>>(32-13)
 | 
			
		||||
		u = x6 + x2
 | 
			
		||||
		x10 ^= u<<18 | u>>(32-18)
 | 
			
		||||
		x14 ^= bits.RotateLeft32(x10+x6, 7)
 | 
			
		||||
		x2 ^= bits.RotateLeft32(x14+x10, 9)
 | 
			
		||||
		x6 ^= bits.RotateLeft32(x2+x14, 13)
 | 
			
		||||
		x10 ^= bits.RotateLeft32(x6+x2, 18)
 | 
			
		||||
 | 
			
		||||
		u = x15 + x11
 | 
			
		||||
		x3 ^= u<<7 | u>>(32-7)
 | 
			
		||||
		u = x3 + x15
 | 
			
		||||
		x7 ^= u<<9 | u>>(32-9)
 | 
			
		||||
		u = x7 + x3
 | 
			
		||||
		x11 ^= u<<13 | u>>(32-13)
 | 
			
		||||
		u = x11 + x7
 | 
			
		||||
		x15 ^= u<<18 | u>>(32-18)
 | 
			
		||||
		x3 ^= bits.RotateLeft32(x15+x11, 7)
 | 
			
		||||
		x7 ^= bits.RotateLeft32(x3+x15, 9)
 | 
			
		||||
		x11 ^= bits.RotateLeft32(x7+x3, 13)
 | 
			
		||||
		x15 ^= bits.RotateLeft32(x11+x7, 18)
 | 
			
		||||
 | 
			
		||||
		u = x0 + x3
 | 
			
		||||
		x1 ^= u<<7 | u>>(32-7)
 | 
			
		||||
		u = x1 + x0
 | 
			
		||||
		x2 ^= u<<9 | u>>(32-9)
 | 
			
		||||
		u = x2 + x1
 | 
			
		||||
		x3 ^= u<<13 | u>>(32-13)
 | 
			
		||||
		u = x3 + x2
 | 
			
		||||
		x0 ^= u<<18 | u>>(32-18)
 | 
			
		||||
		x1 ^= bits.RotateLeft32(x0+x3, 7)
 | 
			
		||||
		x2 ^= bits.RotateLeft32(x1+x0, 9)
 | 
			
		||||
		x3 ^= bits.RotateLeft32(x2+x1, 13)
 | 
			
		||||
		x0 ^= bits.RotateLeft32(x3+x2, 18)
 | 
			
		||||
 | 
			
		||||
		u = x5 + x4
 | 
			
		||||
		x6 ^= u<<7 | u>>(32-7)
 | 
			
		||||
		u = x6 + x5
 | 
			
		||||
		x7 ^= u<<9 | u>>(32-9)
 | 
			
		||||
		u = x7 + x6
 | 
			
		||||
		x4 ^= u<<13 | u>>(32-13)
 | 
			
		||||
		u = x4 + x7
 | 
			
		||||
		x5 ^= u<<18 | u>>(32-18)
 | 
			
		||||
		x6 ^= bits.RotateLeft32(x5+x4, 7)
 | 
			
		||||
		x7 ^= bits.RotateLeft32(x6+x5, 9)
 | 
			
		||||
		x4 ^= bits.RotateLeft32(x7+x6, 13)
 | 
			
		||||
		x5 ^= bits.RotateLeft32(x4+x7, 18)
 | 
			
		||||
 | 
			
		||||
		u = x10 + x9
 | 
			
		||||
		x11 ^= u<<7 | u>>(32-7)
 | 
			
		||||
		u = x11 + x10
 | 
			
		||||
		x8 ^= u<<9 | u>>(32-9)
 | 
			
		||||
		u = x8 + x11
 | 
			
		||||
		x9 ^= u<<13 | u>>(32-13)
 | 
			
		||||
		u = x9 + x8
 | 
			
		||||
		x10 ^= u<<18 | u>>(32-18)
 | 
			
		||||
		x11 ^= bits.RotateLeft32(x10+x9, 7)
 | 
			
		||||
		x8 ^= bits.RotateLeft32(x11+x10, 9)
 | 
			
		||||
		x9 ^= bits.RotateLeft32(x8+x11, 13)
 | 
			
		||||
		x10 ^= bits.RotateLeft32(x9+x8, 18)
 | 
			
		||||
 | 
			
		||||
		u = x15 + x14
 | 
			
		||||
		x12 ^= u<<7 | u>>(32-7)
 | 
			
		||||
		u = x12 + x15
 | 
			
		||||
		x13 ^= u<<9 | u>>(32-9)
 | 
			
		||||
		u = x13 + x12
 | 
			
		||||
		x14 ^= u<<13 | u>>(32-13)
 | 
			
		||||
		u = x14 + x13
 | 
			
		||||
		x15 ^= u<<18 | u>>(32-18)
 | 
			
		||||
		x12 ^= bits.RotateLeft32(x15+x14, 7)
 | 
			
		||||
		x13 ^= bits.RotateLeft32(x12+x15, 9)
 | 
			
		||||
		x14 ^= bits.RotateLeft32(x13+x12, 13)
 | 
			
		||||
		x15 ^= bits.RotateLeft32(x14+x13, 18)
 | 
			
		||||
	}
 | 
			
		||||
	x0 += w0
 | 
			
		||||
	x1 += w1
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//+build gccgo appengine !s390x
 | 
			
		||||
// +build gccgo appengine !s390x
 | 
			
		||||
 | 
			
		||||
package sha3
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,8 +38,9 @@ type state struct {
 | 
			
		|||
	// [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf
 | 
			
		||||
	//     "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and
 | 
			
		||||
	//      Extendable-Output Functions (May 2014)"
 | 
			
		||||
	dsbyte  byte
 | 
			
		||||
	storage [maxRate]byte
 | 
			
		||||
	dsbyte byte
 | 
			
		||||
 | 
			
		||||
	storage storageBuf
 | 
			
		||||
 | 
			
		||||
	// Specific to SHA-3 and SHAKE.
 | 
			
		||||
	outputLen int             // the default output size in bytes
 | 
			
		||||
| 
						 | 
				
			
			@ -60,15 +61,15 @@ func (d *state) Reset() {
 | 
			
		|||
		d.a[i] = 0
 | 
			
		||||
	}
 | 
			
		||||
	d.state = spongeAbsorbing
 | 
			
		||||
	d.buf = d.storage[:0]
 | 
			
		||||
	d.buf = d.storage.asBytes()[:0]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (d *state) clone() *state {
 | 
			
		||||
	ret := *d
 | 
			
		||||
	if ret.state == spongeAbsorbing {
 | 
			
		||||
		ret.buf = ret.storage[:len(ret.buf)]
 | 
			
		||||
		ret.buf = ret.storage.asBytes()[:len(ret.buf)]
 | 
			
		||||
	} else {
 | 
			
		||||
		ret.buf = ret.storage[d.rate-cap(d.buf) : d.rate]
 | 
			
		||||
		ret.buf = ret.storage.asBytes()[d.rate-cap(d.buf) : d.rate]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &ret
 | 
			
		||||
| 
						 | 
				
			
			@ -82,13 +83,13 @@ func (d *state) permute() {
 | 
			
		|||
		// If we're absorbing, we need to xor the input into the state
 | 
			
		||||
		// before applying the permutation.
 | 
			
		||||
		xorIn(d, d.buf)
 | 
			
		||||
		d.buf = d.storage[:0]
 | 
			
		||||
		d.buf = d.storage.asBytes()[:0]
 | 
			
		||||
		keccakF1600(&d.a)
 | 
			
		||||
	case spongeSqueezing:
 | 
			
		||||
		// If we're squeezing, we need to apply the permutatin before
 | 
			
		||||
		// copying more output.
 | 
			
		||||
		keccakF1600(&d.a)
 | 
			
		||||
		d.buf = d.storage[:d.rate]
 | 
			
		||||
		d.buf = d.storage.asBytes()[:d.rate]
 | 
			
		||||
		copyOut(d, d.buf)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +98,7 @@ func (d *state) permute() {
 | 
			
		|||
// the multi-bitrate 10..1 padding rule, and permutes the state.
 | 
			
		||||
func (d *state) padAndPermute(dsbyte byte) {
 | 
			
		||||
	if d.buf == nil {
 | 
			
		||||
		d.buf = d.storage[:0]
 | 
			
		||||
		d.buf = d.storage.asBytes()[:0]
 | 
			
		||||
	}
 | 
			
		||||
	// Pad with this instance's domain-separator bits. We know that there's
 | 
			
		||||
	// at least one byte of space in d.buf because, if it were full,
 | 
			
		||||
| 
						 | 
				
			
			@ -105,7 +106,7 @@ func (d *state) padAndPermute(dsbyte byte) {
 | 
			
		|||
	// first one bit for the padding. See the comment in the state struct.
 | 
			
		||||
	d.buf = append(d.buf, dsbyte)
 | 
			
		||||
	zerosStart := len(d.buf)
 | 
			
		||||
	d.buf = d.storage[:d.rate]
 | 
			
		||||
	d.buf = d.storage.asBytes()[:d.rate]
 | 
			
		||||
	for i := zerosStart; i < d.rate; i++ {
 | 
			
		||||
		d.buf[i] = 0
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -116,7 +117,7 @@ func (d *state) padAndPermute(dsbyte byte) {
 | 
			
		|||
	// Apply the permutation
 | 
			
		||||
	d.permute()
 | 
			
		||||
	d.state = spongeSqueezing
 | 
			
		||||
	d.buf = d.storage[:d.rate]
 | 
			
		||||
	d.buf = d.storage.asBytes()[:d.rate]
 | 
			
		||||
	copyOut(d, d.buf)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -127,7 +128,7 @@ func (d *state) Write(p []byte) (written int, err error) {
 | 
			
		|||
		panic("sha3: write to sponge after read")
 | 
			
		||||
	}
 | 
			
		||||
	if d.buf == nil {
 | 
			
		||||
		d.buf = d.storage[:0]
 | 
			
		||||
		d.buf = d.storage.asBytes()[:0]
 | 
			
		||||
	}
 | 
			
		||||
	written = len(p)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//+build !gccgo,!appengine
 | 
			
		||||
// +build !gccgo,!appengine
 | 
			
		||||
 | 
			
		||||
package sha3
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +112,7 @@ func (s *asmState) Write(b []byte) (int, error) {
 | 
			
		|||
		if len(s.buf) == 0 && len(b) >= cap(s.buf) {
 | 
			
		||||
			// Hash the data directly and push any remaining bytes
 | 
			
		||||
			// into the buffer.
 | 
			
		||||
			remainder := len(s.buf) % s.rate
 | 
			
		||||
			remainder := len(b) % s.rate
 | 
			
		||||
			kimd(s.function, &s.a, b[:len(b)-remainder])
 | 
			
		||||
			if remainder != 0 {
 | 
			
		||||
				s.copyIntoBuf(b[len(b)-remainder:])
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//+build !gccgo,!appengine
 | 
			
		||||
// +build !gccgo,!appengine
 | 
			
		||||
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ type ShakeHash interface {
 | 
			
		|||
 | 
			
		||||
// cSHAKE specific context
 | 
			
		||||
type cshakeState struct {
 | 
			
		||||
	state // SHA-3 state context and Read/Write operations
 | 
			
		||||
	*state // SHA-3 state context and Read/Write operations
 | 
			
		||||
 | 
			
		||||
	// initBlock is the cSHAKE specific initialization set of bytes. It is initialized
 | 
			
		||||
	// by newCShake function and stores concatenation of N followed by S, encoded
 | 
			
		||||
| 
						 | 
				
			
			@ -82,7 +82,7 @@ func leftEncode(value uint64) []byte {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func newCShake(N, S []byte, rate int, dsbyte byte) ShakeHash {
 | 
			
		||||
	c := cshakeState{state: state{rate: rate, dsbyte: dsbyte}}
 | 
			
		||||
	c := cshakeState{state: &state{rate: rate, dsbyte: dsbyte}}
 | 
			
		||||
 | 
			
		||||
	// leftEncode returns max 9 bytes
 | 
			
		||||
	c.initBlock = make([]byte, 0, 9*2+len(N)+len(S))
 | 
			
		||||
| 
						 | 
				
			
			@ -104,7 +104,7 @@ func (c *cshakeState) Reset() {
 | 
			
		|||
func (c *cshakeState) Clone() ShakeHash {
 | 
			
		||||
	b := make([]byte, len(c.initBlock))
 | 
			
		||||
	copy(b, c.initBlock)
 | 
			
		||||
	return &cshakeState{state: *c.clone(), initBlock: b}
 | 
			
		||||
	return &cshakeState{state: c.clone(), initBlock: b}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Clone returns copy of SHAKE context within its current state.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
//+build gccgo appengine !s390x
 | 
			
		||||
// +build gccgo appengine !s390x
 | 
			
		||||
 | 
			
		||||
package sha3
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,13 @@
 | 
			
		|||
 | 
			
		||||
package sha3
 | 
			
		||||
 | 
			
		||||
// A storageBuf is an aligned array of maxRate bytes.
 | 
			
		||||
type storageBuf [maxRate]byte
 | 
			
		||||
 | 
			
		||||
func (b *storageBuf) asBytes() *[maxRate]byte {
 | 
			
		||||
	return (*[maxRate]byte)(b)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	xorIn            = xorInGeneric
 | 
			
		||||
	copyOut          = copyOutGeneric
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,9 +9,16 @@ package sha3
 | 
			
		|||
 | 
			
		||||
import "unsafe"
 | 
			
		||||
 | 
			
		||||
// A storageBuf is an aligned array of maxRate bytes.
 | 
			
		||||
type storageBuf [maxRate / 8]uint64
 | 
			
		||||
 | 
			
		||||
func (b *storageBuf) asBytes() *[maxRate]byte {
 | 
			
		||||
	return (*[maxRate]byte)(unsafe.Pointer(b))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func xorInUnaligned(d *state, buf []byte) {
 | 
			
		||||
	bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))
 | 
			
		||||
	n := len(buf)
 | 
			
		||||
	bw := (*[maxRate / 8]uint64)(unsafe.Pointer(&buf[0]))[: n/8 : n/8]
 | 
			
		||||
	if n >= 72 {
 | 
			
		||||
		d.a[0] ^= bw[0]
 | 
			
		||||
		d.a[1] ^= bw[1]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
// Copyright 2018 The Go Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build !gccgo
 | 
			
		||||
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// System calls for ppc64, AIX are implemented in runtime/syscall_aix.go
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
TEXT ·syscall6(SB),NOSPLIT,$0-88
 | 
			
		||||
	JMP	syscall·syscall6(SB)
 | 
			
		||||
 | 
			
		||||
TEXT ·rawSyscall6(SB),NOSPLIT,$0-88
 | 
			
		||||
	JMP	syscall·rawSyscall6(SB)
 | 
			
		||||
| 
						 | 
				
			
			@ -6,8 +6,6 @@
 | 
			
		|||
 | 
			
		||||
package cpu
 | 
			
		||||
 | 
			
		||||
import "golang.org/x/sys/unix"
 | 
			
		||||
 | 
			
		||||
const cacheLineSize = 128
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +16,7 @@ const (
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	impl := unix.Getsystemcfg(_SC_IMPL)
 | 
			
		||||
	impl := getsystemcfg(_SC_IMPL)
 | 
			
		||||
	if impl&_IMPL_POWER8 != 0 {
 | 
			
		||||
		PPC64.IsPOWER8 = true
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -28,3 +26,9 @@ func init() {
 | 
			
		|||
 | 
			
		||||
	Initialized = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getsystemcfg(label int) (n uint64) {
 | 
			
		||||
	r0, _ := callgetsystemcfg(label)
 | 
			
		||||
	n = uint64(r0)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
// Copyright 2019 The Go Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// Minimal copy of x/sys/unix so the cpu package can make a
 | 
			
		||||
// system call on AIX without depending on x/sys/unix.
 | 
			
		||||
// (See golang.org/issue/32102)
 | 
			
		||||
 | 
			
		||||
// +build aix,ppc64
 | 
			
		||||
// +build !gccgo
 | 
			
		||||
 | 
			
		||||
package cpu
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//go:cgo_import_dynamic libc_getsystemcfg getsystemcfg "libc.a/shr_64.o"
 | 
			
		||||
 | 
			
		||||
//go:linkname libc_getsystemcfg libc_getsystemcfg
 | 
			
		||||
 | 
			
		||||
type syscallFunc uintptr
 | 
			
		||||
 | 
			
		||||
var libc_getsystemcfg syscallFunc
 | 
			
		||||
 | 
			
		||||
type errno = syscall.Errno
 | 
			
		||||
 | 
			
		||||
// Implemented in runtime/syscall_aix.go.
 | 
			
		||||
func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err errno)
 | 
			
		||||
func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err errno)
 | 
			
		||||
 | 
			
		||||
func callgetsystemcfg(label int) (r1 uintptr, e1 errno) {
 | 
			
		||||
	r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_getsystemcfg)), 1, uintptr(label), 0, 0, 0, 0, 0)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -7,6 +7,7 @@
 | 
			
		|||
package unix
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"math/bits"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -79,46 +80,7 @@ func (s *CPUSet) IsSet(cpu int) bool {
 | 
			
		|||
func (s *CPUSet) Count() int {
 | 
			
		||||
	c := 0
 | 
			
		||||
	for _, b := range s {
 | 
			
		||||
		c += onesCount64(uint64(b))
 | 
			
		||||
		c += bits.OnesCount64(uint64(b))
 | 
			
		||||
	}
 | 
			
		||||
	return c
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// onesCount64 is a copy of Go 1.9's math/bits.OnesCount64.
 | 
			
		||||
// Once this package can require Go 1.9, we can delete this
 | 
			
		||||
// and update the caller to use bits.OnesCount64.
 | 
			
		||||
func onesCount64(x uint64) int {
 | 
			
		||||
	const m0 = 0x5555555555555555 // 01010101 ...
 | 
			
		||||
	const m1 = 0x3333333333333333 // 00110011 ...
 | 
			
		||||
	const m2 = 0x0f0f0f0f0f0f0f0f // 00001111 ...
 | 
			
		||||
	const m3 = 0x00ff00ff00ff00ff // etc.
 | 
			
		||||
	const m4 = 0x0000ffff0000ffff
 | 
			
		||||
 | 
			
		||||
	// Implementation: Parallel summing of adjacent bits.
 | 
			
		||||
	// See "Hacker's Delight", Chap. 5: Counting Bits.
 | 
			
		||||
	// The following pattern shows the general approach:
 | 
			
		||||
	//
 | 
			
		||||
	//   x = x>>1&(m0&m) + x&(m0&m)
 | 
			
		||||
	//   x = x>>2&(m1&m) + x&(m1&m)
 | 
			
		||||
	//   x = x>>4&(m2&m) + x&(m2&m)
 | 
			
		||||
	//   x = x>>8&(m3&m) + x&(m3&m)
 | 
			
		||||
	//   x = x>>16&(m4&m) + x&(m4&m)
 | 
			
		||||
	//   x = x>>32&(m5&m) + x&(m5&m)
 | 
			
		||||
	//   return int(x)
 | 
			
		||||
	//
 | 
			
		||||
	// Masking (& operations) can be left away when there's no
 | 
			
		||||
	// danger that a field's sum will carry over into the next
 | 
			
		||||
	// field: Since the result cannot be > 64, 8 bits is enough
 | 
			
		||||
	// and we can ignore the masks for the shifts by 8 and up.
 | 
			
		||||
	// Per "Hacker's Delight", the first line can be simplified
 | 
			
		||||
	// more, but it saves at best one instruction, so we leave
 | 
			
		||||
	// it alone for clarity.
 | 
			
		||||
	const m = 1<<64 - 1
 | 
			
		||||
	x = x>>1&(m0&m) + x&(m0&m)
 | 
			
		||||
	x = x>>2&(m1&m) + x&(m1&m)
 | 
			
		||||
	x = (x>>4 + x) & (m2 & m)
 | 
			
		||||
	x += x >> 8
 | 
			
		||||
	x += x >> 16
 | 
			
		||||
	x += x >> 32
 | 
			
		||||
	return int(x) & (1<<7 - 1)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,54 @@
 | 
			
		|||
// Copyright 2019 The Go Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build riscv64,!gccgo
 | 
			
		||||
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// System calls for linux/riscv64.
 | 
			
		||||
//
 | 
			
		||||
// Where available, just jump to package syscall's implementation of
 | 
			
		||||
// these functions.
 | 
			
		||||
 | 
			
		||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
 | 
			
		||||
	JMP	syscall·Syscall(SB)
 | 
			
		||||
 | 
			
		||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
 | 
			
		||||
	JMP	syscall·Syscall6(SB)
 | 
			
		||||
 | 
			
		||||
TEXT ·SyscallNoError(SB),NOSPLIT,$0-48
 | 
			
		||||
	CALL	runtime·entersyscall(SB)
 | 
			
		||||
	MOV	a1+8(FP), A0
 | 
			
		||||
	MOV	a2+16(FP), A1
 | 
			
		||||
	MOV	a3+24(FP), A2
 | 
			
		||||
	MOV	$0, A3
 | 
			
		||||
	MOV	$0, A4
 | 
			
		||||
	MOV	$0, A5
 | 
			
		||||
	MOV	$0, A6
 | 
			
		||||
	MOV	trap+0(FP), A7	// syscall entry
 | 
			
		||||
	ECALL
 | 
			
		||||
	MOV	A0, r1+32(FP)	// r1
 | 
			
		||||
	MOV	A1, r2+40(FP)	// r2
 | 
			
		||||
	CALL	runtime·exitsyscall(SB)
 | 
			
		||||
	RET
 | 
			
		||||
 | 
			
		||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
 | 
			
		||||
	JMP	syscall·RawSyscall(SB)
 | 
			
		||||
 | 
			
		||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
 | 
			
		||||
	JMP	syscall·RawSyscall6(SB)
 | 
			
		||||
 | 
			
		||||
TEXT ·RawSyscallNoError(SB),NOSPLIT,$0-48
 | 
			
		||||
	MOV	a1+8(FP), A0
 | 
			
		||||
	MOV	a2+16(FP), A1
 | 
			
		||||
	MOV	a3+24(FP), A2
 | 
			
		||||
	MOV	ZERO, A3
 | 
			
		||||
	MOV	ZERO, A4
 | 
			
		||||
	MOV	ZERO, A5
 | 
			
		||||
	MOV	trap+0(FP), A7	// syscall entry
 | 
			
		||||
	ECALL
 | 
			
		||||
	MOV	A0, r1+32(FP)
 | 
			
		||||
	MOV	A1, r2+40(FP)
 | 
			
		||||
	RET
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
// Copyright 2019 The Go Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build !gccgo
 | 
			
		||||
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// System call support for arm64, OpenBSD
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// Just jump to package syscall's implementation for all these functions.
 | 
			
		||||
// The runtime may know about them.
 | 
			
		||||
 | 
			
		||||
TEXT	·Syscall(SB),NOSPLIT,$0-56
 | 
			
		||||
	JMP	syscall·Syscall(SB)
 | 
			
		||||
 | 
			
		||||
TEXT	·Syscall6(SB),NOSPLIT,$0-80
 | 
			
		||||
	JMP	syscall·Syscall6(SB)
 | 
			
		||||
 | 
			
		||||
TEXT	·Syscall9(SB),NOSPLIT,$0-104
 | 
			
		||||
	JMP	syscall·Syscall9(SB)
 | 
			
		||||
 | 
			
		||||
TEXT	·RawSyscall(SB),NOSPLIT,$0-56
 | 
			
		||||
	JMP	syscall·RawSyscall(SB)
 | 
			
		||||
 | 
			
		||||
TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
 | 
			
		||||
	JMP	syscall·RawSyscall6(SB)
 | 
			
		||||
| 
						 | 
				
			
			@ -2,16 +2,101 @@
 | 
			
		|||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris
 | 
			
		||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
 | 
			
		||||
 | 
			
		||||
package unix
 | 
			
		||||
 | 
			
		||||
import "syscall"
 | 
			
		||||
import "unsafe"
 | 
			
		||||
 | 
			
		||||
// readInt returns the size-bytes unsigned integer in native byte order at offset off.
 | 
			
		||||
func readInt(b []byte, off, size uintptr) (u uint64, ok bool) {
 | 
			
		||||
	if len(b) < int(off+size) {
 | 
			
		||||
		return 0, false
 | 
			
		||||
	}
 | 
			
		||||
	if isBigEndian {
 | 
			
		||||
		return readIntBE(b[off:], size), true
 | 
			
		||||
	}
 | 
			
		||||
	return readIntLE(b[off:], size), true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func readIntBE(b []byte, size uintptr) uint64 {
 | 
			
		||||
	switch size {
 | 
			
		||||
	case 1:
 | 
			
		||||
		return uint64(b[0])
 | 
			
		||||
	case 2:
 | 
			
		||||
		_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
 | 
			
		||||
		return uint64(b[1]) | uint64(b[0])<<8
 | 
			
		||||
	case 4:
 | 
			
		||||
		_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
 | 
			
		||||
		return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24
 | 
			
		||||
	case 8:
 | 
			
		||||
		_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
 | 
			
		||||
		return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
 | 
			
		||||
			uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
 | 
			
		||||
	default:
 | 
			
		||||
		panic("syscall: readInt with unsupported size")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func readIntLE(b []byte, size uintptr) uint64 {
 | 
			
		||||
	switch size {
 | 
			
		||||
	case 1:
 | 
			
		||||
		return uint64(b[0])
 | 
			
		||||
	case 2:
 | 
			
		||||
		_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
 | 
			
		||||
		return uint64(b[0]) | uint64(b[1])<<8
 | 
			
		||||
	case 4:
 | 
			
		||||
		_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
 | 
			
		||||
		return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24
 | 
			
		||||
	case 8:
 | 
			
		||||
		_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
 | 
			
		||||
		return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
 | 
			
		||||
			uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
 | 
			
		||||
	default:
 | 
			
		||||
		panic("syscall: readInt with unsupported size")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ParseDirent parses up to max directory entries in buf,
 | 
			
		||||
// appending the names to names. It returns the number of
 | 
			
		||||
// bytes consumed from buf, the number of entries added
 | 
			
		||||
// to names, and the new names slice.
 | 
			
		||||
func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
 | 
			
		||||
	return syscall.ParseDirent(buf, max, names)
 | 
			
		||||
	origlen := len(buf)
 | 
			
		||||
	count = 0
 | 
			
		||||
	for max != 0 && len(buf) > 0 {
 | 
			
		||||
		reclen, ok := direntReclen(buf)
 | 
			
		||||
		if !ok || reclen > uint64(len(buf)) {
 | 
			
		||||
			return origlen, count, names
 | 
			
		||||
		}
 | 
			
		||||
		rec := buf[:reclen]
 | 
			
		||||
		buf = buf[reclen:]
 | 
			
		||||
		ino, ok := direntIno(rec)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		if ino == 0 { // File absent in directory.
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		const namoff = uint64(unsafe.Offsetof(Dirent{}.Name))
 | 
			
		||||
		namlen, ok := direntNamlen(rec)
 | 
			
		||||
		if !ok || namoff+namlen > uint64(len(rec)) {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
		name := rec[namoff : namoff+namlen]
 | 
			
		||||
		for i, c := range name {
 | 
			
		||||
			if c == 0 {
 | 
			
		||||
				name = name[:i]
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// Check for useless names before allocating a string.
 | 
			
		||||
		if string(name) == "." || string(name) == ".." {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		max--
 | 
			
		||||
		count++
 | 
			
		||||
		names = append(names, string(name))
 | 
			
		||||
	}
 | 
			
		||||
	return origlen - len(buf), count, names
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
//
 | 
			
		||||
// +build 386 amd64 amd64p32 arm arm64 ppc64le mipsle mips64le
 | 
			
		||||
// +build 386 amd64 amd64p32 arm arm64 ppc64le mipsle mips64le riscv64
 | 
			
		||||
 | 
			
		||||
package unix
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,19 @@
 | 
			
		|||
 | 
			
		||||
package unix
 | 
			
		||||
 | 
			
		||||
import "runtime"
 | 
			
		||||
import (
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ioctl itself should not be exposed directly, but additional get/set
 | 
			
		||||
// functions for specific types are permissible.
 | 
			
		||||
 | 
			
		||||
// IoctlSetInt performs an ioctl operation which sets an integer value
 | 
			
		||||
// on fd, using the specified request number.
 | 
			
		||||
func IoctlSetInt(fd int, req uint, value int) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(value))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IoctlSetWinsize performs an ioctl on fd with a *Winsize argument.
 | 
			
		||||
//
 | 
			
		||||
| 
						 | 
				
			
			@ -14,7 +26,7 @@ import "runtime"
 | 
			
		|||
func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
 | 
			
		||||
	// TODO: if we get the chance, remove the req parameter and
 | 
			
		||||
	// hardcode TIOCSWINSZ.
 | 
			
		||||
	err := ioctlSetWinsize(fd, req, value)
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
	runtime.KeepAlive(value)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +36,30 @@ func IoctlSetWinsize(fd int, req uint, value *Winsize) error {
 | 
			
		|||
// The req value will usually be TCSETA or TIOCSETA.
 | 
			
		||||
func IoctlSetTermios(fd int, req uint, value *Termios) error {
 | 
			
		||||
	// TODO: if we get the chance, remove the req parameter.
 | 
			
		||||
	err := ioctlSetTermios(fd, req, value)
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
	runtime.KeepAlive(value)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IoctlGetInt performs an ioctl operation which gets an integer value
 | 
			
		||||
// from fd, using the specified request number.
 | 
			
		||||
//
 | 
			
		||||
// A few ioctl requests use the return value as an output parameter;
 | 
			
		||||
// for those, IoctlRetInt should be used instead of this function.
 | 
			
		||||
func IoctlGetInt(fd int, req uint) (int, error) {
 | 
			
		||||
	var value int
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
 | 
			
		||||
	var value Winsize
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 | 
			
		||||
	var value Termios
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -105,25 +105,25 @@ dragonfly_amd64)
 | 
			
		|||
freebsd_386)
 | 
			
		||||
	mkerrors="$mkerrors -m32"
 | 
			
		||||
	mksyscall="go run mksyscall.go -l32"
 | 
			
		||||
	mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master'"
 | 
			
		||||
	mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
 | 
			
		||||
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
 | 
			
		||||
	;;
 | 
			
		||||
freebsd_amd64)
 | 
			
		||||
	mkerrors="$mkerrors -m64"
 | 
			
		||||
	mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master'"
 | 
			
		||||
	mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
 | 
			
		||||
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
 | 
			
		||||
	;;
 | 
			
		||||
freebsd_arm)
 | 
			
		||||
	mkerrors="$mkerrors"
 | 
			
		||||
	mksyscall="go run mksyscall.go -l32 -arm"
 | 
			
		||||
	mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master'"
 | 
			
		||||
	mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
 | 
			
		||||
	# Let the type of C char be signed for making the bare syscall
 | 
			
		||||
	# API consistent across platforms.
 | 
			
		||||
	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
 | 
			
		||||
	;;
 | 
			
		||||
freebsd_arm64)
 | 
			
		||||
	mkerrors="$mkerrors -m64"
 | 
			
		||||
	mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master'"
 | 
			
		||||
	mksysnum="go run mksysnum.go 'https://svn.freebsd.org/base/stable/11/sys/kern/syscalls.master'"
 | 
			
		||||
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
 | 
			
		||||
	;;
 | 
			
		||||
netbsd_386)
 | 
			
		||||
| 
						 | 
				
			
			@ -146,24 +146,39 @@ netbsd_arm)
 | 
			
		|||
	# API consistent across platforms.
 | 
			
		||||
	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
 | 
			
		||||
	;;
 | 
			
		||||
netbsd_arm64)
 | 
			
		||||
	mkerrors="$mkerrors -m64"
 | 
			
		||||
	mksyscall="go run mksyscall.go -netbsd"
 | 
			
		||||
	mksysnum="go run mksysnum.go 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master'"
 | 
			
		||||
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
 | 
			
		||||
	;;
 | 
			
		||||
openbsd_386)
 | 
			
		||||
	mkerrors="$mkerrors -m32"
 | 
			
		||||
	mksyscall="go run mksyscall.go -l32 -openbsd"
 | 
			
		||||
	mksysctl="./mksysctl_openbsd.pl"
 | 
			
		||||
	mksysctl="go run mksysctl_openbsd.go"
 | 
			
		||||
	mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
 | 
			
		||||
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
 | 
			
		||||
	;;
 | 
			
		||||
openbsd_amd64)
 | 
			
		||||
	mkerrors="$mkerrors -m64"
 | 
			
		||||
	mksyscall="go run mksyscall.go -openbsd"
 | 
			
		||||
	mksysctl="./mksysctl_openbsd.pl"
 | 
			
		||||
	mksysctl="go run mksysctl_openbsd.go"
 | 
			
		||||
	mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
 | 
			
		||||
	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
 | 
			
		||||
	;;
 | 
			
		||||
openbsd_arm)
 | 
			
		||||
	mkerrors="$mkerrors"
 | 
			
		||||
	mksyscall="go run mksyscall.go -l32 -openbsd -arm"
 | 
			
		||||
	mksysctl="./mksysctl_openbsd.pl"
 | 
			
		||||
	mksysctl="go run mksysctl_openbsd.go"
 | 
			
		||||
	mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
 | 
			
		||||
	# Let the type of C char be signed for making the bare syscall
 | 
			
		||||
	# API consistent across platforms.
 | 
			
		||||
	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
 | 
			
		||||
	;;
 | 
			
		||||
openbsd_arm64)
 | 
			
		||||
	mkerrors="$mkerrors -m64"
 | 
			
		||||
	mksyscall="go run mksyscall.go -openbsd"
 | 
			
		||||
	mksysctl="go run mksysctl_openbsd.go"
 | 
			
		||||
	mksysnum="go run mksysnum.go 'https://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master'"
 | 
			
		||||
	# Let the type of C char be signed for making the bare syscall
 | 
			
		||||
	# API consistent across platforms.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -182,6 +182,8 @@ struct ltchars {
 | 
			
		|||
#include <sys/signalfd.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/xattr.h>
 | 
			
		||||
#include <linux/bpf.h>
 | 
			
		||||
#include <linux/capability.h>
 | 
			
		||||
#include <linux/errqueue.h>
 | 
			
		||||
#include <linux/if.h>
 | 
			
		||||
#include <linux/if_alg.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -197,12 +199,14 @@ struct ltchars {
 | 
			
		|||
#include <linux/fs.h>
 | 
			
		||||
#include <linux/kexec.h>
 | 
			
		||||
#include <linux/keyctl.h>
 | 
			
		||||
#include <linux/loop.h>
 | 
			
		||||
#include <linux/magic.h>
 | 
			
		||||
#include <linux/memfd.h>
 | 
			
		||||
#include <linux/module.h>
 | 
			
		||||
#include <linux/netfilter/nfnetlink.h>
 | 
			
		||||
#include <linux/netlink.h>
 | 
			
		||||
#include <linux/net_namespace.h>
 | 
			
		||||
#include <linux/nsfs.h>
 | 
			
		||||
#include <linux/perf_event.h>
 | 
			
		||||
#include <linux/random.h>
 | 
			
		||||
#include <linux/reboot.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -222,6 +226,7 @@ struct ltchars {
 | 
			
		|||
#include <linux/hdreg.h>
 | 
			
		||||
#include <linux/rtc.h>
 | 
			
		||||
#include <linux/if_xdp.h>
 | 
			
		||||
#include <linux/cryptouser.h>
 | 
			
		||||
#include <mtd/ubi-user.h>
 | 
			
		||||
#include <net/route.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -432,7 +437,9 @@ ccflags="$@"
 | 
			
		|||
		$2 ~ /^TC[IO](ON|OFF)$/ ||
 | 
			
		||||
		$2 ~ /^IN_/ ||
 | 
			
		||||
		$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
 | 
			
		||||
		$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|EVFILT|NOTE|EV|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
 | 
			
		||||
		$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
 | 
			
		||||
		$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
 | 
			
		||||
		$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|MCAST|EVFILT|NOTE|EV|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR)_/ ||
 | 
			
		||||
		$2 ~ /^TP_STATUS_/ ||
 | 
			
		||||
		$2 ~ /^FALLOC_/ ||
 | 
			
		||||
		$2 == "ICMPV6_FILTER" ||
 | 
			
		||||
| 
						 | 
				
			
			@ -445,6 +452,7 @@ ccflags="$@"
 | 
			
		|||
		$2 ~ /^SYSCTL_VERS/ ||
 | 
			
		||||
		$2 !~ "MNT_BITS" &&
 | 
			
		||||
		$2 ~ /^(MS|MNT|UMOUNT)_/ ||
 | 
			
		||||
		$2 ~ /^NS_GET_/ ||
 | 
			
		||||
		$2 ~ /^TUN(SET|GET|ATTACH|DETACH)/ ||
 | 
			
		||||
		$2 ~ /^(O|F|[ES]?FD|NAME|S|PTRACE|PT)_/ ||
 | 
			
		||||
		$2 ~ /^KEXEC_/ ||
 | 
			
		||||
| 
						 | 
				
			
			@ -465,7 +473,7 @@ ccflags="$@"
 | 
			
		|||
		$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|LOCKS|MEMLOCK|MSGQUEUE|NICE|NOFILE|NPROC|RSS|RTPRIO|RTTIME|SIGPENDING|STACK)|RLIM_INFINITY/ ||
 | 
			
		||||
		$2 ~ /^PRIO_(PROCESS|PGRP|USER)/ ||
 | 
			
		||||
		$2 ~ /^CLONE_[A-Z_]+/ ||
 | 
			
		||||
		$2 !~ /^(BPF_TIMEVAL)$/ &&
 | 
			
		||||
		$2 !~ /^(BPF_TIMEVAL|BPF_FIB_LOOKUP_[A-Z]+)$/ &&
 | 
			
		||||
		$2 ~ /^(BPF|DLT)_/ ||
 | 
			
		||||
		$2 ~ /^(CLOCK|TIMER)_/ ||
 | 
			
		||||
		$2 ~ /^CAN_/ ||
 | 
			
		||||
| 
						 | 
				
			
			@ -499,6 +507,7 @@ ccflags="$@"
 | 
			
		|||
		$2 ~ /^NFN/ ||
 | 
			
		||||
		$2 ~ /^XDP_/ ||
 | 
			
		||||
		$2 ~ /^(HDIO|WIN|SMART)_/ ||
 | 
			
		||||
		$2 ~ /^CRYPTO_/ ||
 | 
			
		||||
		$2 !~ "WMESGLEN" &&
 | 
			
		||||
		$2 ~ /^W[A-Z0-9]+$/ ||
 | 
			
		||||
		$2 ~/^PPPIOC/ ||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,9 +42,16 @@ func main() {
 | 
			
		|||
		log.Fatal(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if goos == "aix" {
 | 
			
		||||
		// Replace type of Atim, Mtim and Ctim by Timespec in Stat_t
 | 
			
		||||
		// to avoid having both StTimespec and Timespec.
 | 
			
		||||
		sttimespec := regexp.MustCompile(`_Ctype_struct_st_timespec`)
 | 
			
		||||
		b = sttimespec.ReplaceAll(b, []byte("Timespec"))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Intentionally export __val fields in Fsid and Sigset_t
 | 
			
		||||
	valRegex := regexp.MustCompile(`type (Fsid|Sigset_t) struct {(\s+)X__val(\s+\S+\s+)}`)
 | 
			
		||||
	b = valRegex.ReplaceAll(b, []byte("type $1 struct {${2}Val$3}"))
 | 
			
		||||
	valRegex := regexp.MustCompile(`type (Fsid|Sigset_t) struct {(\s+)X__(bits|val)(\s+\S+\s+)}`)
 | 
			
		||||
	b = valRegex.ReplaceAll(b, []byte("type $1 struct {${2}Val$4}"))
 | 
			
		||||
 | 
			
		||||
	// Intentionally export __fds_bits field in FdSet
 | 
			
		||||
	fdSetRegex := regexp.MustCompile(`type (FdSet) struct {(\s+)X__fds_bits(\s+\S+\s+)}`)
 | 
			
		||||
| 
						 | 
				
			
			@ -96,6 +103,15 @@ func main() {
 | 
			
		|||
	cgoCommandRegex := regexp.MustCompile(`(cgo -godefs .*)`)
 | 
			
		||||
	b = cgoCommandRegex.ReplaceAll(b, []byte(replacement))
 | 
			
		||||
 | 
			
		||||
	// Rename Stat_t time fields
 | 
			
		||||
	if goos == "freebsd" && goarch == "386" {
 | 
			
		||||
		// Hide Stat_t.[AMCB]tim_ext fields
 | 
			
		||||
		renameStatTimeExtFieldsRegex := regexp.MustCompile(`[AMCB]tim_ext`)
 | 
			
		||||
		b = renameStatTimeExtFieldsRegex.ReplaceAll(b, []byte("_"))
 | 
			
		||||
	}
 | 
			
		||||
	renameStatTimeFieldsRegex := regexp.MustCompile(`([AMCB])(?:irth)?time?(?:spec)?\s+(Timespec|StTimespec)`)
 | 
			
		||||
	b = renameStatTimeFieldsRegex.ReplaceAll(b, []byte("${1}tim ${2}"))
 | 
			
		||||
 | 
			
		||||
	// gofmt
 | 
			
		||||
	b, err = format.Source(b)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -214,6 +214,11 @@ func main() {
 | 
			
		|||
			}
 | 
			
		||||
 | 
			
		||||
			if funct != "fcntl" && funct != "FcntlInt" && funct != "readlen" && funct != "writelen" {
 | 
			
		||||
				if sysname == "select" {
 | 
			
		||||
					// select is a keyword of Go. Its name is
 | 
			
		||||
					// changed to c_select.
 | 
			
		||||
					cExtern += "#define c_select select\n"
 | 
			
		||||
				}
 | 
			
		||||
				// Imports of system calls from libc
 | 
			
		||||
				cExtern += fmt.Sprintf("%s %s", cRettype, sysname)
 | 
			
		||||
				cIn := strings.Join(cIn, ", ")
 | 
			
		||||
| 
						 | 
				
			
			@ -328,7 +333,13 @@ func main() {
 | 
			
		|||
			} else {
 | 
			
		||||
				call += ""
 | 
			
		||||
			}
 | 
			
		||||
			call += fmt.Sprintf("C.%s(%s)", sysname, arglist)
 | 
			
		||||
			if sysname == "select" {
 | 
			
		||||
				// select is a keyword of Go. Its name is
 | 
			
		||||
				// changed to c_select.
 | 
			
		||||
				call += fmt.Sprintf("C.c_%s(%s)", sysname, arglist)
 | 
			
		||||
			} else {
 | 
			
		||||
				call += fmt.Sprintf("C.%s(%s)", sysname, arglist)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Assign return values.
 | 
			
		||||
			body := ""
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -282,6 +282,11 @@ func main() {
 | 
			
		|||
			if !onlyCommon {
 | 
			
		||||
				// GCCGO Prototype Generation
 | 
			
		||||
				// Imports of system calls from libc
 | 
			
		||||
				if sysname == "select" {
 | 
			
		||||
					// select is a keyword of Go. Its name is
 | 
			
		||||
					// changed to c_select.
 | 
			
		||||
					cExtern += "#define c_select select\n"
 | 
			
		||||
				}
 | 
			
		||||
				cExtern += fmt.Sprintf("%s %s", cRettype, sysname)
 | 
			
		||||
				cIn := strings.Join(cIn, ", ")
 | 
			
		||||
				cExtern += fmt.Sprintf("(%s);\n", cIn)
 | 
			
		||||
| 
						 | 
				
			
			@ -490,7 +495,14 @@ func main() {
 | 
			
		|||
 | 
			
		||||
			// GCCGO function generation
 | 
			
		||||
			argsgccgolist := strings.Join(argsgccgo, ", ")
 | 
			
		||||
			callgccgo := fmt.Sprintf("C.%s(%s)", sysname, argsgccgolist)
 | 
			
		||||
			var callgccgo string
 | 
			
		||||
			if sysname == "select" {
 | 
			
		||||
				// select is a keyword of Go. Its name is
 | 
			
		||||
				// changed to c_select.
 | 
			
		||||
				callgccgo = fmt.Sprintf("C.c_%s(%s)", sysname, argsgccgolist)
 | 
			
		||||
			} else {
 | 
			
		||||
				callgccgo = fmt.Sprintf("C.%s(%s)", sysname, argsgccgolist)
 | 
			
		||||
			}
 | 
			
		||||
			textgccgo += callProto
 | 
			
		||||
			textgccgo += fmt.Sprintf("\tr1 = uintptr(%s)\n", callgccgo)
 | 
			
		||||
			textgccgo += "\te1 = syscall.GetErrno()\n"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,355 @@
 | 
			
		|||
// Copyright 2019 The Go Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build ignore
 | 
			
		||||
 | 
			
		||||
// Parse the header files for OpenBSD and generate a Go usable sysctl MIB.
 | 
			
		||||
//
 | 
			
		||||
// Build a MIB with each entry being an array containing the level, type and
 | 
			
		||||
// a hash that will contain additional entries if the current entry is a node.
 | 
			
		||||
// We then walk this MIB and create a flattened sysctl name to OID hash.
 | 
			
		||||
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	goos, goarch string
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// cmdLine returns this programs's commandline arguments.
 | 
			
		||||
func cmdLine() string {
 | 
			
		||||
	return "go run mksysctl_openbsd.go " + strings.Join(os.Args[1:], " ")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// buildTags returns build tags.
 | 
			
		||||
func buildTags() string {
 | 
			
		||||
	return fmt.Sprintf("%s,%s", goarch, goos)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// reMatch performs regular expression match and stores the substring slice to value pointed by m.
 | 
			
		||||
func reMatch(re *regexp.Regexp, str string, m *[]string) bool {
 | 
			
		||||
	*m = re.FindStringSubmatch(str)
 | 
			
		||||
	if *m != nil {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type nodeElement struct {
 | 
			
		||||
	n  int
 | 
			
		||||
	t  string
 | 
			
		||||
	pE *map[string]nodeElement
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	debugEnabled bool
 | 
			
		||||
	mib          map[string]nodeElement
 | 
			
		||||
	node         *map[string]nodeElement
 | 
			
		||||
	nodeMap      map[string]string
 | 
			
		||||
	sysCtl       []string
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	ctlNames1RE = regexp.MustCompile(`^#define\s+(CTL_NAMES)\s+{`)
 | 
			
		||||
	ctlNames2RE = regexp.MustCompile(`^#define\s+(CTL_(.*)_NAMES)\s+{`)
 | 
			
		||||
	ctlNames3RE = regexp.MustCompile(`^#define\s+((.*)CTL_NAMES)\s+{`)
 | 
			
		||||
	netInetRE   = regexp.MustCompile(`^netinet/`)
 | 
			
		||||
	netInet6RE  = regexp.MustCompile(`^netinet6/`)
 | 
			
		||||
	netRE       = regexp.MustCompile(`^net/`)
 | 
			
		||||
	bracesRE    = regexp.MustCompile(`{.*}`)
 | 
			
		||||
	ctlTypeRE   = regexp.MustCompile(`{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}`)
 | 
			
		||||
	fsNetKernRE = regexp.MustCompile(`^(fs|net|kern)_`)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func debug(s string) {
 | 
			
		||||
	if debugEnabled {
 | 
			
		||||
		fmt.Fprintln(os.Stderr, s)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Walk the MIB and build a sysctl name to OID mapping.
 | 
			
		||||
func buildSysctl(pNode *map[string]nodeElement, name string, oid []int) {
 | 
			
		||||
	lNode := pNode // local copy of pointer to node
 | 
			
		||||
	var keys []string
 | 
			
		||||
	for k := range *lNode {
 | 
			
		||||
		keys = append(keys, k)
 | 
			
		||||
	}
 | 
			
		||||
	sort.Strings(keys)
 | 
			
		||||
 | 
			
		||||
	for _, key := range keys {
 | 
			
		||||
		nodename := name
 | 
			
		||||
		if name != "" {
 | 
			
		||||
			nodename += "."
 | 
			
		||||
		}
 | 
			
		||||
		nodename += key
 | 
			
		||||
 | 
			
		||||
		nodeoid := append(oid, (*pNode)[key].n)
 | 
			
		||||
 | 
			
		||||
		if (*pNode)[key].t == `CTLTYPE_NODE` {
 | 
			
		||||
			if _, ok := nodeMap[nodename]; ok {
 | 
			
		||||
				lNode = &mib
 | 
			
		||||
				ctlName := nodeMap[nodename]
 | 
			
		||||
				for _, part := range strings.Split(ctlName, ".") {
 | 
			
		||||
					lNode = ((*lNode)[part]).pE
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				lNode = (*pNode)[key].pE
 | 
			
		||||
			}
 | 
			
		||||
			buildSysctl(lNode, nodename, nodeoid)
 | 
			
		||||
		} else if (*pNode)[key].t != "" {
 | 
			
		||||
			oidStr := []string{}
 | 
			
		||||
			for j := range nodeoid {
 | 
			
		||||
				oidStr = append(oidStr, fmt.Sprintf("%d", nodeoid[j]))
 | 
			
		||||
			}
 | 
			
		||||
			text := "\t{ \"" + nodename + "\", []_C_int{ " + strings.Join(oidStr, ", ") + " } }, \n"
 | 
			
		||||
			sysCtl = append(sysCtl, text)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
	// Get the OS (using GOOS_TARGET if it exist)
 | 
			
		||||
	goos = os.Getenv("GOOS_TARGET")
 | 
			
		||||
	if goos == "" {
 | 
			
		||||
		goos = os.Getenv("GOOS")
 | 
			
		||||
	}
 | 
			
		||||
	// Get the architecture (using GOARCH_TARGET if it exists)
 | 
			
		||||
	goarch = os.Getenv("GOARCH_TARGET")
 | 
			
		||||
	if goarch == "" {
 | 
			
		||||
		goarch = os.Getenv("GOARCH")
 | 
			
		||||
	}
 | 
			
		||||
	// Check if GOOS and GOARCH environment variables are defined
 | 
			
		||||
	if goarch == "" || goos == "" {
 | 
			
		||||
		fmt.Fprintf(os.Stderr, "GOARCH or GOOS not defined in environment\n")
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mib = make(map[string]nodeElement)
 | 
			
		||||
	headers := [...]string{
 | 
			
		||||
		`sys/sysctl.h`,
 | 
			
		||||
		`sys/socket.h`,
 | 
			
		||||
		`sys/tty.h`,
 | 
			
		||||
		`sys/malloc.h`,
 | 
			
		||||
		`sys/mount.h`,
 | 
			
		||||
		`sys/namei.h`,
 | 
			
		||||
		`sys/sem.h`,
 | 
			
		||||
		`sys/shm.h`,
 | 
			
		||||
		`sys/vmmeter.h`,
 | 
			
		||||
		`uvm/uvmexp.h`,
 | 
			
		||||
		`uvm/uvm_param.h`,
 | 
			
		||||
		`uvm/uvm_swap_encrypt.h`,
 | 
			
		||||
		`ddb/db_var.h`,
 | 
			
		||||
		`net/if.h`,
 | 
			
		||||
		`net/if_pfsync.h`,
 | 
			
		||||
		`net/pipex.h`,
 | 
			
		||||
		`netinet/in.h`,
 | 
			
		||||
		`netinet/icmp_var.h`,
 | 
			
		||||
		`netinet/igmp_var.h`,
 | 
			
		||||
		`netinet/ip_ah.h`,
 | 
			
		||||
		`netinet/ip_carp.h`,
 | 
			
		||||
		`netinet/ip_divert.h`,
 | 
			
		||||
		`netinet/ip_esp.h`,
 | 
			
		||||
		`netinet/ip_ether.h`,
 | 
			
		||||
		`netinet/ip_gre.h`,
 | 
			
		||||
		`netinet/ip_ipcomp.h`,
 | 
			
		||||
		`netinet/ip_ipip.h`,
 | 
			
		||||
		`netinet/pim_var.h`,
 | 
			
		||||
		`netinet/tcp_var.h`,
 | 
			
		||||
		`netinet/udp_var.h`,
 | 
			
		||||
		`netinet6/in6.h`,
 | 
			
		||||
		`netinet6/ip6_divert.h`,
 | 
			
		||||
		`netinet6/pim6_var.h`,
 | 
			
		||||
		`netinet/icmp6.h`,
 | 
			
		||||
		`netmpls/mpls.h`,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ctls := [...]string{
 | 
			
		||||
		`kern`,
 | 
			
		||||
		`vm`,
 | 
			
		||||
		`fs`,
 | 
			
		||||
		`net`,
 | 
			
		||||
		//debug			/* Special handling required */
 | 
			
		||||
		`hw`,
 | 
			
		||||
		//machdep		/* Arch specific */
 | 
			
		||||
		`user`,
 | 
			
		||||
		`ddb`,
 | 
			
		||||
		//vfs			/* Special handling required */
 | 
			
		||||
		`fs.posix`,
 | 
			
		||||
		`kern.forkstat`,
 | 
			
		||||
		`kern.intrcnt`,
 | 
			
		||||
		`kern.malloc`,
 | 
			
		||||
		`kern.nchstats`,
 | 
			
		||||
		`kern.seminfo`,
 | 
			
		||||
		`kern.shminfo`,
 | 
			
		||||
		`kern.timecounter`,
 | 
			
		||||
		`kern.tty`,
 | 
			
		||||
		`kern.watchdog`,
 | 
			
		||||
		`net.bpf`,
 | 
			
		||||
		`net.ifq`,
 | 
			
		||||
		`net.inet`,
 | 
			
		||||
		`net.inet.ah`,
 | 
			
		||||
		`net.inet.carp`,
 | 
			
		||||
		`net.inet.divert`,
 | 
			
		||||
		`net.inet.esp`,
 | 
			
		||||
		`net.inet.etherip`,
 | 
			
		||||
		`net.inet.gre`,
 | 
			
		||||
		`net.inet.icmp`,
 | 
			
		||||
		`net.inet.igmp`,
 | 
			
		||||
		`net.inet.ip`,
 | 
			
		||||
		`net.inet.ip.ifq`,
 | 
			
		||||
		`net.inet.ipcomp`,
 | 
			
		||||
		`net.inet.ipip`,
 | 
			
		||||
		`net.inet.mobileip`,
 | 
			
		||||
		`net.inet.pfsync`,
 | 
			
		||||
		`net.inet.pim`,
 | 
			
		||||
		`net.inet.tcp`,
 | 
			
		||||
		`net.inet.udp`,
 | 
			
		||||
		`net.inet6`,
 | 
			
		||||
		`net.inet6.divert`,
 | 
			
		||||
		`net.inet6.ip6`,
 | 
			
		||||
		`net.inet6.icmp6`,
 | 
			
		||||
		`net.inet6.pim6`,
 | 
			
		||||
		`net.inet6.tcp6`,
 | 
			
		||||
		`net.inet6.udp6`,
 | 
			
		||||
		`net.mpls`,
 | 
			
		||||
		`net.mpls.ifq`,
 | 
			
		||||
		`net.key`,
 | 
			
		||||
		`net.pflow`,
 | 
			
		||||
		`net.pfsync`,
 | 
			
		||||
		`net.pipex`,
 | 
			
		||||
		`net.rt`,
 | 
			
		||||
		`vm.swapencrypt`,
 | 
			
		||||
		//vfsgenctl		/* Special handling required */
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Node name "fixups"
 | 
			
		||||
	ctlMap := map[string]string{
 | 
			
		||||
		"ipproto":             "net.inet",
 | 
			
		||||
		"net.inet.ipproto":    "net.inet",
 | 
			
		||||
		"net.inet6.ipv6proto": "net.inet6",
 | 
			
		||||
		"net.inet6.ipv6":      "net.inet6.ip6",
 | 
			
		||||
		"net.inet.icmpv6":     "net.inet6.icmp6",
 | 
			
		||||
		"net.inet6.divert6":   "net.inet6.divert",
 | 
			
		||||
		"net.inet6.tcp6":      "net.inet.tcp",
 | 
			
		||||
		"net.inet6.udp6":      "net.inet.udp",
 | 
			
		||||
		"mpls":                "net.mpls",
 | 
			
		||||
		"swpenc":              "vm.swapencrypt",
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Node mappings
 | 
			
		||||
	nodeMap = map[string]string{
 | 
			
		||||
		"net.inet.ip.ifq": "net.ifq",
 | 
			
		||||
		"net.inet.pfsync": "net.pfsync",
 | 
			
		||||
		"net.mpls.ifq":    "net.ifq",
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mCtls := make(map[string]bool)
 | 
			
		||||
	for _, ctl := range ctls {
 | 
			
		||||
		mCtls[ctl] = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, header := range headers {
 | 
			
		||||
		debug("Processing " + header)
 | 
			
		||||
		file, err := os.Open(filepath.Join("/usr/include", header))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fmt.Fprintf(os.Stderr, "%v\n", err)
 | 
			
		||||
			os.Exit(1)
 | 
			
		||||
		}
 | 
			
		||||
		s := bufio.NewScanner(file)
 | 
			
		||||
		for s.Scan() {
 | 
			
		||||
			var sub []string
 | 
			
		||||
			if reMatch(ctlNames1RE, s.Text(), &sub) ||
 | 
			
		||||
				reMatch(ctlNames2RE, s.Text(), &sub) ||
 | 
			
		||||
				reMatch(ctlNames3RE, s.Text(), &sub) {
 | 
			
		||||
				if sub[1] == `CTL_NAMES` {
 | 
			
		||||
					// Top level.
 | 
			
		||||
					node = &mib
 | 
			
		||||
				} else {
 | 
			
		||||
					// Node.
 | 
			
		||||
					nodename := strings.ToLower(sub[2])
 | 
			
		||||
					ctlName := ""
 | 
			
		||||
					if reMatch(netInetRE, header, &sub) {
 | 
			
		||||
						ctlName = "net.inet." + nodename
 | 
			
		||||
					} else if reMatch(netInet6RE, header, &sub) {
 | 
			
		||||
						ctlName = "net.inet6." + nodename
 | 
			
		||||
					} else if reMatch(netRE, header, &sub) {
 | 
			
		||||
						ctlName = "net." + nodename
 | 
			
		||||
					} else {
 | 
			
		||||
						ctlName = nodename
 | 
			
		||||
						ctlName = fsNetKernRE.ReplaceAllString(ctlName, `$1.`)
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if val, ok := ctlMap[ctlName]; ok {
 | 
			
		||||
						ctlName = val
 | 
			
		||||
					}
 | 
			
		||||
					if _, ok := mCtls[ctlName]; !ok {
 | 
			
		||||
						debug("Ignoring " + ctlName + "...")
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					// Walk down from the top of the MIB.
 | 
			
		||||
					node = &mib
 | 
			
		||||
					for _, part := range strings.Split(ctlName, ".") {
 | 
			
		||||
						if _, ok := (*node)[part]; !ok {
 | 
			
		||||
							debug("Missing node " + part)
 | 
			
		||||
							(*node)[part] = nodeElement{n: 0, t: "", pE: &map[string]nodeElement{}}
 | 
			
		||||
						}
 | 
			
		||||
						node = (*node)[part].pE
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Populate current node with entries.
 | 
			
		||||
				i := -1
 | 
			
		||||
				for !strings.HasPrefix(s.Text(), "}") {
 | 
			
		||||
					s.Scan()
 | 
			
		||||
					if reMatch(bracesRE, s.Text(), &sub) {
 | 
			
		||||
						i++
 | 
			
		||||
					}
 | 
			
		||||
					if !reMatch(ctlTypeRE, s.Text(), &sub) {
 | 
			
		||||
						continue
 | 
			
		||||
					}
 | 
			
		||||
					(*node)[sub[1]] = nodeElement{n: i, t: sub[2], pE: &map[string]nodeElement{}}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		err = s.Err()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			fmt.Fprintf(os.Stderr, "%v\n", err)
 | 
			
		||||
			os.Exit(1)
 | 
			
		||||
		}
 | 
			
		||||
		file.Close()
 | 
			
		||||
	}
 | 
			
		||||
	buildSysctl(&mib, "", []int{})
 | 
			
		||||
 | 
			
		||||
	sort.Strings(sysCtl)
 | 
			
		||||
	text := strings.Join(sysCtl, "")
 | 
			
		||||
 | 
			
		||||
	fmt.Printf(srcTemplate, cmdLine(), buildTags(), text)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const srcTemplate = `// %s
 | 
			
		||||
// Code generated by the command above; DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
// +build %s
 | 
			
		||||
 | 
			
		||||
package unix
 | 
			
		||||
 | 
			
		||||
type mibentry struct {
 | 
			
		||||
	ctlname string
 | 
			
		||||
	ctloid []_C_int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var sysctlMib = []mibentry {
 | 
			
		||||
%s
 | 
			
		||||
}
 | 
			
		||||
`
 | 
			
		||||
| 
						 | 
				
			
			@ -1,265 +0,0 @@
 | 
			
		|||
#!/usr/bin/env perl
 | 
			
		||||
 | 
			
		||||
# Copyright 2011 The Go Authors. All rights reserved.
 | 
			
		||||
# Use of this source code is governed by a BSD-style
 | 
			
		||||
# license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Parse the header files for OpenBSD and generate a Go usable sysctl MIB.
 | 
			
		||||
#
 | 
			
		||||
# Build a MIB with each entry being an array containing the level, type and
 | 
			
		||||
# a hash that will contain additional entries if the current entry is a node.
 | 
			
		||||
# We then walk this MIB and create a flattened sysctl name to OID hash.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
use strict;
 | 
			
		||||
 | 
			
		||||
if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") {
 | 
			
		||||
	print STDERR "GOARCH or GOOS not defined in environment\n";
 | 
			
		||||
	exit 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
my $debug = 0;
 | 
			
		||||
my %ctls = ();
 | 
			
		||||
 | 
			
		||||
my @headers = qw (
 | 
			
		||||
	sys/sysctl.h
 | 
			
		||||
	sys/socket.h
 | 
			
		||||
	sys/tty.h
 | 
			
		||||
	sys/malloc.h
 | 
			
		||||
	sys/mount.h
 | 
			
		||||
	sys/namei.h
 | 
			
		||||
	sys/sem.h
 | 
			
		||||
	sys/shm.h
 | 
			
		||||
	sys/vmmeter.h
 | 
			
		||||
	uvm/uvmexp.h
 | 
			
		||||
	uvm/uvm_param.h
 | 
			
		||||
	uvm/uvm_swap_encrypt.h
 | 
			
		||||
	ddb/db_var.h
 | 
			
		||||
	net/if.h
 | 
			
		||||
	net/if_pfsync.h
 | 
			
		||||
	net/pipex.h
 | 
			
		||||
	netinet/in.h
 | 
			
		||||
	netinet/icmp_var.h
 | 
			
		||||
	netinet/igmp_var.h
 | 
			
		||||
	netinet/ip_ah.h
 | 
			
		||||
	netinet/ip_carp.h
 | 
			
		||||
	netinet/ip_divert.h
 | 
			
		||||
	netinet/ip_esp.h
 | 
			
		||||
	netinet/ip_ether.h
 | 
			
		||||
	netinet/ip_gre.h
 | 
			
		||||
	netinet/ip_ipcomp.h
 | 
			
		||||
	netinet/ip_ipip.h
 | 
			
		||||
	netinet/pim_var.h
 | 
			
		||||
	netinet/tcp_var.h
 | 
			
		||||
	netinet/udp_var.h
 | 
			
		||||
	netinet6/in6.h
 | 
			
		||||
	netinet6/ip6_divert.h
 | 
			
		||||
	netinet6/pim6_var.h
 | 
			
		||||
	netinet/icmp6.h
 | 
			
		||||
	netmpls/mpls.h
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
my @ctls = qw (
 | 
			
		||||
	kern
 | 
			
		||||
	vm
 | 
			
		||||
	fs
 | 
			
		||||
	net
 | 
			
		||||
	#debug				# Special handling required
 | 
			
		||||
	hw
 | 
			
		||||
	#machdep			# Arch specific
 | 
			
		||||
	user
 | 
			
		||||
	ddb
 | 
			
		||||
	#vfs				# Special handling required
 | 
			
		||||
	fs.posix
 | 
			
		||||
	kern.forkstat
 | 
			
		||||
	kern.intrcnt
 | 
			
		||||
	kern.malloc
 | 
			
		||||
	kern.nchstats
 | 
			
		||||
	kern.seminfo
 | 
			
		||||
	kern.shminfo
 | 
			
		||||
	kern.timecounter
 | 
			
		||||
	kern.tty
 | 
			
		||||
	kern.watchdog
 | 
			
		||||
	net.bpf
 | 
			
		||||
	net.ifq
 | 
			
		||||
	net.inet
 | 
			
		||||
	net.inet.ah
 | 
			
		||||
	net.inet.carp
 | 
			
		||||
	net.inet.divert
 | 
			
		||||
	net.inet.esp
 | 
			
		||||
	net.inet.etherip
 | 
			
		||||
	net.inet.gre
 | 
			
		||||
	net.inet.icmp
 | 
			
		||||
	net.inet.igmp
 | 
			
		||||
	net.inet.ip
 | 
			
		||||
	net.inet.ip.ifq
 | 
			
		||||
	net.inet.ipcomp
 | 
			
		||||
	net.inet.ipip
 | 
			
		||||
	net.inet.mobileip
 | 
			
		||||
	net.inet.pfsync
 | 
			
		||||
	net.inet.pim
 | 
			
		||||
	net.inet.tcp
 | 
			
		||||
	net.inet.udp
 | 
			
		||||
	net.inet6
 | 
			
		||||
	net.inet6.divert
 | 
			
		||||
	net.inet6.ip6
 | 
			
		||||
	net.inet6.icmp6
 | 
			
		||||
	net.inet6.pim6
 | 
			
		||||
	net.inet6.tcp6
 | 
			
		||||
	net.inet6.udp6
 | 
			
		||||
	net.mpls
 | 
			
		||||
	net.mpls.ifq
 | 
			
		||||
	net.key
 | 
			
		||||
	net.pflow
 | 
			
		||||
	net.pfsync
 | 
			
		||||
	net.pipex
 | 
			
		||||
	net.rt
 | 
			
		||||
	vm.swapencrypt
 | 
			
		||||
	#vfsgenctl			# Special handling required
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
# Node name "fixups"
 | 
			
		||||
my %ctl_map = (
 | 
			
		||||
	"ipproto" => "net.inet",
 | 
			
		||||
	"net.inet.ipproto" => "net.inet",
 | 
			
		||||
	"net.inet6.ipv6proto" => "net.inet6",
 | 
			
		||||
	"net.inet6.ipv6" => "net.inet6.ip6",
 | 
			
		||||
	"net.inet.icmpv6" => "net.inet6.icmp6",
 | 
			
		||||
	"net.inet6.divert6" => "net.inet6.divert",
 | 
			
		||||
	"net.inet6.tcp6" => "net.inet.tcp",
 | 
			
		||||
	"net.inet6.udp6" => "net.inet.udp",
 | 
			
		||||
	"mpls" => "net.mpls",
 | 
			
		||||
	"swpenc" => "vm.swapencrypt"
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
# Node mappings
 | 
			
		||||
my %node_map = (
 | 
			
		||||
	"net.inet.ip.ifq" => "net.ifq",
 | 
			
		||||
	"net.inet.pfsync" => "net.pfsync",
 | 
			
		||||
	"net.mpls.ifq" => "net.ifq"
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
my $ctlname;
 | 
			
		||||
my %mib = ();
 | 
			
		||||
my %sysctl = ();
 | 
			
		||||
my $node;
 | 
			
		||||
 | 
			
		||||
sub debug() {
 | 
			
		||||
	print STDERR "$_[0]\n" if $debug;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Walk the MIB and build a sysctl name to OID mapping.
 | 
			
		||||
sub build_sysctl() {
 | 
			
		||||
	my ($node, $name, $oid) = @_;
 | 
			
		||||
	my %node = %{$node};
 | 
			
		||||
	my @oid = @{$oid};
 | 
			
		||||
 | 
			
		||||
	foreach my $key (sort keys %node) {
 | 
			
		||||
		my @node = @{$node{$key}};
 | 
			
		||||
		my $nodename = $name.($name ne '' ? '.' : '').$key;
 | 
			
		||||
		my @nodeoid = (@oid, $node[0]);
 | 
			
		||||
		if ($node[1] eq 'CTLTYPE_NODE') {
 | 
			
		||||
			if (exists $node_map{$nodename}) {
 | 
			
		||||
				$node = \%mib;
 | 
			
		||||
				$ctlname = $node_map{$nodename};
 | 
			
		||||
				foreach my $part (split /\./, $ctlname) {
 | 
			
		||||
					$node = \%{@{$$node{$part}}[2]};
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				$node = $node[2];
 | 
			
		||||
			}
 | 
			
		||||
			&build_sysctl($node, $nodename, \@nodeoid);
 | 
			
		||||
		} elsif ($node[1] ne '') {
 | 
			
		||||
			$sysctl{$nodename} = \@nodeoid;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
foreach my $ctl (@ctls) {
 | 
			
		||||
	$ctls{$ctl} = $ctl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Build MIB
 | 
			
		||||
foreach my $header (@headers) {
 | 
			
		||||
	&debug("Processing $header...");
 | 
			
		||||
	open HEADER, "/usr/include/$header" ||
 | 
			
		||||
	    print STDERR "Failed to open $header\n";
 | 
			
		||||
	while (<HEADER>) {
 | 
			
		||||
		if ($_ =~ /^#define\s+(CTL_NAMES)\s+{/ ||
 | 
			
		||||
		    $_ =~ /^#define\s+(CTL_(.*)_NAMES)\s+{/ ||
 | 
			
		||||
		    $_ =~ /^#define\s+((.*)CTL_NAMES)\s+{/) {
 | 
			
		||||
			if ($1 eq 'CTL_NAMES') {
 | 
			
		||||
				# Top level.
 | 
			
		||||
				$node = \%mib;
 | 
			
		||||
			} else {
 | 
			
		||||
				# Node.
 | 
			
		||||
				my $nodename = lc($2);
 | 
			
		||||
				if ($header =~ /^netinet\//) {
 | 
			
		||||
					$ctlname = "net.inet.$nodename";
 | 
			
		||||
				} elsif ($header =~ /^netinet6\//) {
 | 
			
		||||
					$ctlname = "net.inet6.$nodename";
 | 
			
		||||
				} elsif ($header =~ /^net\//) {
 | 
			
		||||
					$ctlname = "net.$nodename";
 | 
			
		||||
				} else {
 | 
			
		||||
					$ctlname = "$nodename";
 | 
			
		||||
					$ctlname =~ s/^(fs|net|kern)_/$1\./;
 | 
			
		||||
				}
 | 
			
		||||
				if (exists $ctl_map{$ctlname}) {
 | 
			
		||||
					$ctlname = $ctl_map{$ctlname};
 | 
			
		||||
				}
 | 
			
		||||
				if (not exists $ctls{$ctlname}) {
 | 
			
		||||
					&debug("Ignoring $ctlname...");
 | 
			
		||||
					next;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				# Walk down from the top of the MIB.
 | 
			
		||||
				$node = \%mib;
 | 
			
		||||
				foreach my $part (split /\./, $ctlname) {
 | 
			
		||||
					if (not exists $$node{$part}) {
 | 
			
		||||
						&debug("Missing node $part");
 | 
			
		||||
						$$node{$part} = [ 0, '', {} ];
 | 
			
		||||
					}
 | 
			
		||||
					$node = \%{@{$$node{$part}}[2]};
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			# Populate current node with entries.
 | 
			
		||||
			my $i = -1;
 | 
			
		||||
			while (defined($_) && $_ !~ /^}/) {
 | 
			
		||||
				$_ = <HEADER>;
 | 
			
		||||
				$i++ if $_ =~ /{.*}/;
 | 
			
		||||
				next if $_ !~ /{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}/;
 | 
			
		||||
				$$node{$1} = [ $i, $2, {} ];
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	close HEADER;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
&build_sysctl(\%mib, "", []);
 | 
			
		||||
 | 
			
		||||
print <<EOF;
 | 
			
		||||
// mksysctl_openbsd.pl
 | 
			
		||||
// Code generated by the command above; DO NOT EDIT.
 | 
			
		||||
 | 
			
		||||
// +build $ENV{'GOARCH'},$ENV{'GOOS'}
 | 
			
		||||
 | 
			
		||||
package unix;
 | 
			
		||||
 | 
			
		||||
type mibentry struct {
 | 
			
		||||
	ctlname string
 | 
			
		||||
	ctloid []_C_int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var sysctlMib = []mibentry {
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
foreach my $name (sort keys %sysctl) {
 | 
			
		||||
	my @oid = @{$sysctl{$name}};
 | 
			
		||||
	print "\t{ \"$name\", []_C_int{ ", join(', ', @oid), " } }, \n";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
print <<EOF;
 | 
			
		||||
}
 | 
			
		||||
EOF
 | 
			
		||||
| 
						 | 
				
			
			@ -139,7 +139,7 @@ func main() {
 | 
			
		|||
				text += format(name, num, proto)
 | 
			
		||||
			}
 | 
			
		||||
		case "freebsd":
 | 
			
		||||
			if t.Match(`^([0-9]+)\s+\S+\s+(?:NO)?STD\s+({ \S+\s+(\w+).*)$`) {
 | 
			
		||||
			if t.Match(`^([0-9]+)\s+\S+\s+(?:(?:NO)?STD|COMPAT10)\s+({ \S+\s+(\w+).*)$`) {
 | 
			
		||||
				num, proto := t.sub[1], t.sub[2]
 | 
			
		||||
				name := fmt.Sprintf("SYS_%s", t.sub[3])
 | 
			
		||||
				text += format(name, num, proto)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,9 +2,6 @@
 | 
			
		|||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build openbsd
 | 
			
		||||
// +build 386 amd64 arm
 | 
			
		||||
 | 
			
		||||
package unix
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,12 @@
 | 
			
		|||
// Copyright 2019 The Go Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build aix dragonfly freebsd linux netbsd openbsd
 | 
			
		||||
 | 
			
		||||
package unix
 | 
			
		||||
 | 
			
		||||
// ReadDirent reads directory entries from fd and writes them into buf.
 | 
			
		||||
func ReadDirent(fd int, buf []byte) (n int, err error) {
 | 
			
		||||
	return Getdents(fd, buf)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
// Copyright 2019 The Go Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build darwin
 | 
			
		||||
 | 
			
		||||
package unix
 | 
			
		||||
 | 
			
		||||
import "unsafe"
 | 
			
		||||
 | 
			
		||||
// ReadDirent reads directory entries from fd and writes them into buf.
 | 
			
		||||
func ReadDirent(fd int, buf []byte) (n int, err error) {
 | 
			
		||||
	// Final argument is (basep *uintptr) and the syscall doesn't take nil.
 | 
			
		||||
	// 64 bits should be enough. (32 bits isn't even on 386). Since the
 | 
			
		||||
	// actual system call is getdirentries64, 64 is a good guess.
 | 
			
		||||
	// TODO(rsc): Can we use a single global basep for all calls?
 | 
			
		||||
	var base = (*uintptr)(unsafe.Pointer(new(uint64)))
 | 
			
		||||
	return Getdirentries(fd, buf, base)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -21,10 +21,10 @@ func cmsgAlignOf(salen int) int {
 | 
			
		|||
	case "aix":
 | 
			
		||||
		// There is no alignment on AIX.
 | 
			
		||||
		salign = 1
 | 
			
		||||
	case "darwin", "dragonfly", "solaris":
 | 
			
		||||
		// NOTE: It seems like 64-bit Darwin, DragonFly BSD and
 | 
			
		||||
		// Solaris kernels still require 32-bit aligned access to
 | 
			
		||||
		// network subsystem.
 | 
			
		||||
	case "darwin", "dragonfly", "solaris", "illumos":
 | 
			
		||||
		// NOTE: It seems like 64-bit Darwin, DragonFly BSD,
 | 
			
		||||
		// illumos, and Solaris kernels still require 32-bit
 | 
			
		||||
		// aligned access to network subsystem.
 | 
			
		||||
		if SizeofPtr == 8 {
 | 
			
		||||
			salign = 4
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,5 +50,4 @@ func BytePtrFromString(s string) (*byte, error) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// Single-word zero for use when we need a valid pointer to 0 bytes.
 | 
			
		||||
// See mkunix.pl.
 | 
			
		||||
var _zero uintptr
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -280,8 +280,24 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
 | 
			
		|||
	return -1, ENOSYS
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntIno(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntReclen(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntNamlen(buf []byte) (uint64, bool) {
 | 
			
		||||
	reclen, ok := direntReclen(buf)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return 0, false
 | 
			
		||||
	}
 | 
			
		||||
	return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//sys	getdirent(fd int, buf []byte) (n int, err error)
 | 
			
		||||
func ReadDirent(fd int, buf []byte) (n int, err error) {
 | 
			
		||||
func Getdents(fd int, buf []byte) (n int, err error) {
 | 
			
		||||
	return getdirent(fd, buf)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -334,49 +350,12 @@ func (w WaitStatus) Signal() Signal {
 | 
			
		|||
 | 
			
		||||
func (w WaitStatus) Continued() bool { return w&0x01000000 != 0 }
 | 
			
		||||
 | 
			
		||||
func (w WaitStatus) CoreDump() bool { return w&0x200 != 0 }
 | 
			
		||||
func (w WaitStatus) CoreDump() bool { return w&0x80 == 0x80 }
 | 
			
		||||
 | 
			
		||||
func (w WaitStatus) TrapCause() int { return -1 }
 | 
			
		||||
 | 
			
		||||
//sys	ioctl(fd int, req uint, arg uintptr) (err error)
 | 
			
		||||
 | 
			
		||||
// ioctl itself should not be exposed directly, but additional get/set
 | 
			
		||||
// functions for specific types are permissible.
 | 
			
		||||
 | 
			
		||||
// IoctlSetInt performs an ioctl operation which sets an integer value
 | 
			
		||||
// on fd, using the specified request number.
 | 
			
		||||
func IoctlSetInt(fd int, req uint, value int) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(value))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlSetTermios(fd int, req uint, value *Termios) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IoctlGetInt performs an ioctl operation which gets an integer value
 | 
			
		||||
// from fd, using the specified request number.
 | 
			
		||||
func IoctlGetInt(fd int, req uint) (int, error) {
 | 
			
		||||
	var value int
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
 | 
			
		||||
	var value Winsize
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 | 
			
		||||
	var value Termios
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// fcntl must never be called with cmd=F_DUP2FD because it doesn't work on AIX
 | 
			
		||||
// There is no way to create a custom fcntl and to keep //sys fcntl easily,
 | 
			
		||||
// Therefore, the programmer must call dup2 instead of fcntl in this case.
 | 
			
		||||
| 
						 | 
				
			
			@ -444,8 +423,6 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 | 
			
		|||
//sysnb	Times(tms *Tms) (ticks uintptr, err error)
 | 
			
		||||
//sysnb	Umask(mask int) (oldmask int)
 | 
			
		||||
//sysnb	Uname(buf *Utsname) (err error)
 | 
			
		||||
//TODO umount
 | 
			
		||||
// //sys	Unmount(target string, flags int) (err error) = umount
 | 
			
		||||
//sys   Unlink(path string) (err error)
 | 
			
		||||
//sys   Unlinkat(dirfd int, path string, flags int) (err error)
 | 
			
		||||
//sys	Ustat(dev int, ubuf *Ustat_t) (err error)
 | 
			
		||||
| 
						 | 
				
			
			@ -456,8 +433,8 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 | 
			
		|||
//sys	Dup2(oldfd int, newfd int) (err error)
 | 
			
		||||
//sys	Fadvise(fd int, offset int64, length int64, advice int) (err error) = posix_fadvise64
 | 
			
		||||
//sys	Fchown(fd int, uid int, gid int) (err error)
 | 
			
		||||
//sys	Fstat(fd int, stat *Stat_t) (err error)
 | 
			
		||||
//sys	Fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = fstatat
 | 
			
		||||
//sys	fstat(fd int, stat *Stat_t) (err error)
 | 
			
		||||
//sys	fstatat(dirfd int, path string, stat *Stat_t, flags int) (err error) = fstatat
 | 
			
		||||
//sys	Fstatfs(fd int, buf *Statfs_t) (err error)
 | 
			
		||||
//sys	Ftruncate(fd int, length int64) (err error)
 | 
			
		||||
//sysnb	Getegid() (egid int)
 | 
			
		||||
| 
						 | 
				
			
			@ -466,18 +443,17 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 | 
			
		|||
//sysnb	Getuid() (uid int)
 | 
			
		||||
//sys	Lchown(path string, uid int, gid int) (err error)
 | 
			
		||||
//sys	Listen(s int, n int) (err error)
 | 
			
		||||
//sys	Lstat(path string, stat *Stat_t) (err error)
 | 
			
		||||
//sys	lstat(path string, stat *Stat_t) (err error)
 | 
			
		||||
//sys	Pause() (err error)
 | 
			
		||||
//sys	Pread(fd int, p []byte, offset int64) (n int, err error) = pread64
 | 
			
		||||
//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error) = pwrite64
 | 
			
		||||
//TODO Select
 | 
			
		||||
// //sys	Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
 | 
			
		||||
//sys	Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
 | 
			
		||||
//sys	Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
 | 
			
		||||
//sysnb	Setregid(rgid int, egid int) (err error)
 | 
			
		||||
//sysnb	Setreuid(ruid int, euid int) (err error)
 | 
			
		||||
//sys	Shutdown(fd int, how int) (err error)
 | 
			
		||||
//sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
 | 
			
		||||
//sys	Stat(path string, stat *Stat_t) (err error)
 | 
			
		||||
//sys	stat(path string, statptr *Stat_t) (err error)
 | 
			
		||||
//sys	Statfs(path string, buf *Statfs_t) (err error)
 | 
			
		||||
//sys	Truncate(path string, length int64) (err error)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -493,8 +469,10 @@ func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 | 
			
		|||
//sysnb	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
 | 
			
		||||
//sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
 | 
			
		||||
//sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
 | 
			
		||||
//sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
 | 
			
		||||
//sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
 | 
			
		||||
 | 
			
		||||
// In order to use msghdr structure with Control, Controllen, nrecvmsg and nsendmsg must be used.
 | 
			
		||||
//sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error) = nrecvmsg
 | 
			
		||||
//sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = nsendmsg
 | 
			
		||||
 | 
			
		||||
//sys	munmap(addr uintptr, length uintptr) (err error)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -547,3 +525,12 @@ func Poll(fds []PollFd, timeout int) (n int, err error) {
 | 
			
		|||
//sys	Utime(path string, buf *Utimbuf) (err error)
 | 
			
		||||
 | 
			
		||||
//sys	Getsystemcfg(label int) (n uint64)
 | 
			
		||||
 | 
			
		||||
//sys	umount(target string) (err error)
 | 
			
		||||
func Unmount(target string, flags int) (err error) {
 | 
			
		||||
	if flags != 0 {
 | 
			
		||||
		// AIX doesn't have any flags for umount.
 | 
			
		||||
		return ENOSYS
 | 
			
		||||
	}
 | 
			
		||||
	return umount(target)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,3 +32,19 @@ func (msghdr *Msghdr) SetControllen(length int) {
 | 
			
		|||
func (cmsg *Cmsghdr) SetLen(length int) {
 | 
			
		||||
	cmsg.Len = uint32(length)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Fstat(fd int, stat *Stat_t) error {
 | 
			
		||||
	return fstat(fd, stat)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Fstatat(dirfd int, path string, stat *Stat_t, flags int) error {
 | 
			
		||||
	return fstatat(dirfd, path, stat, flags)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Lstat(path string, stat *Stat_t) error {
 | 
			
		||||
	return lstat(path, stat)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Stat(path string, statptr *Stat_t) error {
 | 
			
		||||
	return stat(path, statptr)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,3 +32,50 @@ func (msghdr *Msghdr) SetControllen(length int) {
 | 
			
		|||
func (cmsg *Cmsghdr) SetLen(length int) {
 | 
			
		||||
	cmsg.Len = uint32(length)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// In order to only have Timespec structure, type of Stat_t's fields
 | 
			
		||||
// Atim, Mtim and Ctim is changed from StTimespec to Timespec during
 | 
			
		||||
// ztypes generation.
 | 
			
		||||
// On ppc64, Timespec.Nsec is an int64 while StTimespec.Nsec is an
 | 
			
		||||
// int32, so the fields' value must be modified.
 | 
			
		||||
func fixStatTimFields(stat *Stat_t) {
 | 
			
		||||
	stat.Atim.Nsec >>= 32
 | 
			
		||||
	stat.Mtim.Nsec >>= 32
 | 
			
		||||
	stat.Ctim.Nsec >>= 32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Fstat(fd int, stat *Stat_t) error {
 | 
			
		||||
	err := fstat(fd, stat)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	fixStatTimFields(stat)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Fstatat(dirfd int, path string, stat *Stat_t, flags int) error {
 | 
			
		||||
	err := fstatat(dirfd, path, stat, flags)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	fixStatTimFields(stat)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Lstat(path string, stat *Stat_t) error {
 | 
			
		||||
	err := lstat(path, stat)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	fixStatTimFields(stat)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Stat(path string, statptr *Stat_t) error {
 | 
			
		||||
	err := stat(path, statptr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	fixStatTimFields(statptr)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,15 +63,6 @@ func Setgroups(gids []int) (err error) {
 | 
			
		|||
	return setgroups(len(a), &a[0])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ReadDirent(fd int, buf []byte) (n int, err error) {
 | 
			
		||||
	// Final argument is (basep *uintptr) and the syscall doesn't take nil.
 | 
			
		||||
	// 64 bits should be enough. (32 bits isn't even on 386). Since the
 | 
			
		||||
	// actual system call is getdirentries64, 64 is a good guess.
 | 
			
		||||
	// TODO(rsc): Can we use a single global basep for all calls?
 | 
			
		||||
	var base = (*uintptr)(unsafe.Pointer(new(uint64)))
 | 
			
		||||
	return Getdirentries(fd, buf, base)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Wait status is 7 bits at bottom, either 0 (exited),
 | 
			
		||||
// 0x7F (stopped), or a signal number that caused an exit.
 | 
			
		||||
// The 0x80 bit is whether there was a core dump.
 | 
			
		||||
| 
						 | 
				
			
			@ -86,6 +77,7 @@ const (
 | 
			
		|||
	shift = 8
 | 
			
		||||
 | 
			
		||||
	exited  = 0
 | 
			
		||||
	killed  = 9
 | 
			
		||||
	stopped = 0x7F
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +104,8 @@ func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
 | 
			
		|||
 | 
			
		||||
func (w WaitStatus) Stopped() bool { return w&mask == stopped && syscall.Signal(w>>shift) != SIGSTOP }
 | 
			
		||||
 | 
			
		||||
func (w WaitStatus) Killed() bool { return w&mask == killed && syscall.Signal(w>>shift) != SIGKILL }
 | 
			
		||||
 | 
			
		||||
func (w WaitStatus) Continued() bool { return w&mask == stopped && syscall.Signal(w>>shift) == SIGSTOP }
 | 
			
		||||
 | 
			
		||||
func (w WaitStatus) StopSignal() syscall.Signal {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,7 +77,18 @@ func nametomib(name string) (mib []_C_int, err error) {
 | 
			
		|||
	return buf[0 : n/siz], nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//sys   ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
 | 
			
		||||
func direntIno(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntReclen(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntNamlen(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
 | 
			
		||||
func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -328,43 +339,6 @@ func Kill(pid int, signum syscall.Signal) (err error) { return kill(pid, int(sig
 | 
			
		|||
 | 
			
		||||
//sys	ioctl(fd int, req uint, arg uintptr) (err error)
 | 
			
		||||
 | 
			
		||||
// ioctl itself should not be exposed directly, but additional get/set
 | 
			
		||||
// functions for specific types are permissible.
 | 
			
		||||
 | 
			
		||||
// IoctlSetInt performs an ioctl operation which sets an integer value
 | 
			
		||||
// on fd, using the specified request number.
 | 
			
		||||
func IoctlSetInt(fd int, req uint, value int) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(value))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlSetTermios(fd int, req uint, value *Termios) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IoctlGetInt performs an ioctl operation which gets an integer value
 | 
			
		||||
// from fd, using the specified request number.
 | 
			
		||||
func IoctlGetInt(fd int, req uint) (int, error) {
 | 
			
		||||
	var value int
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
 | 
			
		||||
	var value Winsize
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 | 
			
		||||
	var value Termios
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Uname(uname *Utsname) error {
 | 
			
		||||
	mib := []_C_int{CTL_KERN, KERN_OSTYPE}
 | 
			
		||||
	n := unsafe.Sizeof(uname.Sysname)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,8 @@ import (
 | 
			
		|||
	"syscall"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//sys   ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
 | 
			
		||||
 | 
			
		||||
func setTimespec(sec, nsec int64) Timespec {
 | 
			
		||||
	return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,8 @@ import (
 | 
			
		|||
	"syscall"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//sys   ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
 | 
			
		||||
 | 
			
		||||
func setTimespec(sec, nsec int64) Timespec {
 | 
			
		||||
	return Timespec{Sec: sec, Nsec: nsec}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,10 @@ import (
 | 
			
		|||
	"syscall"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func ptrace(request int, pid int, addr uintptr, data uintptr) error {
 | 
			
		||||
	return ENOTSUP
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func setTimespec(sec, nsec int64) Timespec {
 | 
			
		||||
	return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,10 @@ import (
 | 
			
		|||
	"syscall"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func ptrace(request int, pid int, addr uintptr, data uintptr) error {
 | 
			
		||||
	return ENOTSUP
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func setTimespec(sec, nsec int64) Timespec {
 | 
			
		||||
	return Timespec{Sec: sec, Nsec: nsec}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,6 +57,22 @@ func nametomib(name string) (mib []_C_int, err error) {
 | 
			
		|||
	return buf[0 : n/siz], nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntIno(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntReclen(buf []byte) (uint64, bool) {
 | 
			
		||||
	namlen, ok := direntNamlen(buf)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return 0, false
 | 
			
		||||
	}
 | 
			
		||||
	return (16 + namlen + 1 + 7) &^ 7, true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntNamlen(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//sysnb pipe() (r int, w int, err error)
 | 
			
		||||
 | 
			
		||||
func Pipe(p []int) (err error) {
 | 
			
		||||
| 
						 | 
				
			
			@ -134,43 +150,6 @@ func setattrlistTimes(path string, times []Timespec, flags int) error {
 | 
			
		|||
 | 
			
		||||
//sys	ioctl(fd int, req uint, arg uintptr) (err error)
 | 
			
		||||
 | 
			
		||||
// ioctl itself should not be exposed directly, but additional get/set
 | 
			
		||||
// functions for specific types are permissible.
 | 
			
		||||
 | 
			
		||||
// IoctlSetInt performs an ioctl operation which sets an integer value
 | 
			
		||||
// on fd, using the specified request number.
 | 
			
		||||
func IoctlSetInt(fd int, req uint, value int) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(value))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlSetTermios(fd int, req uint, value *Termios) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IoctlGetInt performs an ioctl operation which gets an integer value
 | 
			
		||||
// from fd, using the specified request number.
 | 
			
		||||
func IoctlGetInt(fd int, req uint) (int, error) {
 | 
			
		||||
	var value int
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
 | 
			
		||||
	var value Winsize
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 | 
			
		||||
	var value Termios
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func sysctlUname(mib []_C_int, old *byte, oldlen *uintptr) error {
 | 
			
		||||
	err := sysctl(mib, old, oldlen, nil, 0)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -269,6 +248,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
 | 
			
		|||
//sys	Fstatfs(fd int, stat *Statfs_t) (err error)
 | 
			
		||||
//sys	Fsync(fd int) (err error)
 | 
			
		||||
//sys	Ftruncate(fd int, length int64) (err error)
 | 
			
		||||
//sys	Getdents(fd int, buf []byte) (n int, err error)
 | 
			
		||||
//sys	Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error)
 | 
			
		||||
//sys	Getdtablesize() (size int)
 | 
			
		||||
//sysnb	Getegid() (egid int)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,6 +82,18 @@ func nametomib(name string) (mib []_C_int, err error) {
 | 
			
		|||
	return buf[0 : n/siz], nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntIno(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntReclen(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntNamlen(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Pipe(p []int) (err error) {
 | 
			
		||||
	return Pipe2(p, 0)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -189,43 +201,6 @@ func setattrlistTimes(path string, times []Timespec, flags int) error {
 | 
			
		|||
 | 
			
		||||
//sys   ioctl(fd int, req uint, arg uintptr) (err error)
 | 
			
		||||
 | 
			
		||||
// ioctl itself should not be exposed directly, but additional get/set
 | 
			
		||||
// functions for specific types are permissible.
 | 
			
		||||
 | 
			
		||||
// IoctlSetInt performs an ioctl operation which sets an integer value
 | 
			
		||||
// on fd, using the specified request number.
 | 
			
		||||
func IoctlSetInt(fd int, req uint, value int) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(value))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlSetTermios(fd int, req uint, value *Termios) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IoctlGetInt performs an ioctl operation which gets an integer value
 | 
			
		||||
// from fd, using the specified request number.
 | 
			
		||||
func IoctlGetInt(fd int, req uint) (int, error) {
 | 
			
		||||
	var value int
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
 | 
			
		||||
	var value Winsize
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 | 
			
		||||
	var value Termios
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Uname(uname *Utsname) error {
 | 
			
		||||
	mib := []_C_int{CTL_KERN, KERN_OSTYPE}
 | 
			
		||||
	n := unsafe.Sizeof(uname.Sysname)
 | 
			
		||||
| 
						 | 
				
			
			@ -362,7 +337,21 @@ func Getdents(fd int, buf []byte) (n int, err error) {
 | 
			
		|||
 | 
			
		||||
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
 | 
			
		||||
	if supportsABI(_ino64First) {
 | 
			
		||||
		return getdirentries_freebsd12(fd, buf, basep)
 | 
			
		||||
		if basep == nil || unsafe.Sizeof(*basep) == 8 {
 | 
			
		||||
			return getdirentries_freebsd12(fd, buf, (*uint64)(unsafe.Pointer(basep)))
 | 
			
		||||
		}
 | 
			
		||||
		// The freebsd12 syscall needs a 64-bit base. On 32-bit machines
 | 
			
		||||
		// we can't just use the basep passed in. See #32498.
 | 
			
		||||
		var base uint64 = uint64(*basep)
 | 
			
		||||
		n, err = getdirentries_freebsd12(fd, buf, &base)
 | 
			
		||||
		*basep = uintptr(base)
 | 
			
		||||
		if base>>32 != 0 {
 | 
			
		||||
			// We can't stuff the base back into a uintptr, so any
 | 
			
		||||
			// future calls would be suspect. Generate an error.
 | 
			
		||||
			// EIO is allowed by getdirentries.
 | 
			
		||||
			err = EIO
 | 
			
		||||
		}
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// The old syscall entries are smaller than the new. Use 1/4 of the original
 | 
			
		||||
| 
						 | 
				
			
			@ -404,22 +393,22 @@ func roundup(x, y int) int {
 | 
			
		|||
 | 
			
		||||
func (s *Stat_t) convertFrom(old *stat_freebsd11_t) {
 | 
			
		||||
	*s = Stat_t{
 | 
			
		||||
		Dev:      uint64(old.Dev),
 | 
			
		||||
		Ino:      uint64(old.Ino),
 | 
			
		||||
		Nlink:    uint64(old.Nlink),
 | 
			
		||||
		Mode:     old.Mode,
 | 
			
		||||
		Uid:      old.Uid,
 | 
			
		||||
		Gid:      old.Gid,
 | 
			
		||||
		Rdev:     uint64(old.Rdev),
 | 
			
		||||
		Atim:     old.Atim,
 | 
			
		||||
		Mtim:     old.Mtim,
 | 
			
		||||
		Ctim:     old.Ctim,
 | 
			
		||||
		Birthtim: old.Birthtim,
 | 
			
		||||
		Size:     old.Size,
 | 
			
		||||
		Blocks:   old.Blocks,
 | 
			
		||||
		Blksize:  old.Blksize,
 | 
			
		||||
		Flags:    old.Flags,
 | 
			
		||||
		Gen:      uint64(old.Gen),
 | 
			
		||||
		Dev:     uint64(old.Dev),
 | 
			
		||||
		Ino:     uint64(old.Ino),
 | 
			
		||||
		Nlink:   uint64(old.Nlink),
 | 
			
		||||
		Mode:    old.Mode,
 | 
			
		||||
		Uid:     old.Uid,
 | 
			
		||||
		Gid:     old.Gid,
 | 
			
		||||
		Rdev:    uint64(old.Rdev),
 | 
			
		||||
		Atim:    old.Atim,
 | 
			
		||||
		Mtim:    old.Mtim,
 | 
			
		||||
		Ctim:    old.Ctim,
 | 
			
		||||
		Btim:    old.Btim,
 | 
			
		||||
		Size:    old.Size,
 | 
			
		||||
		Blocks:  old.Blocks,
 | 
			
		||||
		Blksize: old.Blksize,
 | 
			
		||||
		Flags:   old.Flags,
 | 
			
		||||
		Gen:     uint64(old.Gen),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -507,6 +496,70 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
 | 
			
		|||
	return sendfile(outfd, infd, offset, count)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//sys	ptrace(request int, pid int, addr uintptr, data int) (err error)
 | 
			
		||||
 | 
			
		||||
func PtraceAttach(pid int) (err error) {
 | 
			
		||||
	return ptrace(PTRACE_ATTACH, pid, 0, 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PtraceCont(pid int, signal int) (err error) {
 | 
			
		||||
	return ptrace(PTRACE_CONT, pid, 1, signal)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PtraceDetach(pid int) (err error) {
 | 
			
		||||
	return ptrace(PTRACE_DETACH, pid, 1, 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PtraceGetFpRegs(pid int, fpregsout *FpReg) (err error) {
 | 
			
		||||
	return ptrace(PTRACE_GETFPREGS, pid, uintptr(unsafe.Pointer(fpregsout)), 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PtraceGetFsBase(pid int, fsbase *int64) (err error) {
 | 
			
		||||
	return ptrace(PTRACE_GETFSBASE, pid, uintptr(unsafe.Pointer(fsbase)), 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PtraceGetRegs(pid int, regsout *Reg) (err error) {
 | 
			
		||||
	return ptrace(PTRACE_GETREGS, pid, uintptr(unsafe.Pointer(regsout)), 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PtraceIO(req int, pid int, addr uintptr, out []byte, countin int) (count int, err error) {
 | 
			
		||||
	ioDesc := PtraceIoDesc{Op: int32(req), Offs: (*byte)(unsafe.Pointer(addr)), Addr: (*byte)(unsafe.Pointer(&out[0])), Len: uint(countin)}
 | 
			
		||||
	err = ptrace(PTRACE_IO, pid, uintptr(unsafe.Pointer(&ioDesc)), 0)
 | 
			
		||||
	return int(ioDesc.Len), err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PtraceLwpEvents(pid int, enable int) (err error) {
 | 
			
		||||
	return ptrace(PTRACE_LWPEVENTS, pid, 0, enable)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PtraceLwpInfo(pid int, info uintptr) (err error) {
 | 
			
		||||
	return ptrace(PTRACE_LWPINFO, pid, info, int(unsafe.Sizeof(PtraceLwpInfoStruct{})))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
 | 
			
		||||
	return PtraceIO(PIOD_READ_D, pid, addr, out, SizeofLong)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
 | 
			
		||||
	return PtraceIO(PIOD_READ_I, pid, addr, out, SizeofLong)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
 | 
			
		||||
	return PtraceIO(PIOD_WRITE_D, pid, addr, data, SizeofLong)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
 | 
			
		||||
	return PtraceIO(PIOD_WRITE_I, pid, addr, data, SizeofLong)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PtraceSetRegs(pid int, regs *Reg) (err error) {
 | 
			
		||||
	return ptrace(PTRACE_SETREGS, pid, uintptr(unsafe.Pointer(regs)), 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PtraceSingleStep(pid int) (err error) {
 | 
			
		||||
	return ptrace(PTRACE_SINGLESTEP, pid, 1, 0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Exposed directly
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -555,7 +608,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
 | 
			
		|||
//sys	Fsync(fd int) (err error)
 | 
			
		||||
//sys	Ftruncate(fd int, length int64) (err error)
 | 
			
		||||
//sys	getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error)
 | 
			
		||||
//sys	getdirentries_freebsd12(fd int, buf []byte, basep *uintptr) (n int, err error)
 | 
			
		||||
//sys	getdirentries_freebsd12(fd int, buf []byte, basep *uint64) (n int, err error)
 | 
			
		||||
//sys	Getdtablesize() (size int)
 | 
			
		||||
//sysnb	Getegid() (egid int)
 | 
			
		||||
//sysnb	Geteuid() (uid int)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,6 @@ package unix
 | 
			
		|||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"net"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
| 
						 | 
				
			
			@ -72,6 +71,17 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
 | 
			
		|||
// ioctl itself should not be exposed directly, but additional get/set
 | 
			
		||||
// functions for specific types are permissible.
 | 
			
		||||
 | 
			
		||||
// IoctlRetInt performs an ioctl operation specified by req on a device
 | 
			
		||||
// associated with opened file descriptor fd, and returns a non-negative
 | 
			
		||||
// integer that is returned by the ioctl syscall.
 | 
			
		||||
func IoctlRetInt(fd int, req uint) (int, error) {
 | 
			
		||||
	ret, _, err := Syscall(SYS_IOCTL, uintptr(fd), uintptr(req), 0)
 | 
			
		||||
	if err != 0 {
 | 
			
		||||
		return 0, err
 | 
			
		||||
	}
 | 
			
		||||
	return int(ret), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IoctlSetPointerInt performs an ioctl operation which sets an
 | 
			
		||||
// integer value on fd, using the specified request number. The ioctl
 | 
			
		||||
// argument is called with a pointer to the integer value, rather than
 | 
			
		||||
| 
						 | 
				
			
			@ -81,46 +91,18 @@ func IoctlSetPointerInt(fd int, req uint, value int) error {
 | 
			
		|||
	return ioctl(fd, req, uintptr(unsafe.Pointer(&v)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IoctlSetInt performs an ioctl operation which sets an integer value
 | 
			
		||||
// on fd, using the specified request number.
 | 
			
		||||
func IoctlSetInt(fd int, req uint, value int) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(value))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlSetTermios(fd int, req uint, value *Termios) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlSetRTCTime(fd int, value *RTCTime) error {
 | 
			
		||||
	err := ioctl(fd, RTC_SET_TIME, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
	runtime.KeepAlive(value)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IoctlGetInt performs an ioctl operation which gets an integer value
 | 
			
		||||
// from fd, using the specified request number.
 | 
			
		||||
func IoctlGetInt(fd int, req uint) (int, error) {
 | 
			
		||||
	var value int
 | 
			
		||||
func IoctlGetUint32(fd int, req uint) (uint32, error) {
 | 
			
		||||
	var value uint32
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
 | 
			
		||||
	var value Winsize
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 | 
			
		||||
	var value Termios
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetRTCTime(fd int) (*RTCTime, error) {
 | 
			
		||||
	var value RTCTime
 | 
			
		||||
	err := ioctl(fd, RTC_RD_TIME, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
| 
						 | 
				
			
			@ -759,7 +741,7 @@ const px_proto_oe = 0
 | 
			
		|||
 | 
			
		||||
type SockaddrPPPoE struct {
 | 
			
		||||
	SID    uint16
 | 
			
		||||
	Remote net.HardwareAddr
 | 
			
		||||
	Remote []byte
 | 
			
		||||
	Dev    string
 | 
			
		||||
	raw    RawSockaddrPPPoX
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -910,7 +892,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
 | 
			
		|||
		}
 | 
			
		||||
		sa := &SockaddrPPPoE{
 | 
			
		||||
			SID:    binary.BigEndian.Uint16(pp[6:8]),
 | 
			
		||||
			Remote: net.HardwareAddr(pp[8:14]),
 | 
			
		||||
			Remote: pp[8:14],
 | 
			
		||||
		}
 | 
			
		||||
		for i := 14; i < 14+IFNAMSIZ; i++ {
 | 
			
		||||
			if pp[i] == 0 {
 | 
			
		||||
| 
						 | 
				
			
			@ -1408,8 +1390,20 @@ func Reboot(cmd int) (err error) {
 | 
			
		|||
	return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ReadDirent(fd int, buf []byte) (n int, err error) {
 | 
			
		||||
	return Getdents(fd, buf)
 | 
			
		||||
func direntIno(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntReclen(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntNamlen(buf []byte) (uint64, bool) {
 | 
			
		||||
	reclen, ok := direntReclen(buf)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return 0, false
 | 
			
		||||
	}
 | 
			
		||||
	return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//sys	mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
 | 
			
		||||
| 
						 | 
				
			
			@ -1444,6 +1438,8 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e
 | 
			
		|||
//sys	Acct(path string) (err error)
 | 
			
		||||
//sys	AddKey(keyType string, description string, payload []byte, ringid int) (id int, err error)
 | 
			
		||||
//sys	Adjtimex(buf *Timex) (state int, err error)
 | 
			
		||||
//sys	Capget(hdr *CapUserHeader, data *CapUserData) (err error)
 | 
			
		||||
//sys	Capset(hdr *CapUserHeader, data *CapUserData) (err error)
 | 
			
		||||
//sys	Chdir(path string) (err error)
 | 
			
		||||
//sys	Chroot(path string) (err error)
 | 
			
		||||
//sys	ClockGetres(clockid int32, res *Timespec) (err error)
 | 
			
		||||
| 
						 | 
				
			
			@ -1531,9 +1527,13 @@ func Setgid(uid int) (err error) {
 | 
			
		|||
	return EOPNOTSUPP
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) {
 | 
			
		||||
	return signalfd(fd, sigmask, _C__NSIG/8, flags)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//sys	Setpriority(which int, who int, prio int) (err error)
 | 
			
		||||
//sys	Setxattr(path string, attr string, data []byte, flags int) (err error)
 | 
			
		||||
//sys	Signalfd(fd int, mask *Sigset_t, flags int) = SYS_SIGNALFD4
 | 
			
		||||
//sys	signalfd(fd int, sigmask *Sigset_t, maskSize uintptr, flags int) (newfd int, err error) = SYS_SIGNALFD4
 | 
			
		||||
//sys	Statx(dirfd int, path string, flags int, mask int, stat *Statx_t) (err error)
 | 
			
		||||
//sys	Sync()
 | 
			
		||||
//sys	Syncfs(fd int) (err error)
 | 
			
		||||
| 
						 | 
				
			
			@ -1662,6 +1662,82 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
 | 
			
		|||
	return EACCES
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//sys nameToHandleAt(dirFD int, pathname string, fh *fileHandle, mountID *_C_int, flags int) (err error) = SYS_NAME_TO_HANDLE_AT
 | 
			
		||||
//sys openByHandleAt(mountFD int, fh *fileHandle, flags int) (fd int, err error) = SYS_OPEN_BY_HANDLE_AT
 | 
			
		||||
 | 
			
		||||
// fileHandle is the argument to nameToHandleAt and openByHandleAt. We
 | 
			
		||||
// originally tried to generate it via unix/linux/types.go with "type
 | 
			
		||||
// fileHandle C.struct_file_handle" but that generated empty structs
 | 
			
		||||
// for mips64 and mips64le. Instead, hard code it for now (it's the
 | 
			
		||||
// same everywhere else) until the mips64 generator issue is fixed.
 | 
			
		||||
type fileHandle struct {
 | 
			
		||||
	Bytes uint32
 | 
			
		||||
	Type  int32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FileHandle represents the C struct file_handle used by
 | 
			
		||||
// name_to_handle_at (see NameToHandleAt) and open_by_handle_at (see
 | 
			
		||||
// OpenByHandleAt).
 | 
			
		||||
type FileHandle struct {
 | 
			
		||||
	*fileHandle
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewFileHandle constructs a FileHandle.
 | 
			
		||||
func NewFileHandle(handleType int32, handle []byte) FileHandle {
 | 
			
		||||
	const hdrSize = unsafe.Sizeof(fileHandle{})
 | 
			
		||||
	buf := make([]byte, hdrSize+uintptr(len(handle)))
 | 
			
		||||
	copy(buf[hdrSize:], handle)
 | 
			
		||||
	fh := (*fileHandle)(unsafe.Pointer(&buf[0]))
 | 
			
		||||
	fh.Type = handleType
 | 
			
		||||
	fh.Bytes = uint32(len(handle))
 | 
			
		||||
	return FileHandle{fh}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fh *FileHandle) Size() int   { return int(fh.fileHandle.Bytes) }
 | 
			
		||||
func (fh *FileHandle) Type() int32 { return fh.fileHandle.Type }
 | 
			
		||||
func (fh *FileHandle) Bytes() []byte {
 | 
			
		||||
	n := fh.Size()
 | 
			
		||||
	if n == 0 {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return (*[1 << 30]byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&fh.fileHandle.Type)) + 4))[:n:n]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NameToHandleAt wraps the name_to_handle_at system call; it obtains
 | 
			
		||||
// a handle for a path name.
 | 
			
		||||
func NameToHandleAt(dirfd int, path string, flags int) (handle FileHandle, mountID int, err error) {
 | 
			
		||||
	var mid _C_int
 | 
			
		||||
	// Try first with a small buffer, assuming the handle will
 | 
			
		||||
	// only be 32 bytes.
 | 
			
		||||
	size := uint32(32 + unsafe.Sizeof(fileHandle{}))
 | 
			
		||||
	didResize := false
 | 
			
		||||
	for {
 | 
			
		||||
		buf := make([]byte, size)
 | 
			
		||||
		fh := (*fileHandle)(unsafe.Pointer(&buf[0]))
 | 
			
		||||
		fh.Bytes = size - uint32(unsafe.Sizeof(fileHandle{}))
 | 
			
		||||
		err = nameToHandleAt(dirfd, path, fh, &mid, flags)
 | 
			
		||||
		if err == EOVERFLOW {
 | 
			
		||||
			if didResize {
 | 
			
		||||
				// We shouldn't need to resize more than once
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			didResize = true
 | 
			
		||||
			size = fh.Bytes + uint32(unsafe.Sizeof(fileHandle{}))
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		return FileHandle{fh}, int(mid), nil
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// OpenByHandleAt wraps the open_by_handle_at system call; it opens a
 | 
			
		||||
// file via a handle as previously returned by NameToHandleAt.
 | 
			
		||||
func OpenByHandleAt(mountFD int, handle FileHandle, flags int) (fd int, err error) {
 | 
			
		||||
	return openByHandleAt(mountFD, handle.fileHandle, flags)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Unimplemented
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -1669,8 +1745,6 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
 | 
			
		|||
// Alarm
 | 
			
		||||
// ArchPrctl
 | 
			
		||||
// Brk
 | 
			
		||||
// Capget
 | 
			
		||||
// Capset
 | 
			
		||||
// ClockNanosleep
 | 
			
		||||
// ClockSettime
 | 
			
		||||
// Clone
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -272,3 +272,16 @@ func SyncFileRange(fd int, off int64, n int64, flags int) error {
 | 
			
		|||
	// order of their arguments.
 | 
			
		||||
	return armSyncFileRange(fd, flags, off, n)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//sys	kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, flags int) (err error)
 | 
			
		||||
 | 
			
		||||
func KexecFileLoad(kernelFd int, initrdFd int, cmdline string, flags int) error {
 | 
			
		||||
	cmdlineLen := len(cmdline)
 | 
			
		||||
	if cmdlineLen > 0 {
 | 
			
		||||
		// Account for the additional NULL byte added by
 | 
			
		||||
		// BytePtrFromString in kexecFileLoad. The kexec_file_load
 | 
			
		||||
		// syscall expects a NULL-terminated string.
 | 
			
		||||
		cmdlineLen++
 | 
			
		||||
	}
 | 
			
		||||
	return kexecFileLoad(kernelFd, initrdFd, cmdlineLen, cmdline, flags)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -94,6 +94,18 @@ func nametomib(name string) (mib []_C_int, err error) {
 | 
			
		|||
	return mib, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntIno(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntReclen(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntNamlen(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SysctlClockinfo(name string) (*Clockinfo, error) {
 | 
			
		||||
	mib, err := sysctlmib(name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -120,9 +132,30 @@ func Pipe(p []int) (err error) {
 | 
			
		|||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//sys getdents(fd int, buf []byte) (n int, err error)
 | 
			
		||||
//sys Getdents(fd int, buf []byte) (n int, err error)
 | 
			
		||||
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
 | 
			
		||||
	return getdents(fd, buf)
 | 
			
		||||
	n, err = Getdents(fd, buf)
 | 
			
		||||
	if err != nil || basep == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var off int64
 | 
			
		||||
	off, err = Seek(fd, 0, 1 /* SEEK_CUR */)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		*basep = ^uintptr(0)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	*basep = uintptr(off)
 | 
			
		||||
	if unsafe.Sizeof(*basep) == 8 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if off>>32 != 0 {
 | 
			
		||||
		// We can't stuff the offset back into a uintptr, so any
 | 
			
		||||
		// future calls would be suspect. Generate an error.
 | 
			
		||||
		// EIO is allowed by getdirentries.
 | 
			
		||||
		err = EIO
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const ImplementsGetwd = true
 | 
			
		||||
| 
						 | 
				
			
			@ -154,43 +187,6 @@ func setattrlistTimes(path string, times []Timespec, flags int) error {
 | 
			
		|||
 | 
			
		||||
//sys	ioctl(fd int, req uint, arg uintptr) (err error)
 | 
			
		||||
 | 
			
		||||
// ioctl itself should not be exposed directly, but additional get/set
 | 
			
		||||
// functions for specific types are permissible.
 | 
			
		||||
 | 
			
		||||
// IoctlSetInt performs an ioctl operation which sets an integer value
 | 
			
		||||
// on fd, using the specified request number.
 | 
			
		||||
func IoctlSetInt(fd int, req uint, value int) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(value))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlSetTermios(fd int, req uint, value *Termios) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IoctlGetInt performs an ioctl operation which gets an integer value
 | 
			
		||||
// from fd, using the specified request number.
 | 
			
		||||
func IoctlGetInt(fd int, req uint) (int, error) {
 | 
			
		||||
	var value int
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
 | 
			
		||||
	var value Winsize
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 | 
			
		||||
	var value Termios
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetPtmget(fd int, req uint) (*Ptmget, error) {
 | 
			
		||||
	var value Ptmget
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,6 +43,18 @@ func nametomib(name string) (mib []_C_int, err error) {
 | 
			
		|||
	return nil, EINVAL
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntIno(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Fileno), unsafe.Sizeof(Dirent{}.Fileno))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntReclen(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntNamlen(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SysctlClockinfo(name string) (*Clockinfo, error) {
 | 
			
		||||
	mib, err := sysctlmib(name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -89,9 +101,30 @@ func Pipe(p []int) (err error) {
 | 
			
		|||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//sys getdents(fd int, buf []byte) (n int, err error)
 | 
			
		||||
//sys Getdents(fd int, buf []byte) (n int, err error)
 | 
			
		||||
func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
 | 
			
		||||
	return getdents(fd, buf)
 | 
			
		||||
	n, err = Getdents(fd, buf)
 | 
			
		||||
	if err != nil || basep == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var off int64
 | 
			
		||||
	off, err = Seek(fd, 0, 1 /* SEEK_CUR */)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		*basep = ^uintptr(0)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	*basep = uintptr(off)
 | 
			
		||||
	if unsafe.Sizeof(*basep) == 8 {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if off>>32 != 0 {
 | 
			
		||||
		// We can't stuff the offset back into a uintptr, so any
 | 
			
		||||
		// future calls would be suspect. Generate an error.
 | 
			
		||||
		// EIO was allowed by getdirentries.
 | 
			
		||||
		err = EIO
 | 
			
		||||
	}
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const ImplementsGetwd = true
 | 
			
		||||
| 
						 | 
				
			
			@ -145,43 +178,6 @@ func setattrlistTimes(path string, times []Timespec, flags int) error {
 | 
			
		|||
 | 
			
		||||
//sys	ioctl(fd int, req uint, arg uintptr) (err error)
 | 
			
		||||
 | 
			
		||||
// ioctl itself should not be exposed directly, but additional get/set
 | 
			
		||||
// functions for specific types are permissible.
 | 
			
		||||
 | 
			
		||||
// IoctlSetInt performs an ioctl operation which sets an integer value
 | 
			
		||||
// on fd, using the specified request number.
 | 
			
		||||
func IoctlSetInt(fd int, req uint, value int) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(value))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlSetWinsize(fd int, req uint, value *Winsize) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlSetTermios(fd int, req uint, value *Termios) error {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IoctlGetInt performs an ioctl operation which gets an integer value
 | 
			
		||||
// from fd, using the specified request number.
 | 
			
		||||
func IoctlGetInt(fd int, req uint) (int, error) {
 | 
			
		||||
	var value int
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
 | 
			
		||||
	var value Winsize
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 | 
			
		||||
	var value Termios
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//sys	ppoll(fds *PollFd, nfds int, timeout *Timespec, sigmask *Sigset_t) (n int, err error)
 | 
			
		||||
 | 
			
		||||
func Ppoll(fds []PollFd, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,37 @@
 | 
			
		|||
// Copyright 2019 The Go Authors. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
// +build arm64,openbsd
 | 
			
		||||
 | 
			
		||||
package unix
 | 
			
		||||
 | 
			
		||||
func setTimespec(sec, nsec int64) Timespec {
 | 
			
		||||
	return Timespec{Sec: sec, Nsec: nsec}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func setTimeval(sec, usec int64) Timeval {
 | 
			
		||||
	return Timeval{Sec: sec, Usec: usec}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SetKevent(k *Kevent_t, fd, mode, flags int) {
 | 
			
		||||
	k.Ident = uint64(fd)
 | 
			
		||||
	k.Filter = int16(mode)
 | 
			
		||||
	k.Flags = uint16(flags)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (iov *Iovec) SetLen(length int) {
 | 
			
		||||
	iov.Len = uint64(length)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (msghdr *Msghdr) SetControllen(length int) {
 | 
			
		||||
	msghdr.Controllen = uint32(length)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (cmsg *Cmsghdr) SetLen(length int) {
 | 
			
		||||
	cmsg.Len = uint32(length)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SYS___SYSCTL is used by syscall_bsd.go for all BSDs, but in modern versions
 | 
			
		||||
// of openbsd/amd64 the syscall is called sysctl instead of __sysctl.
 | 
			
		||||
const SYS___SYSCTL = SYS_SYSCTL
 | 
			
		||||
| 
						 | 
				
			
			@ -35,6 +35,22 @@ type SockaddrDatalink struct {
 | 
			
		|||
	raw    RawSockaddrDatalink
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntIno(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Ino), unsafe.Sizeof(Dirent{}.Ino))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntReclen(buf []byte) (uint64, bool) {
 | 
			
		||||
	return readInt(buf, unsafe.Offsetof(Dirent{}.Reclen), unsafe.Sizeof(Dirent{}.Reclen))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func direntNamlen(buf []byte) (uint64, bool) {
 | 
			
		||||
	reclen, ok := direntReclen(buf)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return 0, false
 | 
			
		||||
	}
 | 
			
		||||
	return reclen - uint64(unsafe.Offsetof(Dirent{}.Name)), true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//sysnb	pipe(p *[2]_C_int) (n int, err error)
 | 
			
		||||
 | 
			
		||||
func Pipe(p []int) (err error) {
 | 
			
		||||
| 
						 | 
				
			
			@ -189,6 +205,7 @@ func Setgroups(gids []int) (err error) {
 | 
			
		|||
	return setgroups(len(a), &a[0])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ReadDirent reads directory entries from fd and writes them into buf.
 | 
			
		||||
func ReadDirent(fd int, buf []byte) (n int, err error) {
 | 
			
		||||
	// Final argument is (basep *uintptr) and the syscall doesn't take nil.
 | 
			
		||||
	// TODO(rsc): Can we use a single global basep for all calls?
 | 
			
		||||
| 
						 | 
				
			
			@ -536,40 +553,10 @@ func Minor(dev uint64) uint32 {
 | 
			
		|||
 | 
			
		||||
//sys	ioctl(fd int, req uint, arg uintptr) (err error)
 | 
			
		||||
 | 
			
		||||
func IoctlSetInt(fd int, req uint, value int) (err error) {
 | 
			
		||||
	return ioctl(fd, req, uintptr(value))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlSetWinsize(fd int, req uint, value *Winsize) (err error) {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ioctlSetTermios(fd int, req uint, value *Termios) (err error) {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlSetTermio(fd int, req uint, value *Termio) (err error) {
 | 
			
		||||
	return ioctl(fd, req, uintptr(unsafe.Pointer(value)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetInt(fd int, req uint) (int, error) {
 | 
			
		||||
	var value int
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetWinsize(fd int, req uint) (*Winsize, error) {
 | 
			
		||||
	var value Winsize
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetTermios(fd int, req uint) (*Termios, error) {
 | 
			
		||||
	var value Termios
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
	return &value, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func IoctlGetTermio(fd int, req uint) (*Termio, error) {
 | 
			
		||||
	var value Termio
 | 
			
		||||
	err := ioctl(fd, req, uintptr(unsafe.Pointer(&value)))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue