Commit Graph

737220 Commits

Author SHA1 Message Date
Markus Elfring
0d576d9239 crypto: sahara - Delete an error message for a failed memory allocation in sahara_probe()
Omit an extra message for a memory allocation failure in this function.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:36 +08:00
Markus Elfring
0c704bf044 crypto: ux500 - Delete two unnecessary variable initialisations in ux500_cryp_probe()
Two local variables will eventually be set to appropriate pointers
a bit later. Thus omit their explicit initialisation at the beginning.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:34 +08:00
Markus Elfring
9dea694135 crypto: ux500 - Adjust an error message in ux500_cryp_probe()
Replace the function name in this error message so that the same name
is mentioned according to what was called before.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:34 +08:00
Markus Elfring
50ca524d7c crypto: ux500 - Adjust two condition checks in ux500_cryp_probe()
The local variable "cryp_error" was used only for two condition checks.

* Check the return values from these function calls directly instead.

* Delete this variable which became unnecessary with this refactoring.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:34 +08:00
Markus Elfring
dbbd5d1eff crypto: ux500 - Delete an error message for a failed memory allocation in ux500_cryp_probe()
Omit an extra message for a memory allocation failure in this function.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:33 +08:00
Conor McLoughlin
333e18c5cc crypto: testmgr - Fix incorrect values in PKCS#1 test vector
The RSA private key for the first form should have
version, prime1, prime2, exponent1, exponent2, coefficient
values 0.
With non-zero values for prime1,2, exponent 1,2 and coefficient
the Intel QAT driver will assume that values are provided for the
private key second form. This will result in signature verification
failures for modules where QAT device is present and the modules
are signed with rsa,sha256.

Cc: <stable@vger.kernel.org>
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu@intel.com>
Signed-off-by: Conor McLoughlin <conor.mcloughlin@intel.com>
Reviewed-by: Stephan Mueller <smueller@chronox.de>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:32 +08:00
Antoine Tenart
57240a78be crypto: inside-secure - unmap the result in the hash send error path
This patch adds a label to unmap the result buffer in the hash send
function error path.

Fixes: 1b44c5a60c ("crypto: inside-secure - add SafeXcel EIP197 crypto engine driver")
Suggested-by: Ofer Heifetz <oferh@marvell.com>
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:28 +08:00
Antoine Tenart
f7268c538b crypto: inside-secure - keep the requests push/pop synced
This patch updates the Inside Secure SafeXcel driver to avoid being
out-of-sync between the number of requests sent and the one being
completed.

The number of requests acknowledged by the driver can be different than
the threshold that was configured if new requests were being pushed to
the h/w in the meantime. The driver wasn't taking those into account,
and the number of remaining requests to handled (to reconfigure the
interrupt threshold) could be out-of sync.

This patch fixes it by not taking in account the number of requests
left, but by taking in account the total number of requests being sent
to the hardware, so that new requests are being taken into account.

Fixes: dc7e28a328 ("crypto: inside-secure - dequeue all requests at once")
Suggested-by: Ofer Heifetz <oferh@marvell.com>
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:27 +08:00
Antoine Tenart
b7007dbccd crypto: inside-secure - fix the invalidation step during cra_exit
When exiting a transformation, the cra_exit() helper is called in each
driver providing one. The Inside Secure SafeXcel driver has one, which
is responsible of freeing some areas and of sending one invalidation
request to the crypto engine, to invalidate the context that was used
during the transformation.

We could see in some setups (when lots of transformations were being
used with a short lifetime, and hence lots of cra_exit() calls) NULL
pointer dereferences and other weird issues. All these issues were
coming from accessing the tfm context.

The issue is the invalidation request completion is checked using a
wait_for_completion_interruptible() call in both the cipher and hash
cra_exit() helpers. In some cases this was interrupted while the
invalidation request wasn't processed yet. And then cra_exit() returned,
and its caller was freeing the tfm instance. Only then the request was
being handled by the SafeXcel driver, which lead to the said issues.

This patch fixes this by using wait_for_completion() calls in these
specific cases.

Fixes: 1b44c5a60c ("crypto: inside-secure - add SafeXcel EIP197 crypto engine driver")
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:27 +08:00
Antoine Tenart
95831ceafc crypto: inside-secure - do not process request if no command was issued
This patch adds a check in the SafeXcel dequeue function, to avoid
processing request further if no hardware command was issued. This can
happen in certain cases where the ->send() function caches all the data
that would have been send.

Fixes: 809778e02c ("crypto: inside-secure - fix hash when length is a multiple of a block")
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:26 +08:00
Antoine Tenart
666a9c70b0 crypto: inside-secure - fix the cache_len computation
This patch fixes the cache length computation as cache_len could end up
being a negative value. The check between the queued size and the
block size is updated to reflect the caching mechanism which can cache
up to a full block size (included!).

Fixes: 809778e02c ("crypto: inside-secure - fix hash when length is a multiple of a block")
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:26 +08:00
Antoine Tenart
c1a8fa6e24 crypto: inside-secure - fix the extra cache computation
This patch fixes the extra cache computation when the queued data is a
multiple of a block size. This fixes the hash support in some cases.

Fixes: 809778e02c ("crypto: inside-secure - fix hash when length is a multiple of a block")
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:24 +08:00
Antoine Tenart
e1d24c0bb7 crypto: inside-secure - do not overwrite the threshold value
This patch fixes the Inside Secure SafeXcel driver not to overwrite the
interrupt threshold value. In certain cases the value of this register,
which controls when to fire an interrupt, was overwritten. This lead to
packet not being processed or acked as the driver never was aware of
their completion.

This patch fixes this behaviour by not setting the threshold when
requests are being processed by the engine.

Fixes: dc7e28a328 ("crypto: inside-secure - dequeue all requests at once")
Suggested-by: Ofer Heifetz <oferh@marvell.com>
Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:23 +08:00
Antoine Tenart
c4ecc8f0bd MAINTAINERS: update the Inside Secure maintainer email
Free Electrons became Bootlin. Update my email accordingly.

Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:22 +08:00
Stefan Wahren
7b4c5d30d0 hwrng: bcm2835 - Handle deferred clock properly
In case the probe of the clock is deferred, we would assume it is
optional. This is wrong, so defer the probe of this driver until
the clock is available.

Fixes: 791af4f490 ("hwrng: bcm2835 - Manage an optional clock")
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:21 +08:00
Jinbum Park
4ff8b1dd81 crypto: arm/aes-cipher - move S-box to .rodata section
Move the AES inverse S-box to the .rodata section
where it is safe from abuse by speculation.

Signed-off-by: Jinbum Park <jinb.park7@gmail.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:19 +08:00
Peter Robinson
7c73cf4cc2 crypto: sunxi-ss - Add MODULE_ALIAS to sun4i-ss
The MODULE_ALIAS is required to enable the sun4i-ss driver to load
automatically when built at a module. Tested on a Cubietruck.

Fixes: 6298e94821 ("crypto: sunxi-ss - Add Allwinner Security System crypto accelerator")
Signed-off-by: Peter Robinson <pbrobinson@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-22 22:16:15 +08:00
Fabien DESSENNE
a43a34845a crypto: stm32/cryp - add stm32mp1 support
stm32mp1 differs from stm32f7 in the way it handles byte ordering and
padding for aes gcm & ccm algo.

Signed-off-by: Fabien Dessenne <fabien.dessenne@st.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:57 +08:00
Fabien DESSENNE
9d3b5030bc crypto: stm32/cryp - add aes gcm / ccm support
Add AEAD cipher algorithms for aes gcm and ccm.

Signed-off-by: Fabien Dessenne <fabien.dessenne@st.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:57 +08:00
Colin Ian King
9f32bb5358 crypto: qat - Make several functions static
Functions qat_rsa_set_n, qat_rsa_set_e and qat_rsa_set_n are local to
the source and do not need to be in global scope, so make them static.

Cleans up sparse warnings:
drivers/crypto/qat/qat_common/qat_asym_algs.c:972:5: warning: symbol
'qat_rsa_set_n' was not declared. Should it be static?
drivers/crypto/qat/qat_common/qat_asym_algs.c:1003:5: warning: symbol
'qat_rsa_set_e' was not declared. Should it be static?
drivers/crypto/qat/qat_common/qat_asym_algs.c:1027:5: warning: symbol
'qat_rsa_set_d' was not declared. Should it be static?

Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:57 +08:00
Colin Ian King
404a36a73c crypto: ccp - Make function ccp_get_dma_chan_attr static
Function ccp_get_dma_chan_attr is local to the source and does not
need to be in global scope, so make it static.

Cleans up sparse warning:
drivers/crypto/ccp/ccp-dmaengine.c:41:14: warning: symbol
'ccp_get_dma_chan_attr' was not declared. Should it be static?

Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:56 +08:00
Colin Ian King
1efb892b6c crypto: chelsio - Make function aead_ccm_validate_input static
Function aead_ccm_validate_input is local to the source and does not
need to be in global scope, so make it static.

Cleans up sparse warning:
drivers/crypto/chelsio/chcr_algo.c:2627:5: warning: symbol
'aead_ccm_validate_input' was not declared. Should it be static?

Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:56 +08:00
Tim Chen
b09dd34705 x86/crypto: Designate maintainer for SHA-1/256/512
multibuffer driver

Even though I created the original implementation of SHA1 multibuffer
driver, Megha extended it to SHA256 and SHA512 and she is now maintaining
the code for SHA1/SHA256/SHA512 multi-buffer driver.

Add the entry in the MAINTAINERS file so any update patch can find
its way properly to Megha.

Signed-off-by: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:56 +08:00
Lionel Debieve
d03d29bd18 crypto: stm32/hash - rework padding length
Due to another patch, the dma fails when padding is
needed as the given length is not correct.

Signed-off-by: Lionel Debieve <lionel.debieve@st.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:55 +08:00
Lionel Debieve
ff1cae4e7f crypto: stm32/hash - fix performance issues
Fixing bugs link to stress tests. Bad results are
detected during testmgr selftests executing in a
faster environment. bufcnt value may be resetted and
false IT are sometimes detected.

Signed-off-by: Lionel Debieve <lionel.debieve@st.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:55 +08:00
Lionel Debieve
a3d98b9028 crypto: stm32/hash - avoid error if maxburst not defined
dma-maxburst is an optional value and must not return
error in case of dma not used (or max-burst not defined).

Signed-off-by: Lionel Debieve <lionel.debieve@st.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:55 +08:00
Horia Geantă
d3e41b50b4 crypto: caam/qi - add GCM support
Add support for AES working in Galois Counter Mode.
The following algorithms are added:
gcm(aes)
rfc4106(gcm(aes))
rfc4543(gcm(aes))

There is a limitation related to IV size, similar to the one present in
SW implementation (crypto/gcm.c):
The only IV size allowed is 12 bytes. It will be padded by HW to the right
with 0x0000_0001 (up to 16 bytes - AES block size), according to the
GCM specification.

Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:55 +08:00
Horia Geantă
87ec3a0b1c crypto: caam - prepare for gcm(aes) support over QI interface
Update gcm(aes) descriptors (generic, rfc4106 and rfc4543) such that
they would also work when submitted via the QI interface.

Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:53 +08:00
Horia Geantă
cb3078f35b crypto: caam/qi - return -EBADMSG for ICV check failure
Crypto drivers are expected to return -EBADMSG in case of
ICV check (authentication) failure.

In this case it also makes sense to suppress the error message
in the QI dequeue callback.

Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:53 +08:00
Corentin LABBE
dc7bcef5e9 crypto: stm32-cryp - convert to the new crypto engine API
This patch convert the stm32-cryp driver to the new crypto engine API.
Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Tested-by: Fabien Dessenne <fabien.dessenne@st.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:53 +08:00
Corentin LABBE
fb45490d50 crypto: stm32-hash - convert to the new crypto engine API
This patch convert the stm32-hash driver to the new crypto engine API.

Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Tested-by: Fabien Dessenne <fabien.dessenne@st.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:52 +08:00
Corentin LABBE
67189375bb crypto: virtio - convert to new crypto engine API
This patch convert the driver to the new crypto engine API.

Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:52 +08:00
Corentin LABBE
c21c8b8984 crypto: omap - convert to new crypto engine API
This patch convert the driver to the new crypto engine API.

Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:51 +08:00
Corentin LABBE
218d1cc186 crypto: engine - Permit to enqueue all async requests
The crypto engine could actually only enqueue hash and ablkcipher request.
This patch permit it to enqueue any type of crypto_async_request.

Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Tested-by: Fabien Dessenne <fabien.dessenne@st.com>
Tested-by: Fabien Dessenne <fabien.dessenne@st.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:50 +08:00
Corentin LABBE
ce09a6c042 crypto: doc - document crypto engine API
Signed-off-by: Corentin Labbe <clabbe.montjoie@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:49 +08:00
Jia-Ju Bai
9a69b7ae79 crypto: user - Replace GFP_ATOMIC with GFP_KERNEL in crypto_report
After checking all possible call chains to crypto_report here,
my tool finds that crypto_report is never called in atomic context.
And crypto_report calls crypto_alg_match which calls down_read,
thus it proves again that crypto_report can call functions which may sleep.
Thus GFP_ATOMIC is not necessary, and it can be replaced with GFP_KERNEL.

This is found by a static analysis tool named DCNS written by myself.

Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:47 +08:00
Jia-Ju Bai
1ca2809897 crypto: rsa-pkcs1pad - Replace GFP_ATOMIC with GFP_KERNEL in pkcs1pad_encrypt_sign_complete
After checking all possible call chains to kzalloc here,
my tool finds that this kzalloc is never called in atomic context.
Thus GFP_ATOMIC is not necessary, and it can be replaced with GFP_KERNEL.

This is found by a static analysis tool named DCNS written by myself.

Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:47 +08:00
Eric Biggers
c7f582f5de crypto: sha512-mb - remove HASH_FIRST flag
The HASH_FIRST flag is never set.  Remove it.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:46 +08:00
Eric Biggers
ee689d164a crypto: sha256-mb - remove HASH_FIRST flag
The HASH_FIRST flag is never set.  Remove it.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:46 +08:00
Eric Biggers
7a95cbd9a9 crypto: sha1-mb - remove HASH_FIRST flag
The HASH_FIRST flag is never set.  Remove it.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:45 +08:00
Eric Biggers
edbd1ecbd8 crypto: mcryptd - remove pointless wrapper functions
There is no need for ahash_mcryptd_{update,final,finup,digest}(); we
should just call crypto_ahash_*() directly.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Acked-by: Tim Chen <tim.c.chen@linux.intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:45 +08:00
weiyongjun \(A\)
40b776ae9f hwrng: imx-rngc - make symbol imx_rngc_pm_ops static
Fixes the following sparse warnings:

drivers/char/hw_random/imx-rngc.c:303:1: warning:
 symbol 'imx_rngc_pm_ops' was not declared. Should it be static?

Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
Reviewed-by: Martin Kaiser <martin@kaiser.cx>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:44 +08:00
Gilad Ben-Yossef
94f32d92cf MAINTAINERS: update ccree entry
Update Arm TrustZone CryptoCell driver entry move into drivers/crypto/

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:44 +08:00
Gilad Ben-Yossef
ab8ec9658f crypto: ccree - add FIPS support
Add FIPS mode support to CryptoCell driver

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:42 +08:00
Gilad Ben-Yossef
ff27e85a85 crypto: ccree - add AEAD support
Add CryptoCell AEAD support

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:42 +08:00
Gilad Ben-Yossef
63893811b0 crypto: ccree - add ahash support
Add CryptoCell async. hash and HMAC support.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:41 +08:00
Gilad Ben-Yossef
63ee04c8b4 crypto: ccree - add skcipher support
Add CryptoCell skcipher support

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:40 +08:00
Gilad Ben-Yossef
4c3f97276e crypto: ccree - introduce CryptoCell driver
Introduce basic low level Arm TrustZone CryptoCell HW support.
This first patch doesn't actually register any Crypto API
transformations, these will follow up in the next patch.

This first revision supports the CC 712 REE component.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:40 +08:00
Gilad Ben-Yossef
e294ca1cca staging: ccree: rename staging ver and mark as broken
Rename the Kconfig var of the staging tree version of the driver
in preparation of introducing the final version of the driver
into the cryptodev tree to avoid link time symbol collisions.

Signed-off-by: Gilad Ben-Yossef <gilad@benyossef.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:26:39 +08:00
Kamil Konieczny
6f221f7e86 crypto: hash - Require export/import in ahash
Export and import are mandatory in async hash. As drivers were
rewritten, drop empty wrappers and correct init of ahash transformation.

Signed-off-by: Kamil Konieczny <k.konieczny@partner.samsung.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2018-02-15 23:24:59 +08:00