Commit Graph

1209 Commits

Author SHA1 Message Date
Herbert Xu aeb4c132f3 crypto: talitos - Convert to new AEAD interface
This patch converts talitos to the new AEAD interface.  IV generation
has been removed since it's equivalent to a software implementation.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-08-04 20:45:34 +08:00
Herbert Xu e19ab1211d crypto: qat - Convert to new AEAD interface
This patch converts qat to the new AEAD interface.  IV generation
has been removed since it's equivalent to a software implementation.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Tested-by: Tadeusz Struk <tadeusz.struk@intel.com>
2015-08-04 20:45:33 +08:00
Herbert Xu c1359495c8 crypto: picoxcell - Convert to new AEAD interface
This patch converts picoxcell to the new AEAD interface.  IV
generation has been removed since it's equivalent to a software
implementation.

As picoxcell cannot handle SG lists longer than 16 elements,
this patch has made the software fallback mandatory.  If an SG
list comes in that exceeds the limit, we will simply use the
fallback.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-08-04 20:45:33 +08:00
Herbert Xu d7295a8dc9 crypto: ixp4xx - Convert to new AEAD interface
This patch converts ixp4xx to the new AEAD interface.  IV generation
has been removed since it's a purely software implementation.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-08-04 20:45:32 +08:00
Herbert Xu 479bcc7c5b crypto: caam - Convert authenc to new AEAD interface
This patch converts the authenc implementations in caam to the
new AEAD interface.  The biggest change is that seqiv no longer
generates a random IV.  Instead the IPsec sequence number is used
as the IV.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-08-04 20:45:31 +08:00
Herbert Xu 1d6669fa83 Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Merge the crypto tree to pull in the qat registration bug fix.
2015-08-04 20:44:35 +08:00
Aaron Sierra 76bea64c4c crypto: talitos - Remove zero_entry static initializer
Compiling the talitos driver with my GCC 4.3.1 e500v2 cross-compiler
resulted in a failed build due to the anonymous union/structures
introduced in this commit:

  crypto: talitos - enhanced talitos_desc struct for SEC1

The build error was:

  drivers/crypto/talitos.h:56: error: unknown field 'len' specified in initializer
  drivers/crypto/talitos.h:56: warning: missing braces around initializer
  drivers/crypto/talitos.h:56: warning: (near initialization for 'zero_entry.<anonymous>')
  drivers/crypto/talitos.h:57: error: unknown field 'j_extent' specified in initializer
  drivers/crypto/talitos.h:58: error: unknown field 'eptr' specified in initializer
  drivers/crypto/talitos.h:58: warning: excess elements in struct initializer
  drivers/crypto/talitos.h:58: warning: (near initialization for 'zero_entry')
  make[2]: *** [drivers/crypto/talitos.o] Error 1
  make[1]: *** [drivers/crypto] Error 2
  make: *** [drivers] Error 2

This patch eliminates the errors by relying on the C standard's
implicit assignment of zero to static variables.

Signed-off-by: Aaron Sierra <asierra@xes-inc.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-08-04 17:41:33 +08:00
Colin Ian King 327cbbabfb crypto: img-hash - fix spelling mistake in dev_err error message
Trival change, fix spelling mistake 'aquire' -> 'acquire' in
dev_err message.

Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-08-04 17:41:31 +08:00
Horia Geant? 4aad0cc5c3 crypto: caam - fix rfc4106 encap shared descriptor
The encap shared descriptor was changed to use the new IV convention.
In the process some commands were shifted, making the output length
zero, caam effectively writing garbage in dst.

While here, update the decap descriptor to execute the "write" commands
before the "read"s (as it previously was).
This makes sure the input fifo is drained before becoming full.

Fixes: 46218750d5 ("crypto: caam - Use new IV convention")
Signed-off-by: Horia Geant? <horia.geanta@freescale.com>
Signed-off-by: Tudor Ambarus <tudor.ambarus@freescale.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-31 15:17:33 +08:00
Dan Streetman 844190dbeb crypto: nx - use be32_to_cpu for __be32 field in debug msg
One of the debug messages in the NX 842 PowerNV driver is missing
the required be32_to_cpu() wrapper when accessing the __be32 field
csb->count.  Add the wrapper so the message will show the correct count.

Signed-off-by: Dan Streetman <ddstreet@ieee.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-30 21:49:41 +08:00
Dan Streetman 7371c0a5c2 crypto: nx - don't err if compressed output > input
Return success instead of error if compression succeeds but the output is
larger than the input.

It's unlikely that the caller will use the compressed data since it's
larger than the original uncompressed data, but there was no error and
returning an error code is incorrect.  Further, for testing small input
buffers, the output is likely to be larger than the input and success
needs to be returned to verify the test.

Signed-off-by: Dan Streetman <ddstreet@ieee.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-30 21:49:40 +08:00
Bruce Allan caa8c50849 crypto: qat - remove unnecessary list iteration
There's no need to iterate through the list for instances in the
accel_table since the number of devices is already known in this file.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-28 15:03:35 +08:00
Ahsan Atta ec0d6fa3e8 crypto: qat - Fix typo othewise->otherwise
Signed-off-by: Ahsan Atta <ahsan.atta@intel.com>
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-28 15:03:34 +08:00
Bruce Allan 13dd7bee20 crypto: qat - remove unused define
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-28 15:03:33 +08:00
Bruce Allan ea77fcdaf1 crypto: qat - fix bug in ADF_RING_SIZE_BYTES_MIN macro
The subject macro mistakenly compares the passed-in ring size in bytes
with ADF_RING_SIZE_4K which is 0x6 (an internal representation of 4KB)
rather than comparing with the intended value of 4096.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-28 15:03:32 +08:00
Bruce Allan 5995752ead crypto: qat - remove redundant struct elem
The element pci_dev_id in the struct adf_hw_device_data is redundant since
the PCI device id can be retrieved from the struct pci_dev.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-28 15:03:32 +08:00
Dan Streetman 03952d9801 crypto: nx - make platform drivers directly register with crypto
Remove the common 'platform' registration module, and move the crypto
compression driver registration into each of the pSeries and PowerNV
platform NX 842 drivers.  Change the nx-842.c code into simple common
functions that each platform driver uses to perform constraints-based
buffer changes, i.e. realigning and/or resizing buffers to match the
driver's hardware requirements.

The common 'platform' module was my mistake to create - since each
platform driver will only load/operate when running on its own
platform (i.e. a pSeries platform or a PowerNV platform), they can
directly register with the crypto subsystem, using the same alg and
driver name.  This removes unneeded complexity.

Signed-off-by: Dan Streetman <ddstreet@ieee.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-23 18:14:33 +08:00
Dan Streetman 174d66d472 crypto: nx - rename nx-842-crypto.c to nx-842.c
The last commit merged nx-842.c's code into nx-842-crypto.c.  It
did not rename nx-842-crypto.c to nx-842.c, in order to let the
patch more clearly show what was merged.  This just renames
nx-842-crypto.c to nx-842.c, with no changes to its code.

Signed-off-by: Dan Streetman <ddstreet@ieee.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-23 18:14:32 +08:00
Dan Streetman d31581a6e3 crypto: nx - merge nx-compress and nx-compress-crypto
Merge the nx-842.c code into nx-842-crypto.c.

This allows later patches to remove the 'platform' driver, and instead
allow each platform driver to directly register with the crypto
compression api.

Signed-off-by: Dan Streetman <ddstreet@ieee.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-23 18:14:31 +08:00
Dan Streetman 20fc311fc0 crypto: nx - use common code for both NX decompress success cases
Replace the duplicated finishing code (set destination buffer length and
set return code to 0) in the case of decompressing a buffer with no header
with a goto to the success case of decompressing a buffer with a header.

This is a trivial change that allows both success cases to use common code,
and includes the pr_debug() msg in both cases as well.

Signed-off-by: Dan Streetman <ddstreet@ieee.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-23 18:14:31 +08:00
Dan Streetman ee781b7ff3 crypto: nx - don't register pSeries driver if ENODEV
Don't register the pSeries driver when parsing the device tree returns
ENODEV.

The nx842_probe() function in the pSeries driver returns error instead
of registering as a crypto compression driver, when it receives an
error return value from the nx842_OF_upd() function that probes the
device tree nodes, except when ENODEV is returned.  However ENODEV
should not be a special case and the driver should not register when
there is no hw device, or the hw device is disabled.

Signed-off-by: Dan Streetman <ddstreet@ieee.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-23 18:14:30 +08:00
Dan Streetman 7f6e3aad5a crypto: nx - move kzalloc() out of spinlock
Move the kzalloc() calls in nx842_probe() and nx842_OF_upd() to the top
of the functions, before taking the devdata spinlock.

Since kzalloc() without GFP_ATOMIC can sleep, it can't be called while
holding a spinlock.  Move the calls to before taking the lock.

Signed-off-by: Dan Streetman <ddstreet@ieee.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-23 18:14:30 +08:00
Dan Streetman 90fd73f912 crypto: nx - remove pSeries NX 'status' field
Remove the 'status' field from the pSeries NX driver data.

The 'status' field isn't used by the driver at all; it simply checks the
devicetree status node at initialization, and returns success if 'okay'
and failure otherwise.

Signed-off-by: Dan Streetman <ddstreet@ieee.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-23 18:14:30 +08:00
Dan Streetman 039af9675f crypto: nx - remove __init/__exit from VIO functions
Remove the __init and __exit modifiers from the VIO driver probe and
remove functions.

The driver functions should not be marked __init/__exit because they
can/will be called during runtime, not only at module init and exit.

Signed-off-by: Dan Streetman <ddstreet@ieee.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-23 18:14:29 +08:00
Tadeusz Struk 8f5ea2df02 crypto: qat - Don't attempt to register algorithm multiple times
When multiple devices are present in the system the driver attempts
to register the same algorithm many times.

Changes in v2:
 - use proper synchronization mechanizm between register and unregister

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-23 18:14:28 +08:00
Herbert Xu f898c522f0 crypto: ixp4xx - Remove bogus BUG_ON on scattered dst buffer
This patch removes a bogus BUG_ON in the ablkcipher path that
triggers when the destination buffer is different from the source
buffer and is scattered.

Cc: stable@vger.kernel.org
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-23 18:09:18 +08:00
Tadeusz Struk 6f043b50da crypto: qat - Fix invalid synchronization between register/unregister sym algs
The synchronization method used atomic was bogus.
Use a proper synchronization with mutex.

Cc: stable@vger.kernel.org
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-23 18:09:17 +08:00
Tadeusz Struk 3cf080a7b7 crypto: qat - fix invalid check for RSA keylen in fips mode
The condition checking allowed key length was invalid.

Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-21 20:19:40 +08:00
LABBE Corentin 6298e94821 crypto: sunxi-ss - Add Allwinner Security System crypto accelerator
Add support for the Security System included in Allwinner SoC A20.
The Security System is a hardware cryptographic accelerator that support:
- MD5 and SHA1 hash algorithms
- AES block cipher in CBC/ECB mode with 128/196/256bits keys.
- DES and 3DES block cipher in CBC/ECB mode

Signed-off-by: LABBE Corentin <clabbe.montjoie@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-20 15:54:08 +08:00
Tudor Ambarus c1f2cd21ed crypto: caam - fix warning in APPEND_MATH_IMM_u64
An implicit truncation is done when using a variable of 64 bits
in MATH command:

warning: large integer implicitly truncated to unsigned type [-Woverflow]

Silence the compiler by feeding it with an explicit truncated value.

Signed-off-by: Tudor Ambarus <tudor.ambarus@freescale.com>
Signed-off-by: Horia Geant? <horia.geanta@freescale.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-20 15:53:43 +08:00
Horia Geant? 62743a4145 crypto: caam - fix RNG init descriptor ret. code checking
When successful, the descriptor that performs RNG initialization
is allowed to return a status code of 7000_0000h, since last command
in the descriptor is a JUMP HALT.

Signed-off-by: Horia Geant? <horia.geanta@freescale.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-20 15:53:42 +08:00
Horia Geant? f109674951 crypto: caam - fix snooping for write transactions
HW coherency won't work properly for CAAM write transactions
if AWCACHE is left to default (POR) value - 4'b0001.
It has to be programmed to 4'b0010, i.e. AXI3 Cacheable bit set.

For platforms that have HW coherency support:
-PPC-based: the update has no effect; CAAM coherency already works
due to the IOMMU (PAMU) driver setting the correct memory coherency
attributes
-ARM-based: the update fixes cache coherency issues,
since IOMMU (SMMU) driver is not programmed to behave similar to PAMU

Signed-off-by: Horia Geant? <horia.geanta@freescale.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-20 15:53:41 +08:00
Alex Porosanu e27513eb61 crypto: caam - fix ERA property reading
In order to ensure that the ERA property is properly read from DT
on all platforms, of_property_read* function needs to be used.

Signed-off-by: Alex Porosanu <alexandru.porosanu@freescale.com>
Signed-off-by: Horia Geant? <horia.geanta@freescale.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-20 15:53:39 +08:00
Tadeusz Struk a990532023 crypto: qat - Add support for RSA algorithm
Add RSA support to QAT driver.
Removed unused RNG rings.

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-17 21:20:18 +08:00
Tadeusz Struk 28cfaf67e5 crypto: qat - add MMP FW support to accel engine
Add code that loads the MMP firmware

Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-17 21:20:16 +08:00
Pingchao Yang f3dd7e60d2 crypto: qat - add support for MMP FW
Load Modular Math Processor(MMP) firmware into QAT devices to support
public key algorithm acceleration.

Signed-off-by: Pingchao Yang <pingchao.yang@intel.com>
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-17 21:20:15 +08:00
Herbert Xu cc81565307 crypto: nx - Convert ccm to new AEAD interface
This patch converts the nx ccm and 4309 implementations to the
new AEAD interface.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-17 21:20:13 +08:00
Leonidas Da Silva Barbosa 2d6f0600b2 crypto: vmx - Adding enable_kernel_vsx() to access VSX instructions
vmx-crypto driver make use of some VSX instructions which are
only available if VSX is enabled. Running in cases where VSX
are not enabled vmx-crypto fails in a VSX exception.

In order to fix this enable_kernel_vsx() was added to turn on
VSX instructions for vmx-crypto.

Signed-off-by: Leonidas S. Barbosa <leosilva@linux.vnet.ibm.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-14 14:56:48 +08:00
Krzysztof Kozlowski 1f644a7c7c crypto: marvell/cesa - Drop owner assignment from platform_driver
platform_driver does not need to set an owner because
platform_driver_register() will set it.

Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-14 14:56:48 +08:00
Herbert Xu 46218750d5 crypto: caam - Use new IV convention
This patch converts rfc4106 to the new calling convention where
the IV is now part of the AD and needs to be skipped.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-14 14:56:47 +08:00
Herbert Xu c3d219495e crypto: nx - Use new IV convention
This patch converts rfc4106 to the new calling convention where
the IV is now part of the AD and needs to be skipped.  This patch
also makes use of type-safe AEAD functions where possible.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-14 14:56:47 +08:00
Herbert Xu 23ad69aafe crypto: nx/842 - Fix context corruption
The transform context is shared memory and must not be written
to without locking.  This patch adds locking to nx-842 to prevent
context corruption.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-14 14:56:45 +08:00
Herbert Xu 773bb50625 Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Merge the crypto tree to pull in the nx reentrancy patch.
2015-07-14 14:55:32 +08:00
Vutla, Lokesh 340d9d317e crypto: omap-aes - Use BIT() macro
Use BIT()/GENMASK() macros for all register definitions instead of
hand-writing bit masks.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-08 15:18:46 +08:00
Vutla, Lokesh 5396c6c074 crypto: omap-aes - Fix configuring of AES mode
AES_CTRL_REG is used to configure AES mode. Before configuring
any mode we need to make sure all other modes are reset or else
driver will misbehave. So mask all modes before configuring
any AES mode.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-08 15:18:45 +08:00
Vutla, Lokesh 6e2e3d1de4 crypto: omap-aes - Increase priority of hw accelerator
Increasing the priority of omap-aes hw algos, in order to take
precedence over sw algos.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-08 15:18:43 +08:00
Vutla, Lokesh 310b0d55f0 crypto: omap-aes - Fix CTR mode
Algo self tests are failing for CTR mode with omap-aes driver,
giving the following error:

[  150.053644]       omap_aes_crypt: request size is not exact amount of AES blocks
[  150.061262] alg: skcipher: encryption failed on test 5 for ctr-aes-omap: ret=22

This is because the input length is not aligned with AES_BLOCK_SIZE.
Adding support for omap-aes driver for inputs with length not aligned
with AES_BLOCK_SIZE.

Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-08 15:18:42 +08:00
Herbert Xu 030f4e9687 crypto: nx - Fix reentrancy bugs
This patch fixes a host of reentrancy bugs in the nx driver.  The
following algorithms are affected:

* CCM
* GCM
* CTR
* XCBC
* SHA256
* SHA512

The crypto API allows a single transform to be used by multiple
threads simultaneously.  For example, IPsec will use a single tfm
to process packets for a given SA.  As packets may arrive on
multiple CPUs that tfm must be reentrant.

The nx driver does try to deal with this by using a spin lock.
Unfortunately only the basic AES/CBC/ECB algorithms do this in
the correct way.

The symptom of these bugs may range from the generation of incorrect
output to memory corruption.

Cc: stable@vger.kernel.org
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-08 15:14:13 +08:00
Nishanth Aravamudan 2b93f7ee08 crypto: nx - reduce chattiness of platform drivers
While we never would successfully load on the wrong machine type, there
is extra output by default regardless of machine type.

For instance, on a PowerVM LPAR, we see the following:

nx_compress_powernv: loading
nx_compress_powernv: no coprocessors found

even though those coprocessors could never be found.

Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com>
Cc: Dan Streetman <ddstreet@us.ibm.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: linux-crypto@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-07 21:54:26 +08:00
Nishanth Aravamudan 7abd75bf7a crypto: nx - do not emit extra output if status is disabled
If the device-tree indicates the nx-842 device's status is 'disabled',
we emit two messages:

nx_compress_pseries ibm,compression-v1: nx842_OF_upd_status: status 'disabled' is not 'okay'.
nx_compress_pseries ibm,compression-v1: nx842_OF_upd: device disabled

Given that 'disabled' is a valid state, and we are going to emit that
the device is disabled, only print out a non-'okay' status if it is not
'disabled'.

Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2015-07-06 16:32:03 +08:00