
This commit fixes issue #91. [AN10922][] specifies the key diversification algorithms used by the MIFARE SAM AV3. Support for these algorithms was added to `libfreefare` via pull-request #79. However, while every attempt was made to write a faithful implementation, the implemented code did not properly handle cases where the diversification data was less than or equal to the block size of the cipher: 16 bytes for AES, and 8 bytes for DES. This bug was identified in issue #91. This commit addresses this problem while providing a way to revert to the previous behavior in cases where it is necessary to maintain previous deployments. This was accomplished by introducing a new `flags` parameter to the `mifare_key_deriver_new_an10922` method. Normally, `flags` should simply be set to `AN10922_FLAG_DEFAULT`. However, if the previous behavior is required, it should be set to `AN10922_FLAG_EMULATE_ISSUE_91`. [AN10922][] does not include any test vectors that might have helped to identify this problem earlier. However, [AN10957][] (pages 13-14) was found to have a suitable example usage of [AN10922][] with an appropriately short value for *M* that we are using as a test vector to verify correct behavior. Note that the issue being addressed here is not a security issue: using the `AN10922_FLAG_EMULATE_ISSUE_91` should not be any less secure than using `AN10922_FLAG_DEFAULT`. [AN10922]: https://www.nxp.com/docs/en/application-note/AN10922.pdf [AN10957]: https://www.nxp.com/docs/en/application-note/AN10957.pdf
173 lines
5.9 KiB
Groff
173 lines
5.9 KiB
Groff
.\" Copyright (C) 2018 Robert Quattlebaum
|
|
.\"
|
|
.\" This program is free software: you can redistribute it and/or modify it
|
|
.\" under the terms of the GNU Lesser 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 General Public License for
|
|
.\" more details.
|
|
.\"
|
|
.\" You should have received a copy of the GNU Lesser General Public License
|
|
.\" along with this program. If not, see <http://www.gnu.org/licenses/>
|
|
.\"
|
|
.Dd January 4, 2018
|
|
.Dt MIFARE_KEY_DERIVER 3
|
|
.Os
|
|
.\" _ _
|
|
.\" | \ | | __ _ _ __ ___ ___
|
|
.\" | \| |/ _` | '_ ` _ \ / _ \
|
|
.\" | |\ | (_| | | | | | | __/
|
|
.\" |_| \_|\__,_|_| |_| |_|\___|
|
|
.\"
|
|
.Sh NAME
|
|
.Nm mifare_key_deriver_new_an10922 ,
|
|
.Nm mifare_key_deriver_begin ,
|
|
.Nm mifare_key_deriver_update_data ,
|
|
.Nm mifare_key_deriver_update_uid ,
|
|
.Nm mifare_key_deriver_update_aid ,
|
|
.Nm mifare_key_deriver_update_cstr ,
|
|
.Nm mifare_key_deriver_end ,
|
|
.Nm mifare_key_deriver_end_raw ,
|
|
.Nm mifare_key_deriver_free ,
|
|
.Nd Mifare Key Derivation Functions
|
|
.\" _ _ _
|
|
.\" | | (_) |__ _ __ __ _ _ __ _ _
|
|
.\" | | | | '_ \| '__/ _` | '__| | | |
|
|
.\" | |___| | |_) | | | (_| | | | |_| |
|
|
.\" |_____|_|_.__/|_| \__,_|_| \__, |
|
|
.\" |___/
|
|
.Sh LIBRARY
|
|
Mifare card manipulation library (libfreefare, \-lfreefare)
|
|
.\" ____ _
|
|
.\" / ___| _ _ _ __ ___ _ __ ___(_)___
|
|
.\" \___ \| | | | '_ \ / _ \| '_ \/ __| / __|
|
|
.\" ___) | |_| | | | | (_) | |_) \__ \ \__ \
|
|
.\" |____/ \__, |_| |_|\___/| .__/|___/_|___/
|
|
.\" |___/ |_|
|
|
.Sh SYNOPSIS
|
|
.In freefare.h
|
|
.Ft MifareKeyDeriver
|
|
.Fn mifare_key_deriver_new_an10922 "MifareDESFireKey master_key" "MifareKeyType output_key_type" "int flags"
|
|
.Ft int
|
|
.Fn mifare_key_deriver_begin "MifareKeyDeriver deriver"
|
|
.Ft int
|
|
.Fn mifare_key_deriver_update_data "MifareKeyDeriver deriver" "const uint8_t *data" "size_t len"
|
|
.Ft int
|
|
.Fn mifare_key_deriver_update_uid "MifareKeyDeriver deriver" "FreefareTag tag"
|
|
.Ft int
|
|
.Fn mifare_key_deriver_update_aid "MifareKeyDeriver deriver" "MifareDESFireAID aid"
|
|
.Ft int
|
|
.Fn mifare_key_deriver_update_cstr "MifareKeyDeriver deriver" "const char *cstr"
|
|
.Ft MifareDESFireKey
|
|
.Fn mifare_key_deriver_end "MifareKeyDeriver deriver"
|
|
.Ft int
|
|
.Fn mifare_key_deriver_end_raw "MifareKeyDeriver deriver" "uint8_t* derived_data" "size_t data_max_len"
|
|
.Ft void
|
|
.Fn mifare_key_deriver_free "MifareKeyDeriver deriver"
|
|
.\" ____ _ _ _
|
|
.\" | _ \ ___ ___ ___ _ __(_)_ __ | |_(_) ___ _ __
|
|
.\" | | | |/ _ \/ __|/ __| '__| | '_ \| __| |/ _ \| '_ \
|
|
.\" | |_| | __/\__ \ (__| | | | |_) | |_| | (_) | | | |
|
|
.\" |____/ \___||___/\___|_| |_| .__/ \__|_|\___/|_| |_|
|
|
.\" |_|
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Fn mifare_key_deriver_*
|
|
family of functions allows for the diversification of Mifare DESFire keys.
|
|
.Pp
|
|
The
|
|
.Fn mifare_key_deriver_new_an10922
|
|
function alocates a new key deriver object which can be used to generate
|
|
diversified keys from
|
|
.Va master_key
|
|
in accordinance with AN10922 when the flags field is is set to AN10922_FLAG_DEFAULT.
|
|
When the flags field is set to AN10922_FLAG_EMULATE_ISSUE_91, the resulting key
|
|
deriver will use the non-AN10922-compliant key derivation that was originally being
|
|
used by this API. All new deployments should use AN10922_FLAG_DEFAULT. See issue #91 for
|
|
more information.
|
|
.Pp
|
|
The
|
|
.Fn mifare_key_deriver_begin
|
|
function marks the start of the derivation of a new diversified key.
|
|
.Pp
|
|
The
|
|
.Fn mifare_key_deriver_update_data ,
|
|
.Fn mifare_key_deriver_update_uid ,
|
|
.Fn mifare_key_deriver_update_aid
|
|
and
|
|
.Fn mifare_key_deriver_update_cstr
|
|
functions are used to specify the information that should be used to derive
|
|
the diversified key from the master key.
|
|
.Pp
|
|
The
|
|
.Fn mifare_key_deriver_end
|
|
function marks the end of the derivation and returns the new diversified key.
|
|
It is the responsibility of the caller to to free the returned key by calling
|
|
.Fn mifare_desfire_key_free .
|
|
.Fn mifare_key_deriver_end_raw
|
|
is a variant used to directly fetch the raw bytes of the derived key.
|
|
.Pp
|
|
.\" ____ _ _
|
|
.\" | _ \ ___| |_ _ _ _ __ _ __ __ ____ _| |_ _ ___ ___
|
|
.\" | |_) / _ \ __| | | | '__| '_ \ \ \ / / _` | | | | |/ _ \/ __|
|
|
.\" | _ < __/ |_| |_| | | | | | | \ V / (_| | | |_| | __/\__ \
|
|
.\" |_| \_\___|\__|\__,_|_| |_| |_| \_/ \__,_|_|\__,_|\___||___/
|
|
.\"
|
|
.Sh RETURN VALUES
|
|
.Fn mifare_key_deriver_new_an10922
|
|
returns the allocated key deriver or
|
|
.Va NULL
|
|
on failure.
|
|
.Pp
|
|
The
|
|
.Fn mifare_key_deriver_begin ,
|
|
.Fn mifare_key_deriver_update_data ,
|
|
.Fn mifare_key_deriver_update_uid ,
|
|
.Fn mifare_key_deriver_update_aid
|
|
and
|
|
.Fn mifare_key_deriver_update_cstr
|
|
functions return
|
|
.Va 0
|
|
on success and
|
|
.Va -1
|
|
on failure.
|
|
.Pp
|
|
The
|
|
.Fn mifare_key_deriver_end
|
|
function returns the new diversified key on success and
|
|
.Va NULL
|
|
on failure. It is the responsibility of the
|
|
caller to to free the returned key by calling
|
|
.Fn mifare_desfire_key_free .
|
|
.Pp
|
|
The
|
|
.Fn mifare_key_deriver_end_raw
|
|
function returns
|
|
.Va -1
|
|
on failure. On success, it returns the number of bytes that were derived. If
|
|
.Va data_max_len
|
|
is smaller than the return value, then no bytes were written to
|
|
.Va derived_data .
|
|
.Pp
|
|
Upon failure, all methods update
|
|
.Va errno
|
|
with the appropriate error code.
|
|
.\" ____ _
|
|
.\" / ___| ___ ___ __ _| |___ ___
|
|
.\" \___ \ / _ \/ _ \ / _` | / __|/ _ \
|
|
.\" ___) | __/ __/ | (_| | \__ \ (_) |
|
|
.\" |____/ \___|\___| \__,_|_|___/\___/
|
|
.\"
|
|
.Sh SEE ALSO
|
|
.Xr mifare_desfire_key 3
|
|
.\" _ _ _
|
|
.\" / \ _ _| |_| |__ ___ _ __ ___
|
|
.\" / _ \| | | | __| '_ \ / _ \| '__/ __|
|
|
.\" / ___ \ |_| | |_| | | | (_) | | \__ \
|
|
.\" /_/ \_\__,_|\__|_| |_|\___/|_| |___/
|
|
.\"
|
|
.Sh AUTHORS
|
|
.An Robert Quattlebaum darco@deepdarc.com
|